Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable support for android 5/6 for termux-app #2740

Merged
merged 19 commits into from
May 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6213b7f
Changed: Use double quotes instead of single quotes for all gradle de…
agnostic-apollo Apr 25, 2022
623aaeb
Changed: Bump down `minSdkVersion` from `24` to `21` to restart suppo…
agnostic-apollo Apr 25, 2022
9143ebd
Changed: Enable desugaring support to enable support for new language…
agnostic-apollo Apr 25, 2022
a1719d9
Changed: Bump `termux-am-library` to 2.0.0 that uses `minSdkVersion` …
agnostic-apollo Apr 25, 2022
14e9a8b
Changed: Use float dp parameter instead of int for `ViewUtils.dpToPx(…
agnostic-apollo Apr 25, 2022
fa82962
Added: Add `ViewUtils.pxToDp()`
agnostic-apollo Apr 25, 2022
677a580
Changed: Add general compatibility fixes for `minSdkVerion` `21`
agnostic-apollo Apr 25, 2022
55dcd09
Fixed: Fixed extra keys not showing properly on Android 5
agnostic-apollo Apr 25, 2022
c549988
Fixed: Fix broken javadocs links
agnostic-apollo Apr 25, 2022
4e08f76
Changed: Export correct PATH and also export LD_LIBRARY_PATH for Andr…
agnostic-apollo Apr 25, 2022
ab9b620
Added: Add ResourceUtils to get resource ids from names
agnostic-apollo Apr 25, 2022
5290ce1
Added|Fixed: Add `TermuxNotificationUtils.getTermuxOrPluginAppNotific…
agnostic-apollo Apr 25, 2022
007bef8
Added: Add message to bootstrap error if user installed termux on por…
agnostic-apollo Apr 25, 2022
7677633
Fixed: Catch `UnsatisfiedLinkError` for `local-socket` library
agnostic-apollo Apr 28, 2022
18a1a33
Added: Enable `TERMUX_PACKAGE_VARIANT` `apt-android-5` builds
agnostic-apollo Apr 28, 2022
4d084c0
Changed: Bump android-5 bootstraps to v2022.04.28-r6
Grimler91 Apr 28, 2022
899ef71
Changed: Bump android-7 bootstraps to v2022.04.28-r5
Grimler91 Apr 28, 2022
7b222ba
Changed: Export correct PATH and also export LD_LIBRARY_PATH for `apt…
agnostic-apollo Apr 28, 2022
b04f209
Added: Add TERMUX_DEVS key SHA-256 digest to official signing keys list
agnostic-apollo Apr 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ext {
// crash at startup.
// Bootstrap of a different variant must not be manually installed by the user after app installation
// by replacing $PREFIX since app code is dependant on the variant used to build the APK.
// Currently supported values are: [ "apt-android-7" ]
// Currently supported values are: [ "apt-android-7" "apt-android-5" ]
packageVariant = System.getenv("TERMUX_PACKAGE_VARIANT") ?: "apt-android-7" // Default: "apt-android-7"
}

Expand Down Expand Up @@ -97,6 +97,9 @@ android {
}

compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true

sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand Down Expand Up @@ -140,6 +143,7 @@ android {
dependencies {
testImplementation "junit:junit:4.13.2"
testImplementation "org.robolectric:robolectric:4.4"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
}

task versionName {
Expand Down Expand Up @@ -210,11 +214,17 @@ task downloadBootstraps() {
doLast {
def packageVariant = project.ext.packageVariant
if (packageVariant == "apt-android-7") {
def version = "2022.04.22-r1" + "+" + packageVariant
downloadBootstrap("aarch64", "ec8a6043644594fc24681cffaf9c7b32f5bc68df7491c5df9a060e40e1934c70", version)
downloadBootstrap("arm", "f8ec9505081b81da0ee66413762c52e6cb4a6ebd7be1a2a5ddee8953e0795dc9", version)
downloadBootstrap("i686", "0491f12ed84a5ef3c28bd742311fed9f176e32100a2c6bbdb017df8f48044484", version)
downloadBootstrap("x86_64", "94073a0e136bf5a9c05c1997a55dc261248f4ccb8bffaa9a950a132529cd1529", version)
def version = "2022.04.28-r5" + "+" + packageVariant
downloadBootstrap("aarch64", "4a51a7eb209fe82efc24d52e3cccc13165f27377290687cb82038cbd8e948430", version)
downloadBootstrap("arm", "6459a786acbae50d4c8a36fa1c3de6a4dd2d482572f6d54f73274709bd627325", version)
downloadBootstrap("i686", "919d212b2f19e08600938db4079e794e947365022dbfd50ac342c50fcedcd7be", version)
downloadBootstrap("x86_64", "61b02fdc03ea4f5d9da8d8cf018013fdc6659e6da6cbf44e9b24d1c623580b89", version)
} else if (packageVariant == "apt-android-5") {
def version = "2022.04.28-r6" + "+" + packageVariant
downloadBootstrap("aarch64", "913609d439415c828c5640be1b0561467e539cb1c7080662decaaca2fb4820e7", version)
downloadBootstrap("arm", "26bfb45304c946170db69108e5eb6e3641aad751406ce106c80df80cad2eccf8", version)
downloadBootstrap("i686", "46dcfeb5eef67ba765498db9fe4c50dc4690805139aa0dd141a9d8ee0693cd27", version)
downloadBootstrap("x86_64", "615b590679ee6cd885b7fd2ff9473c845e920f9b422f790bb158c63fe42b8481", version)
} else {
throw new GradleException("Unsupported TERMUX_PACKAGE_VARIANT \"" + packageVariant + "\"")
}
Expand Down
12 changes: 8 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="false"
android:theme="@style/Theme.TermuxApp.DayNight.DarkActionBar">
android:theme="@style/Theme.TermuxApp.DayNight.DarkActionBar"
tools:targetApi="m">

<activity
android:name=".app.TermuxActivity"
Expand All @@ -55,7 +56,8 @@
android:label="@string/application_name"
android:launchMode="singleTask"
android:resizeableActivity="true"
android:theme="@style/Theme.TermuxActivity.DayNight.NoActionBar">
android:theme="@style/Theme.TermuxActivity.DayNight.NoActionBar"
tools:targetApi="n">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down Expand Up @@ -91,7 +93,8 @@
android:exported="false"
android:label="@string/application_name"
android:parentActivityName=".app.TermuxActivity"
android:resizeableActivity="true" />
android:resizeableActivity="true"
tools:targetApi="n" />

<activity
android:name=".app.activities.SettingsActivity"
Expand All @@ -111,7 +114,8 @@
android:label="@string/application_name"
android:noHistory="true"
android:resizeableActivity="true"
android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver">
android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver"
tools:targetApi="n">

<!-- Accept multiple file types when sending. -->
<intent-filter>
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/com/termux/app/TermuxActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo

private int mNavBarHeight;

private int mTerminalToolbarDefaultHeight;
private float mTerminalToolbarDefaultHeight;


private static final int CONTEXT_MENU_SELECT_URL_ID = 0;
Expand Down Expand Up @@ -528,7 +528,7 @@ private void setTerminalToolbarHeight() {
if (terminalToolbarViewPager == null) return;

ViewGroup.LayoutParams layoutParams = terminalToolbarViewPager.getLayoutParams();
layoutParams.height = (int) Math.round(mTerminalToolbarDefaultHeight *
layoutParams.height = Math.round(mTerminalToolbarDefaultHeight *
(mTermuxTerminalExtraKeys.getExtraKeysInfo() == null ? 0 : mTermuxTerminalExtraKeys.getExtraKeysInfo().getMatrix().length) *
mProperties.getTerminalToolbarHeightScaleFactor());
terminalToolbarViewPager.setLayoutParams(layoutParams);
Expand Down Expand Up @@ -835,6 +835,10 @@ public ViewPager getTerminalToolbarViewPager() {
return (ViewPager) findViewById(R.id.terminal_toolbar_view_pager);
}

public float getTerminalToolbarDefaultHeight() {
return mTerminalToolbarDefaultHeight;
}

public boolean isTerminalViewSelected() {
return getTerminalToolbarViewPager().getCurrentItem() == 0;
}
Expand Down Expand Up @@ -960,7 +964,7 @@ private void reloadActivityStyling(boolean recreateActivity) {

if (mExtraKeysView != null) {
mExtraKeysView.setButtonTextAllCaps(mProperties.shouldExtraKeysTextBeAllCaps());
mExtraKeysView.reload(mTermuxTerminalExtraKeys.getExtraKeysInfo());
mExtraKeysView.reload(mTermuxTerminalExtraKeys.getExtraKeysInfo(), mTerminalToolbarDefaultHeight);
}

// Update NightMode.APP_NIGHT_MODE
Expand Down
15 changes: 12 additions & 3 deletions app/src/main/java/com/termux/app/TermuxInstaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.system.Os;
import android.util.Pair;
Expand Down Expand Up @@ -71,8 +72,9 @@ static void setupBootstrapIfNeeded(final Activity activity, final Runnable whenD

// Termux can only be run as the primary user (device owner) since only that
// account has the expected file system paths. Verify that:
if (!PackageUtils.isCurrentUserThePrimaryUser(activity)) {
bootstrapErrorMessage = activity.getString(R.string.bootstrap_error_not_primary_user_message, MarkdownUtils.getMarkdownCodeForString(TERMUX_PREFIX_DIR_PATH, false));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !PackageUtils.isCurrentUserThePrimaryUser(activity)) {
bootstrapErrorMessage = activity.getString(R.string.bootstrap_error_not_primary_user_message,
MarkdownUtils.getMarkdownCodeForString(TERMUX_PREFIX_DIR_PATH, false));
Logger.logError(LOG_TAG, "isFilesDirectoryAccessible: " + isFilesDirectoryAccessible);
Logger.logError(LOG_TAG, bootstrapErrorMessage);
sendBootstrapCrashReportNotification(activity, bootstrapErrorMessage);
Expand All @@ -83,7 +85,14 @@ static void setupBootstrapIfNeeded(final Activity activity, final Runnable whenD
}

if (!isFilesDirectoryAccessible) {
bootstrapErrorMessage = Error.getMinimalErrorString(filesDirectoryAccessibleError) + "\nTERMUX_FILES_DIR: " + MarkdownUtils.getMarkdownCodeForString(TermuxConstants.TERMUX_FILES_DIR_PATH, false);
bootstrapErrorMessage = Error.getMinimalErrorString(filesDirectoryAccessibleError);
//noinspection SdCardPath
if (PackageUtils.isAppInstalledOnExternalStorage(activity) &&
!TermuxConstants.TERMUX_FILES_DIR_PATH.equals(activity.getFilesDir().getAbsolutePath().replaceAll("^/data/user/0/", "/data/data/"))) {
bootstrapErrorMessage += "\n\n" + activity.getString(R.string.bootstrap_error_installed_on_portable_sd,
MarkdownUtils.getMarkdownCodeForString(TERMUX_PREFIX_DIR_PATH, false));
}

Logger.logError(LOG_TAG, bootstrapErrorMessage);
sendBootstrapCrashReportNotification(activity, bootstrapErrorMessage);
MessageDialogUtils.showMessage(activity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public Object instantiateItem(@NonNull ViewGroup collection, int position) {
extraKeysView.setExtraKeysViewClient(mActivity.getTermuxTerminalExtraKeys());
extraKeysView.setButtonTextAllCaps(mActivity.getProperties().shouldExtraKeysTextBeAllCaps());
mActivity.setExtraKeysView(extraKeysView);
extraKeysView.reload(mActivity.getTermuxTerminalExtraKeys().getExtraKeysInfo());
extraKeysView.reload(mActivity.getTermuxTerminalExtraKeys().getExtraKeysInfo(),
mActivity.getTerminalToolbarDefaultHeight());

// apply extra keys fix if enabled in prefs
if (mActivity.getProperties().isUsingFullScreen() && mActivity.getProperties().isUsingFullScreenWorkAround()) {
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@
<string name="bootstrap_error_try_again">Try again</string>
<string name="bootstrap_error_not_primary_user_message">&TERMUX_APP_NAME; can only be run as the primary user.
\nBootstrap binaries compiled for &TERMUX_APP_NAME; have hardcoded $PREFIX path and cannot be installed
under any path other than %1$s.</string>
under any path other than:\n%1$s.</string>
<string name="bootstrap_error_installed_on_portable_sd">&TERMUX_APP_NAME; cannot be installed on
portable/external/removable sd card on your device.
\nBootstrap binaries compiled for &TERMUX_APP_NAME; have hardcoded $PREFIX path and cannot be installed
under any path other than:\n%1$s.</string>



Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath "com.android.tools.build:gradle:4.2.2"
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
org.gradle.jvmargs=-Xmx2048M
android.useAndroidX=true

minSdkVersion=24
minSdkVersion=21
targetSdkVersion=28
ndkVersion=22.1.7171670
compileSdkVersion=30
Expand Down
4 changes: 2 additions & 2 deletions terminal-emulator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ tasks.withType(Test) {
}

dependencies {
implementation 'androidx.annotation:annotation:1.3.0'
testImplementation 'junit:junit:4.13.2'
implementation "androidx.annotation:annotation:1.3.0"
testImplementation "junit:junit:4.13.2"
}

task sourceJar(type: Jar) {
Expand Down
2 changes: 1 addition & 1 deletion terminal-view/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
}

dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation "junit:junit:4.13.2"
}

task sourceJar(type: Jar) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,7 @@ protected void onDetachedFromWindow() {
* Define functions required for long hold toolbar.
*/
private final Runnable mShowFloatingToolbar = new Runnable() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void run() {
if (getTextSelectionActionMode() != null) {
Expand All @@ -1253,13 +1254,15 @@ public void run() {
}
};

@RequiresApi(api = Build.VERSION_CODES.M)
private void showFloatingToolbar() {
if (getTextSelectionActionMode() != null) {
int delay = ViewConfiguration.getDoubleTapTimeout();
postDelayed(mShowFloatingToolbar, delay);
}
}

@RequiresApi(api = Build.VERSION_CODES.M)
void hideFloatingToolbar() {
if (getTextSelectionActionMode() != null) {
removeCallbacks(mShowFloatingToolbar);
Expand All @@ -1268,7 +1271,7 @@ void hideFloatingToolbar() {
}

public void updateFloatingToolbarVisibility(MotionEvent event) {
if (getTextSelectionActionMode() != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && getTextSelectionActionMode() != null) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_MOVE:
hideFloatingToolbar();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.termux.view.support;

import android.util.Log;
import android.widget.PopupWindow;

import java.lang.reflect.Method;

/**
* Implementation of PopupWindow compatibility that can call Gingerbread APIs.
* https://chromium.googlesource.com/android_tools/+/HEAD/sdk/extras/android/support/v4/src/gingerbread/android/support/v4/widget/PopupWindowCompatGingerbread.java
*/
public class PopupWindowCompatGingerbread {

private static Method sSetWindowLayoutTypeMethod;
private static boolean sSetWindowLayoutTypeMethodAttempted;
private static Method sGetWindowLayoutTypeMethod;
private static boolean sGetWindowLayoutTypeMethodAttempted;

public static void setWindowLayoutType(PopupWindow popupWindow, int layoutType) {
if (!sSetWindowLayoutTypeMethodAttempted) {
try {
sSetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
"setWindowLayoutType", int.class);
sSetWindowLayoutTypeMethod.setAccessible(true);
} catch (Exception e) {
// Reflection method fetch failed. Oh well.
}
sSetWindowLayoutTypeMethodAttempted = true;
}
if (sSetWindowLayoutTypeMethod != null) {
try {
sSetWindowLayoutTypeMethod.invoke(popupWindow, layoutType);
} catch (Exception e) {
// Reflection call failed. Oh well.
}
}
}

public static int getWindowLayoutType(PopupWindow popupWindow) {
if (!sGetWindowLayoutTypeMethodAttempted) {
try {
sGetWindowLayoutTypeMethod = PopupWindow.class.getDeclaredMethod(
"getWindowLayoutType");
sGetWindowLayoutTypeMethod.setAccessible(true);
} catch (Exception e) {
// Reflection method fetch failed. Oh well.
}
sGetWindowLayoutTypeMethodAttempted = true;
}
if (sGetWindowLayoutTypeMethod != null) {
try {
return (Integer) sGetWindowLayoutTypeMethod.invoke(popupWindow);
} catch (Exception e) {
// Reflection call failed. Oh well.
}
}
return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.Menu;
Expand Down Expand Up @@ -153,6 +154,12 @@ public void onDestroyActionMode(ActionMode mode) {

};

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
mActionMode = terminalView.startActionMode(callback);
return;
}

//noinspection NewApi
mActionMode = terminalView.startActionMode(new ActionMode.Callback2() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.SystemClock;
import android.view.MotionEvent;
import android.view.View;
Expand All @@ -14,6 +15,7 @@

import com.termux.view.R;
import com.termux.view.TerminalView;
import com.termux.view.support.PopupWindowCompatGingerbread;

@SuppressLint("ViewConstructor")
public class TextSelectionHandleView extends View {
Expand Down Expand Up @@ -68,13 +70,18 @@ private void initHandle() {
android.R.attr.textSelectHandleWindowStyle);
mHandle.setSplitTouchEnabled(true);
mHandle.setClippingEnabled(false);
mHandle.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
mHandle.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
mHandle.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mHandle.setBackgroundDrawable(null);
mHandle.setAnimationStyle(0);
mHandle.setEnterTransition(null);
mHandle.setExitTransition(null);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mHandle.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
mHandle.setEnterTransition(null);
mHandle.setExitTransition(null);
} else {
PopupWindowCompatGingerbread.setWindowLayoutType(mHandle, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
}
mHandle.setContentView(this);
}

Expand Down
Loading