Compare commits

..

32 Commits

Author SHA1 Message Date
Leonid Pliushch
92570bee06 version 0.106 2021-01-17 19:45:19 +02:00
Leonid Pliushch
05bb399893 terminal-view: fix array indexing 2021-01-17 19:40:29 +02:00
Henrik Grimler
831aa69da8 Merge pull request #726 from dkramer95/OpenBroadcast
Sends broadcast on app open to notify addon termux receivers
2021-01-06 13:48:15 +01:00
Leonid Pliushch
a56cba6843 version 0.105 2021-01-06 14:31:56 +02:00
Leonid Pliushch
9228982632 remove restrictions from viewable file types
Fixes https://github.com/termux/termux-app/issues/1872 and
similar issues.
2021-01-06 14:28:28 +02:00
Leonid Pliushch
38114784f1 update bootstrap archives 2021-01-06 14:23:15 +02:00
Henrik Grimler
b805f1486c Merge pull request #1869 from termux/ctrlspace
Add workaround property to fix ctrl+space on devices where this does not work
2021-01-04 22:41:56 +01:00
Henrik Grimler
7d31b7f480 terminal-emulator: tests: change spaces to tabs for consistency 2021-01-02 09:12:14 +01:00
Henrik Grimler
a0298285e3 terminal-emulator: tests: avoid error about methods not being mocked
unitTests.returnDefaultValues = true fixes it.
More info: http://g.co/androidstudio/not-mocked
2021-01-02 09:12:14 +01:00
Lucy Phipps
538a1d5cdf F-Droid URL for Termux:Styling 2021-01-01 23:48:34 +02:00
Henrik Grimler
f1e973f0d2 terminal-view: add "ctrl-space-workaround" property
Makes it possible to run ctrl+space with hardware keyboards on
devices/ROMs where it otherwise is broken. On devices where it already
works this workaround breaks ctrl+space though.

Where to add this fix was investigated and found by @5bodnar.
2021-01-01 19:20:16 +01:00
Henrik Grimler
b467b68f7b terminal-view: mv code to get properties to its own function 2021-01-01 19:20:11 +01:00
Henrik Grimler
b895cbbb1e app: set importantForAutofill="no" for extra keys input field
Fixes warning "extra_keys_right.xml:2: Missing autofillHints attribute".
2021-01-01 18:13:37 +01:00
Henrik Grimler
fc30eba247 terminal-view: silence warning from use of SHOW_AS_ACTION_ALWAYS
```
Prefer "SHOW_AS_ACTION_IF_ROOM" instead of "SHOW_AS_ACTION_ALWAYS"
```
2021-01-01 18:13:36 +01:00
Henrik Grimler
b1d4c0c7fe app: disable test for "ProtectedPermissions"
Needed for tests to pass after READ_LOGS and WRITE_SECURE_SETTINGS
were added to AndroidManifest.xml.
2021-01-01 18:13:36 +01:00
Henrik Grimler
7fe5bd32c8 Update ndk to r22 2021-01-01 18:12:53 +01:00
Henrik Grimler
43bbef9a11 Update plugins and gradle to latest versions 2021-01-01 18:12:53 +01:00
Henrik Grimler
eaea0f74a5 Fix github links for terminal-{emulator,view} jcenter packages 2021-01-01 18:12:53 +01:00
Leonid Pliushch
cb13a5a531 version 0.104 2020-12-29 13:45:35 +02:00
Kevin LeBlanc
d267843e36 Don't exclude hidden files from document provider (#1220)
Credit to @johnmellor for requesting the document provider in the
first place via #79, mentioning this limitation in a comment on
that issue, and creating a commit like this one to address it.
2020-12-29 13:42:36 +02:00
Leonid Pliushch
5ca67dd885 update bootstrap archives 2020-12-29 13:40:25 +02:00
Leonid Pliushch
6b0d531758 Revert "update readme" 2020-12-17 20:27:46 +02:00
Leonid Pliushch
1b3283bd69 update bootstrap archives 2020-12-11 20:07:40 +02:00
Leonid Pliushch
2820f6a7b8 update readme 2020-12-11 17:36:14 +02:00
Leonid Pliushch
8925ae67bb update readme 2020-12-11 17:35:28 +02:00
Lucy Phipps
4066c5df42 don't add $PREFIX/bin/applets to $PATH
busybox doesn't use that folder anymore, and is deprecated anyway
2020-11-24 23:16:17 +02:00
Leonid Pliushch
20aac6aa72 copy FUNDING.yml from termux-packages repo 2020-11-18 03:04:38 +02:00
Leonid Pliushch
e1f799f9a1 version 0.103 2020-11-17 20:40:40 +02:00
Leonid Pliushch
4479de4b9b update bootstrap archives 2020-11-17 20:35:55 +02:00
Leonid Pliushch
3a8f53a54c add permission WRITE_SECURE_SETTINGS
https://github.com/termux/termux-api/issues/211
2020-11-17 20:07:33 +02:00
Leonid Pliushch
2f04a6186b add READ_LOGS permission
* https://github.com/termux/termux-app/issues/873
* https://github.com/termux/termux-app/issues/1821
2020-11-17 20:03:10 +02:00
David Kramer
3bb2849a88 Sends broadcast on app open to notify addon termux receivers 2018-06-18 13:06:34 -06:00
23 changed files with 259 additions and 205 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
patreon: termux
custom: https://paypal.me/fornwall

