Compare commits

..

16 Commits
v0.67 ... v0.71

Author SHA1 Message Date
Fredrik Fornwall
81b5889a26 Bump version to 0.71 2019-05-21 21:52:39 +02:00
Leonid Plyushch
514f59258a let $PREFIX/tmp be cleaned when TermuxService is going to be stopped 2019-05-21 21:52:14 +02:00
Leonid Plyushch
9f79393aa5 Revert "clean /tmp directory on cold start"
This reverts commit beb8a004e6.
2019-05-21 21:52:14 +02:00
Leonid Plyushch
e49d514236 Revert "sessions: do not clear TMPDIR if application was not started"
This reverts commit bd45837d93.
2019-05-21 21:52:14 +02:00
Leonid Plyushch
4e1462326c remove intent category "default"
It was needed only when Termux had separate icon for failsafe activity.
2019-05-21 21:52:14 +02:00
Fredrik Fornwall
b0f1773a92 Bump version to 0.70 2019-05-20 13:32:35 +02:00
Fredrik Fornwall
af9f28c010 Remove the failsafe activity
The failsafe activity were infrequently used while confusing users.

Replace it with an app shortcut on Android 7.1+ and a separate app on
earlier versions.
2019-05-20 13:32:03 +02:00
Nishith Khanna
fef0c66868 Tweak notification icon color to make it work with dark notifcations
As the notification icon and text is set to black, ROMs like Samsung OneUI and themes that change notifications to have a dark background will have visibility issues with Termux notifications. This commit sets a neutral color which will be visible on both white and dark backgrounds.
2019-05-20 13:27:58 +02:00
Fredrik Fornwall
7a5da83ce2 Bump version to 0.69 2019-05-12 00:18:02 +02:00
Fredrik Fornwall
97f01387b9 Update Android Gradle plugin 2019-05-12 00:17:16 +02:00
Jonas L
012ff83a06 Add limit for the bell (vibration)
This fixes https://github.com/termux/termux-app/issues/442
2019-05-12 00:13:54 +02:00
Michal Bednarski
a082c63849 Make am work on Android Q 2019-05-12 00:10:27 +02:00
Fredrik Fornwall
8c27084086 Bump version to 0.68 2019-04-22 00:54:27 +02:00
Fredrik Fornwall
f4fb45cbd6 Add the label attribute on TermuxActivity
Should fix the F-Droid naming of the app, see
https://github.com/termux/termux-app/issues/1107
2019-04-21 20:19:34 +02:00
Leonid Plyushch
0605fc4843 reformat res/values/strings.xml 2019-04-18 20:22:40 +03:00
Leonid Plyushch
3bbd61f9d7 extra keys view: fix crash in some cases
AndroidRuntime: FATAL EXCEPTION: main
AndroidRuntime: Process: com.termux, PID: 15799
AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.ToggleButton.isPressed()' on a null object reference
AndroidRuntime:        at com.termux.app.ExtraKeysView.readSpecialButton(ExtraKeysView.java:119)
AndroidRuntime:        at com.termux.app.TermuxViewClient.readControlKey(TermuxViewClient.java:116)
AndroidRuntime:        at com.termux.view.TerminalView.inputCodePoint(TerminalView.java:655)
AndroidRuntime:        at com.termux.view.TerminalView$2.sendTextToTerminal(TerminalView.java:336)
AndroidRuntime:        at com.termux.view.TerminalView$2.commitText(TerminalView.java:273)
AndroidRuntime:        at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:341)
AndroidRuntime:        at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:85)
AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:105)
AndroidRuntime:        at android.os.Looper.loop(Looper.java:164)
AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6944)
AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
AndroidRuntime:        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
2019-04-17 03:13:32 +03:00
11 changed files with 152 additions and 104 deletions

View File