View File

@@ -9,7 +9,7 @@ android {
dependencies { dependencies {
implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0" implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.drawerlayout:drawerlayout:1.1.0" implementation "androidx.drawerlayout:drawerlayout:1.1.1"
implementation project(":terminal-view") implementation project(":terminal-view")
} }
@@ -17,8 +17,8 @@ android {
applicationId "com.termux" applicationId "com.termux"
minSdkVersion project.properties.minSdkVersion.toInteger() minSdkVersion project.properties.minSdkVersion.toInteger()
targetSdkVersion project.properties.targetSdkVersion.toInteger() targetSdkVersion project.properties.targetSdkVersion.toInteger()
versionCode 102 versionCode 106
versionName "0.102" versionName "0.106"
externalNativeBuild { externalNativeBuild {
ndkBuild { ndkBuild {
@@ -64,6 +64,10 @@ android {
} }
} }
lintOptions {
disable 'ProtectedPermissions'
}
testOptions { testOptions {
unitTests { unitTests {
includeAndroidResources = true includeAndroidResources = true
@@ -72,8 +76,8 @@ android {
} }
dependencies { dependencies {
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13.1'
testImplementation 'org.robolectric:robolectric:4.3.1' testImplementation 'org.robolectric:robolectric:4.4'
} }
task versionName { task versionName {
@@ -133,11 +137,11 @@ clean {
task downloadBootstraps(){ task downloadBootstraps(){
doLast { doLast {
def version = 31 def version = 35
downloadBootstrap("aarch64", "e9149cb01735f04b180434093dfb8e703015f8a66044acaead7cbff1e536a990", version) downloadBootstrap("aarch64", "6707cc641cde13dc2f24e819cd8ca3f1a9a003577523c25beff72690588594f5", version)
downloadBootstrap("arm", "8e5776074c58b3e94b1336f2ec0e840057fce9c089faee6683ae5c136441da7b", version) downloadBootstrap("arm", "eadc9afb52900dc744fdb39ed0c3dbb87ad8ce6190b27946467df7aeab353fa7", version)
downloadBootstrap("i686", "f89be9d0197fb9c6b498922ff0f95562fd17b63c934617858f959b8e452ade27", version) downloadBootstrap("i686", "b674ef43c8388dd19e0d25b024b5792c8532ee0ddcc49f90c0716042724fa905", version)
downloadBootstrap("x86_64", "9aa97647afc085fae4e8485458a7d15f23db6e1e3601727f014af8b8eb4519a9", version) downloadBootstrap("x86_64", "86043eb76efededbdf5644686a899f4d762703fe18e23fb906a2482d593d7549", version)
} }
} }

View File

@@ -22,6 +22,8 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application <application
android:extractNativeLibs="true" android:extractNativeLibs="true"
@@ -81,16 +83,15 @@
<data android:mimeType="text/*" /> <data android:mimeType="text/*" />
<data android:mimeType="video/*" /> <data android:mimeType="video/*" />
</intent-filter> </intent-filter>
<!-- Be more restrictive for viewing files, restricting ourselves to text files. --> <!-- Accept multiple file types to let Termux be usable as generic file viewer. -->
<intent-filter tools:ignore="AppLinkUrlError"> <intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW"/> <action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="text/*" /> <data android:mimeType="text/*" />
<data android:mimeType="application/*log*" /> <data android:mimeType="video/*" />
<data android:mimeType="application/json" />
<data android:mimeType="application/*xml*" />
<data android:mimeType="application/*latex*" />
<data android:mimeType="application/javascript" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@@ -161,7 +161,7 @@ public final class BackgroundJob {
environment.add("PATH= " + System.getenv("PATH")); environment.add("PATH= " + System.getenv("PATH"));
} else { } else {
environment.add("LANG=en_US.UTF-8"); environment.add("LANG=en_US.UTF-8");
environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin:" + TermuxService.PREFIX_PATH + "/bin/applets"); environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin");
environment.add("PWD=" + cwd); environment.add("PWD=" + cwd);
environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp"); environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp");
} }

View File

@@ -15,6 +15,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Typeface; import android.graphics.Typeface;
@@ -101,6 +102,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style"; private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
private static final String BROADCAST_TERMUX_OPENED = "com.termux.app.OPENED";
/** The main view of the activity showing the terminal. Initialized in onCreate(). */ /** The main view of the activity showing the terminal. Initialized in onCreate(). */
@SuppressWarnings("NullableProblems") @SuppressWarnings("NullableProblems")
@NonNull @NonNull
@@ -324,6 +327,26 @@ public final class TermuxActivity extends Activity implements ServiceConnection
checkForFontAndColors(); checkForFontAndColors();
mBellSoundId = mBellSoundPool.load(this, R.raw.bell, 1); mBellSoundId = mBellSoundPool.load(this, R.raw.bell, 1);
sendOpenedBroadcast();
}
/**
* Send a broadcast notifying Termux app has been opened
*/
void sendOpenedBroadcast() {
Intent broadcast = new Intent(BROADCAST_TERMUX_OPENED);
List<ResolveInfo> matches = getPackageManager().queryBroadcastReceivers(broadcast, 0);
// send broadcast to registered Termux receivers
// this technique is needed to work around broadcast changes that Oreo introduced
for (ResolveInfo info : matches) {
Intent explicitBroadcast = new Intent(broadcast);
ComponentName cname = new ComponentName(info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
explicitBroadcast.setComponent(cname);
sendBroadcast(explicitBroadcast);
}
} }
void toggleShowExtraKeys() { void toggleShowExtraKeys() {
@@ -861,7 +884,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
// The startActivity() call is not documented to throw IllegalArgumentException. // The startActivity() call is not documented to throw IllegalArgumentException.
// However, crash reporting shows that it sometimes does, so catch it here. // However, crash reporting shows that it sometimes does, so catch it here.
new AlertDialog.Builder(this).setMessage(R.string.styling_not_installed) new AlertDialog.Builder(this).setMessage(R.string.styling_not_installed)
.setPositiveButton(R.string.styling_install, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=com.termux.styling")))).setNegativeButton(android.R.string.cancel, null).show(); .setPositiveButton(R.string.styling_install, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://f-droid.org/en/packages/com.termux.styling/")))).setNegativeButton(android.R.string.cancel, null).show();
} }
return true; return true;
} }

View File

@@ -91,10 +91,8 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION); final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION);
final File parent = getFileForDocId(parentDocumentId); final File parent = getFileForDocId(parentDocumentId);
for (File file : parent.listFiles()) { for (File file : parent.listFiles()) {
if (!file.getName().startsWith(".")) {
includeFile(result, null, file); includeFile(result, null, file);
} }
}
return result; return result;
} }
@@ -177,8 +175,7 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
} catch (IOException e) { } catch (IOException e) {
isInsideHome = true; isInsideHome = true;
} }
final boolean isHidden = file.getName().startsWith("."); if (isInsideHome) {
if (isInsideHome && !isHidden) {
if (file.isDirectory()) { if (file.isDirectory()) {
Collections.addAll(pending, file.listFiles()); Collections.addAll(pending, file.listFiles());
} else { } else {

View File

@@ -7,6 +7,7 @@
android:imeOptions="actionSend|flagNoFullscreen" android:imeOptions="actionSend|flagNoFullscreen"
android:maxLines="1" android:maxLines="1"
android:inputType="text" android:inputType="text"
android:importantForAutofill="no"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textColorHighlight="@android:color/darker_gray" android:textColorHighlight="@android:color/darker_gray"
android:paddingTop="0dp" android:paddingTop="0dp"

View File

@@ -4,7 +4,7 @@ buildscript {
google() google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.android.tools.build:gradle:4.1.1'
} }
} }

View File

@@ -17,5 +17,5 @@ android.useAndroidX=true
minSdkVersion=24 minSdkVersion=24
targetSdkVersion=28 targetSdkVersion=28
ndkVersion=21.3.6528147 ndkVersion=22.0.7026061
compileSdkVersion=28 compileSdkVersion=28

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id "com.jfrog.bintray" version "1.7.3" id "com.jfrog.bintray" version "1.8.5"
id "com.github.dcendents.android-maven" version "2.0" id "com.github.dcendents.android-maven" version "2.1"
} }
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
@@ -11,8 +11,8 @@ ext {
libraryName = 'TerminalEmulator' libraryName = 'TerminalEmulator'
artifact = 'terminal-emulator' artifact = 'terminal-emulator'
libraryDescription = 'The terminal emulator used in Termux' libraryDescription = 'The terminal emulator used in Termux'
siteUrl = 'https://github.com/termux/termux' siteUrl = 'https://github.com/termux/termux-app'
gitUrl = 'https://github.com/termux/termux.git' gitUrl = 'https://github.com/termux/termux-app.git'
libraryVersion = '0.52' libraryVersion = '0.52'
} }
@@ -52,6 +52,10 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
testOptions {
unitTests.returnDefaultValues = true
}
} }
tasks.withType(Test) { tasks.withType(Test) {
@@ -61,7 +65,7 @@ tasks.withType(Test) {
} }
dependencies { dependencies {
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13.1'
} }
apply from: '../scripts/bintray-publish.gradle' apply from: '../scripts/bintray-publish.gradle'

View File

@@ -161,7 +161,7 @@ public class CursorAndScreenTest extends TerminalTestCase {
/** /**
* See comments on horizontal tab handling in TerminalEmulator.java. * See comments on horizontal tab handling in TerminalEmulator.java.
* * <p/>
* We do not want to color already written cells when tabbing over them. * We do not want to color already written cells when tabbing over them.
*/ */
public void DISABLED_testHorizontalTabColorsBackground() { public void DISABLED_testHorizontalTabColorsBackground() {

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id "com.jfrog.bintray" version "1.7.3" id "com.jfrog.bintray" version "1.8.5"
id "com.github.dcendents.android-maven" version "2.0" id "com.github.dcendents.android-maven" version "2.1"
} }
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
@@ -11,8 +11,8 @@ ext {
libraryName = 'TerminalView' libraryName = 'TerminalView'
artifact = 'terminal-view' artifact = 'terminal-view'
libraryDescription = 'The terminal view used in Termux' libraryDescription = 'The terminal view used in Termux'
siteUrl = 'https://github.com/termux/termux' siteUrl = 'https://github.com/termux/termux-app'
gitUrl = 'https://github.com/termux/termux.git' gitUrl = 'https://github.com/termux/termux-app.git'
libraryVersion = '0.50' libraryVersion = '0.50'
} }
@@ -44,7 +44,7 @@ android {
} }
dependencies { dependencies {
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13.1'
} }
apply from: '../scripts/bintray-publish.gradle' apply from: '../scripts/bintray-publish.gradle'