@@ -14,8 +14,8 @@ android {
applicationId "com.termux"
minSdkVersion 21
targetSdkVersion 28
versionCode 67
versionName "0.67"
versionCode 71
versionName "0.71"
}
buildTypes {

View File

@@ -30,6 +30,7 @@
<activity
android:name="com.termux.app.TermuxActivity"
android:label="@string/application_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:launchMode="singleTask"
android:resizeableActivity="true"
@@ -37,25 +38,14 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
</activity>
<activity
android:name="com.termux.app.TermuxFailsafeActivity"
android:label="@string/app_failsafe_mode" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.termux.app.TermuxHelpActivity"
android:exported="false"

View File

@@ -108,6 +108,11 @@ public final class BackgroundJob {
// EXTERNAL_STORAGE is needed for /system/bin/am to work on at least
// Samsung S7 - see https://plus.google.com/110070148244138185604/posts/gp8Lk3aCGp3.
environment.add("EXTERNAL_STORAGE=" + System.getenv("EXTERNAL_STORAGE"));
String androidRuntimeRoot = System.getenv("ANDROID_RUNTIME_ROOT");
// ANDROID_RUNTIME_ROOT is required for `am` to run on Android Q
if (androidRuntimeRoot != null) {
environment.add("ANDROID_RUNTIME_ROOT=" + androidRuntimeRoot);
}
if (failSafe) {
// Keep the default path so that system binaries can be used in the failsafe session.
environment.add("PATH= " + System.getenv("PATH"));

View File

@@ -0,0 +1,63 @@
package com.termux.app;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.os.Vibrator;
public class BellUtil {
private static BellUtil instance = null;
private static final Object lock = new Object();
public static BellUtil with(Context context) {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new BellUtil((Vibrator) context.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE));
}
}
}
return instance;
}
private static final long DURATION = 50;
private static final long MIN_PAUSE = 3 * DURATION;
private final Handler handler = new Handler(Looper.getMainLooper());
private long lastBell = 0;
private final Runnable bellRunnable;
private BellUtil(final Vibrator vibrator) {
bellRunnable = new Runnable() {
@Override
public void run() {
if (vibrator != null) {
vibrator.vibrate(DURATION);
}
}
};
}
public synchronized void doBell() {
long now = now();
long timeSinceLastBell = now - lastBell;
if (timeSinceLastBell < 0) {
// there is a next bell pending; don't schedule another one
} else if (timeSinceLastBell < MIN_PAUSE) {
// there was a bell recently, scheudle the next one
handler.postDelayed(bellRunnable, MIN_PAUSE - timeSinceLastBell);
lastBell = lastBell + MIN_PAUSE;
} else {
// the last bell was long ago, do it now
bellRunnable.run();
lastBell = now;
}
}
private long now() {
return SystemClock.uptimeMillis();
}
}

View File

@@ -115,10 +115,14 @@ public final class ExtraKeysView extends GridLayout {
if (! state.isOn)
return false;
if (state.button == null) {
return false;
}
if (state.button.isPressed())
return true;
if (! state.button.isChecked())
return false;

View File

@@ -83,6 +83,8 @@ import androidx.viewpager.widget.ViewPager;
*/
public final class TermuxActivity extends Activity implements ServiceConnection {
public static final String TERMUX_FAILSAFE_SESSION_ACTION = "com.termux.app.failsafe_session";
private static final int CONTEXTMENU_SELECT_URL_ID = 0;
private static final int CONTEXTMENU_SHARE_TRANSCRIPT_ID = 1;
private static final int CONTEXTMENU_PASTE_ID = 3;
@@ -400,7 +402,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
mBellSoundPool.play(mBellSoundId, 1.f, 1.f, 1, 0, 1.f);
break;
case TermuxPreferences.BELL_VIBRATE:
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(50);
BellUtil.with(TermuxActivity.this).doBell();
break;
case TermuxPreferences.BELL_IGNORE:
// Ignore the bell character.
@@ -478,9 +480,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
Bundle bundle = getIntent().getExtras();
boolean launchFailsafe = false;
if (bundle != null) {
launchFailsafe = bundle.getBoolean(TermuxFailsafeActivity.TERMUX_FAILSAFE_SESSION_ACTION, false);
launchFailsafe = bundle.getBoolean(TERMUX_FAILSAFE_SESSION_ACTION, false);
}
clearTemporaryDirectory();
addNewSession(launchFailsafe, null);
} catch (WindowManager.BadTokenException e) {
// Activity finished - ignore.
@@ -494,8 +495,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
Intent i = getIntent();
if (i != null && Intent.ACTION_RUN.equals(i.getAction())) {
// Android 7.1 app shortcut from res/xml/shortcuts.xml.
clearTemporaryDirectory();
addNewSession(false, null);
boolean failSafe = i.getBooleanExtra(TERMUX_FAILSAFE_SESSION_ACTION, false);
addNewSession(failSafe, null);
} else {
switchToSession(getStoredCurrentSessionOrLast());
}
@@ -833,18 +834,4 @@ public final class TermuxActivity extends Activity implements ServiceConnection
}
}
private void clearTemporaryDirectory() {
if (mTermService.getSessions().size() == 0 && !mTermService.isWakelockEnabled()) {
File termuxTmpDir = new File(TermuxService.PREFIX_PATH + "/tmp");
if (termuxTmpDir.exists()) {
try {
TermuxInstaller.deleteFolder(termuxTmpDir);
} catch (Exception e) {
e.printStackTrace();
}
termuxTmpDir.mkdirs();
}
}
}
}

View File

@@ -1,19 +0,0 @@
package com.termux.app;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public final class TermuxFailsafeActivity extends Activity {
public static final String TERMUX_FAILSAFE_SESSION_ACTION = "com.termux.app.failsafe_session";
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Intent intent = new Intent(TermuxFailsafeActivity.this, TermuxActivity.class);
intent.putExtra(TERMUX_FAILSAFE_SESSION_ACTION, true);
startActivity(intent);
finish();
}
}

View File

@@ -214,7 +214,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
builder.setShowWhen(false);
// Background color for small notification icon:
builder.setColor(0xFF000000);
builder.setColor(0xFF607D8B);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
@@ -237,6 +237,18 @@ public final class TermuxService extends Service implements SessionChangedCallba
@Override
public void onDestroy() {
File termuxTmpDir = new File(TermuxService.PREFIX_PATH + "/tmp");
if (termuxTmpDir.exists()) {
try {
TermuxInstaller.deleteFolder(termuxTmpDir.getCanonicalFile());
} catch (Exception e) {
Log.e(EmulatorDebug.LOG_TAG, "Error while removing directory " + termuxTmpDir.getAbsolutePath(), e);
}
termuxTmpDir.mkdirs();
}
if (mWakeLock != null) mWakeLock.release();
if (mWifiLock != null) mWifiLock.release();
@@ -250,14 +262,6 @@ public final class TermuxService extends Service implements SessionChangedCallba
return mTerminalSessions;
}
public boolean isWakelockEnabled() {
if (mWakeLock == null) {
return false;
} else {
return mWakeLock.isHeld();
}
}
TerminalSession createTermSession(String executablePath, String[] arguments, String cwd, boolean failSafe) {
new File(HOME_PATH).mkdirs();

View File

@@ -1,53 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="application_name">Termux</string>
<string name="shared_user_label">Termux user</string>
<string name="app_failsafe_mode">Termux (failsafe)</string>
<string name="new_session">New session</string>
<string name="new_session_failsafe">Failsafe</string>
<string name="toggle_soft_keyboard">Keyboard</string>
<string name="reset_terminal">Reset</string>
<string name="style_terminal">Style</string>
<string name="share_transcript_title">Terminal transcript</string>
<string name="help">Help</string>
<string name="toggle_keep_screen_on">Keep screen on</string>
<string name="application_name">Termux</string>
<string name="shared_user_label">Termux user</string>
<string name="new_session">New session</string>
<string name="new_session_failsafe">Failsafe</string>
<string name="toggle_soft_keyboard">Keyboard</string>
<string name="reset_terminal">Reset</string>
<string name="style_terminal">Style</string>
<string name="share_transcript_title">Terminal transcript</string>
<string name="help">Help</string>
<string name="toggle_keep_screen_on">Keep screen on</string>
<string name="bootstrap_installer_body">Installing…</string>
<string name="bootstrap_error_title">Unable to install</string>
<string name="bootstrap_error_body">Termux was unable to install the bootstrap packages.\n\nCheck your network connection and try again.</string>
<string name="bootstrap_error_abort">Abort</string>
<string name="bootstrap_error_try_again">Try again</string>
<string name="bootstrap_error_not_primary_user_message">Termux can only be installed on the primary user account.</string>
<string name="bootstrap_installer_body">Installing…</string>
<string name="bootstrap_error_title">Unable to install</string>
<string name="bootstrap_error_body">Termux was unable to install the bootstrap packages.\n\nCheck your network connection and try again.</string>
<string name="bootstrap_error_abort">Abort</string>
<string name="bootstrap_error_try_again">Try again</string>
<string name="bootstrap_error_not_primary_user_message">Termux can only be installed on the primary user account.</string>
<string name="max_terminals_reached_title">Max terminals reached</string>
<string name="max_terminals_reached_message">Close down existing ones before creating new.</string>
<string name="max_terminals_reached_title">Max terminals reached</string>
<string name="max_terminals_reached_message">Close down existing ones before creating new.</string>
<string name="reset_toast_notification">Terminal reset.</string>
<string name="reset_toast_notification">Terminal reset.</string>
<string name="select_url">Select URL</string>
<string name="select_url_dialog_title">Click URL to copy or long press to open</string>
<string name="select_all_and_share">Share transcript</string>
<string name="select_url_no_found">No URL found in the terminal.</string>
<string name="select_url_copied_to_clipboard">URL copied to clipboard</string>
<string name="share_transcript_chooser_title">Send text to:</string>
<string name="select_url">Select URL</string>
<string name="select_url_dialog_title">Click URL to copy or long press to open</string>
<string name="select_all_and_share">Share transcript</string>
<string name="select_url_no_found">No URL found in the terminal.</string>
<string name="select_url_copied_to_clipboard">URL copied to clipboard</string>
<string name="share_transcript_chooser_title">Send text to:</string>
<string name="kill_process">Kill process (%d)</string>
<string name="confirm_kill_process">Really kill this session?</string>
<string name="kill_process">Kill process (%d)</string>
<string name="confirm_kill_process">Really kill this session?</string>
<string name="session_rename_title">Set session name</string>
<string name="session_rename_positive_button">Set</string>
<string name="session_new_named_title">New named session</string>
<string name="session_new_named_positive_button">Create</string>
<string name="session_rename_title">Set session name</string>
<string name="session_rename_positive_button">Set</string>
<string name="session_new_named_title">New named session</string>
<string name="session_new_named_positive_button">Create</string>
<string name="styling_not_installed">The Termux:Style add-on is not installed.</string>
<string name="styling_install">Install</string>
<string name="styling_not_installed">The Termux:Style add-on is not installed.</string>
<string name="styling_install">Install</string>
<string name="notification_action_exit">Exit</string>
<string name="notification_action_wake_lock">Acquire wakelock</string>
<string name="notification_action_wake_unlock">Release wakelock</string>
<string name="file_received_title">Save file in ~/downloads/</string>
<string name="file_received_edit_button">Edit</string>
<string name="file_received_open_folder_button">Open folder</string>
<string name="notification_action_exit">Exit</string>
<string name="notification_action_wake_lock">Acquire wakelock</string>
<string name="notification_action_wake_unlock">Release wakelock</string>
<string name="file_received_title">Save file in ~/downloads/</string>
<string name="file_received_edit_button">Edit</string>
<string name="file_received_open_folder_button">Open folder</string>
</resources>

View File

@@ -1,5 +1,6 @@
<shortcuts xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="new_session"
android:enabled="true"
@@ -11,4 +12,19 @@
android:targetPackage="com.termux"
android:targetClass="com.termux.app.TermuxActivity"/>
</shortcut>
<shortcut
android:shortcutId="new_failsafe_session"
android:enabled="true"
android:icon="@drawable/ic_new_session"
android:shortcutShortLabel="@string/new_session_failsafe"
tools:targetApi="n_mr1">
<intent
android:action="android.intent.action.RUN"
android:targetPackage="com.termux"
android:targetClass="com.termux.app.TermuxActivity">
<extra android:name="com.termux.app.failsafe_session" android:value="true" />
</intent>
</shortcut>
</shortcuts>

View File

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