View File

@@ -255,20 +255,7 @@ public final class TerminalView extends View {
@Override @Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) { public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
File propsFile = new File(getContext().getFilesDir() + "/home/.termux/termux.properties"); Properties props = getProperties();
if (!propsFile.exists())
propsFile = new File(getContext().getFilesDir() + "/home/.config/termux/termux.properties");
Properties props = new Properties();
try {
if (propsFile.isFile() && propsFile.canRead()) {
try (FileInputStream in = new FileInputStream(propsFile)) {
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
}
} catch (Exception e) {
Log.e("termux", "Error loading props", e);
}
if (props.getProperty("enforce-char-based-input", "false").equals("true")) { if (props.getProperty("enforce-char-based-input", "false").equals("true")) {
// Some keyboards seems do not reset the internal state on TYPE_NULL. // Some keyboards seems do not reset the internal state on TYPE_NULL.
@@ -552,6 +539,8 @@ public final class TerminalView extends View {
@Override @Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) { public boolean onKeyPreIme(int keyCode, KeyEvent event) {
Properties props = getProperties();
if (LOG_KEY_EVENTS) if (LOG_KEY_EVENTS)
Log.i(EmulatorDebug.LOG_TAG, "onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")"); Log.i(EmulatorDebug.LOG_TAG, "onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")");
if (keyCode == KeyEvent.KEYCODE_BACK) { if (keyCode == KeyEvent.KEYCODE_BACK) {
@@ -567,6 +556,11 @@ public final class TerminalView extends View {
return onKeyUp(keyCode, event); return onKeyUp(keyCode, event);
} }
} }
} else if (props.getProperty("ctrl-space-workaround", "false").equals("true") &&
keyCode == KeyEvent.KEYCODE_SPACE && event.isCtrlPressed()) {
/* ctrl + space does not work on some ROMs without this workaround.
However, this breaks it on devices where it works out of the box. */
return onKeyDown(keyCode, event);
} }
return super.onKeyPreIme(keyCode, event); return super.onKeyPreIme(keyCode, event);
} }
@@ -1197,7 +1191,7 @@ public final class TerminalView extends View {
final ActionMode.Callback callback = new ActionMode.Callback() { final ActionMode.Callback callback = new ActionMode.Callback() {
@Override @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) { public boolean onCreateActionMode(ActionMode mode, Menu menu) {
int show = MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT; int show = MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT;
ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); ClipboardManager clipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
menu.add(Menu.NONE, 1, Menu.NONE, R.string.copy_text).setShowAsAction(show); menu.add(Menu.NONE, 1, Menu.NONE, R.string.copy_text).setShowAsAction(show);
@@ -1544,6 +1538,34 @@ public final class TerminalView extends View {
} }
} }
private Properties getProperties() {
File propsFile;
Properties props = new Properties();
String possiblePropLocations[] = {
getContext().getFilesDir() + "/home/.termux/termux.properties",
getContext().getFilesDir() + "/home/.config/termux/termux.properties"
};
propsFile = new File(possiblePropLocations[0]);
int i = 0;
while (!propsFile.exists() && i < possiblePropLocations.length) {
propsFile = new File(possiblePropLocations[i]);
i += 1;
}
try {
if (propsFile.isFile() && propsFile.canRead()) {
try (FileInputStream in = new FileInputStream(propsFile)) {
props.load(new InputStreamReader(in, StandardCharsets.UTF_8));
}
}
} catch (Exception e) {
Log.e("termux", "Error loading props", e);
}
return props;
}
@RequiresApi(api = Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.O)
@Override @Override
public void autofill(AutofillValue value) { public void autofill(AutofillValue value) {