mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-05 02:05:25 +08:00
Define TermuxConstants
class to store all shared constants of Termux app and its plugins
This commit removes almost all hardcoded paths in Termux app and moves the references to the `TermuxConstants` class. The `TermuxConstants` class should be imported by other termux plugin apps instead of copying and defining their own constants. The 3rd party apps can also import it for interacting with termux apps. App and sub class specific constants are defined in their own nested classes to keep them segregated from each other and for better readability.
This commit is contained in:
@@ -21,6 +21,15 @@ android {
|
||||
versionCode 108
|
||||
versionName "0.108"
|
||||
|
||||
manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux"
|
||||
manifestPlaceholders.TERMUX_APP_NAME = "Termux"
|
||||
manifestPlaceholders.TERMUX_API_APP_NAME = "Termux:API"
|
||||
manifestPlaceholders.TERMUX_BOOT_APP_NAME = "Termux:Boot"
|
||||
manifestPlaceholders.TERMUX_FLOAT_APP_NAME = "Termux:Float"
|
||||
manifestPlaceholders.TERMUX_STYLING_APP_NAME = "Termux:Styling"
|
||||
manifestPlaceholders.TERMUX_TASKER_APP_NAME = "Termux:Tasker"
|
||||
manifestPlaceholders.TERMUX_WIDGET_APP_NAME = "Termux:Widget"
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
cFlags "-std=c11", "-Wall", "-Wextra", "-Werror", "-Os", "-fno-stack-protector", "-Wl,--gc-sections"
|
||||
|
@@ -2,13 +2,13 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.termux"
|
||||
android:installLocation="internalOnly"
|
||||
android:sharedUserId="com.termux"
|
||||
android:sharedUserId="${TERMUX_PACKAGE_NAME}"
|
||||
android:sharedUserLabel="@string/shared_user_label" >
|
||||
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
|
||||
<permission android:name="com.termux.permission.RUN_COMMAND"
|
||||
<permission android:name="${TERMUX_PACKAGE_NAME}.permission.RUN_COMMAND"
|
||||
android:label="@string/run_command_permission_label"
|
||||
android:description="@string/run_command_permission_description"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@@ -28,13 +28,14 @@
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<application
|
||||
android:extractNativeLibs="true"
|
||||
android:allowBackup="false"
|
||||
android:label="@string/application_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:banner="@drawable/banner"
|
||||
android:label="@string/application_name"
|
||||
android:theme="@style/Theme.Termux"
|
||||
|
||||
android:extractNativeLibs="true"
|
||||
android:allowBackup="false"
|
||||
android:supportsRtl="false" >
|
||||
|
||||
<!-- This (or rather, value 2.1 or higher) is needed to make the Samsung Galaxy S8
|
||||
@@ -42,7 +43,7 @@
|
||||
<meta-data android:name="android.max_aspect" android:value="10.0" />
|
||||
|
||||
<activity
|
||||
android:name="com.termux.app.TermuxActivity"
|
||||
android:name=".app.TermuxActivity"
|
||||
android:label="@string/application_name"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
|
||||
android:launchMode="singleTask"
|
||||
@@ -60,7 +61,7 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="com.termux.app.TermuxHelpActivity"
|
||||
android:name=".app.TermuxHelpActivity"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.Material.Light.DarkActionBar"
|
||||
android:parentActivityName=".app.TermuxActivity"
|
||||
@@ -68,9 +69,9 @@
|
||||
android:label="@string/application_name" />
|
||||
|
||||
<activity
|
||||
android:name="com.termux.filepicker.TermuxFileReceiverActivity"
|
||||
android:name=".filepicker.TermuxFileReceiverActivity"
|
||||
android:label="@string/application_name"
|
||||
android:taskAffinity="com.termux.filereceiver"
|
||||
android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver"
|
||||
android:excludeFromRecents="true"
|
||||
android:resizeableActivity="true"
|
||||
android:noHistory="true">
|
||||
@@ -100,7 +101,7 @@
|
||||
|
||||
<activity-alias
|
||||
android:name=".HomeActivity"
|
||||
android:targetActivity="com.termux.app.TermuxActivity">
|
||||
android:targetActivity=".app.TermuxActivity">
|
||||
|
||||
<!-- Launch activity automatically on boot on Android Things devices -->
|
||||
<intent-filter>
|
||||
@@ -112,7 +113,7 @@
|
||||
|
||||
<provider
|
||||
android:name=".filepicker.TermuxDocumentsProvider"
|
||||
android:authorities="com.termux.documents"
|
||||
android:authorities="${TERMUX_PACKAGE_NAME}.documents"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.MANAGE_DOCUMENTS">
|
||||
@@ -122,25 +123,25 @@
|
||||
</provider>
|
||||
|
||||
<service
|
||||
android:name="com.termux.app.TermuxService"
|
||||
android:name=".app.TermuxService"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".app.RunCommandService"
|
||||
android:exported="true"
|
||||
android:permission="com.termux.permission.RUN_COMMAND" >
|
||||
android:permission="${TERMUX_PACKAGE_NAME}.permission.RUN_COMMAND" >
|
||||
<intent-filter>
|
||||
<action android:name="com.termux.RUN_COMMAND" />
|
||||
<action android:name="${TERMUX_PACKAGE_NAME}.RUN_COMMAND" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<receiver android:name=".app.TermuxOpenReceiver" />
|
||||
|
||||
<provider android:authorities="com.termux.files"
|
||||
<provider android:authorities="${TERMUX_PACKAGE_NAME}.files"
|
||||
android:readPermission="android.permission.permRead"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:name="com.termux.app.TermuxOpenReceiver$ContentProvider" />
|
||||
android:name=".app.TermuxOpenReceiver$ContentProvider" />
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
|
||||
</application>
|
||||
|
@@ -36,7 +36,7 @@ public final class BackgroundJob {
|
||||
|
||||
public BackgroundJob(String cwd, String fileToExecute, final String[] args, final TermuxService service, PendingIntent pendingIntent) {
|
||||
String[] env = buildEnvironment(false, cwd);
|
||||
if (cwd == null || cwd.isEmpty()) cwd = TermuxService.HOME_PATH;
|
||||
if (cwd == null || cwd.isEmpty()) cwd = TermuxConstants.HOME_PATH;
|
||||
|
||||
final String[] progArray = setupProcessArgs(fileToExecute, args);
|
||||
final String processDescription = Arrays.toString(progArray);
|
||||
@@ -134,17 +134,17 @@ public final class BackgroundJob {
|
||||
}
|
||||
|
||||
static String[] buildEnvironment(boolean failSafe, String cwd) {
|
||||
new File(TermuxService.HOME_PATH).mkdirs();
|
||||
new File(TermuxConstants.HOME_PATH).mkdirs();
|
||||
|
||||
if (cwd == null || cwd.isEmpty()) cwd = TermuxService.HOME_PATH;
|
||||
if (cwd == null || cwd.isEmpty()) cwd = TermuxConstants.HOME_PATH;
|
||||
|
||||
List<String> environment = new ArrayList<>();
|
||||
|
||||
environment.add("TERMUX_VERSION=" + BuildConfig.VERSION_NAME);
|
||||
environment.add("TERM=xterm-256color");
|
||||
environment.add("COLORTERM=truecolor");
|
||||
environment.add("HOME=" + TermuxService.HOME_PATH);
|
||||
environment.add("PREFIX=" + TermuxService.PREFIX_PATH);
|
||||
environment.add("HOME=" + TermuxConstants.HOME_PATH);
|
||||
environment.add("PREFIX=" + TermuxConstants.PREFIX_PATH);
|
||||
environment.add("BOOTCLASSPATH=" + System.getenv("BOOTCLASSPATH"));
|
||||
environment.add("ANDROID_ROOT=" + System.getenv("ANDROID_ROOT"));
|
||||
environment.add("ANDROID_DATA=" + System.getenv("ANDROID_DATA"));
|
||||
@@ -164,9 +164,9 @@ public final class BackgroundJob {
|
||||
environment.add("PATH= " + System.getenv("PATH"));
|
||||
} else {
|
||||
environment.add("LANG=en_US.UTF-8");
|
||||
environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin");
|
||||
environment.add("PATH=" + TermuxConstants.PREFIX_PATH + "/bin");
|
||||
environment.add("PWD=" + cwd);
|
||||
environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp");
|
||||
environment.add("TMPDIR=" + TermuxConstants.PREFIX_PATH + "/tmp");
|
||||
}
|
||||
|
||||
return environment.toArray(new String[0]);
|
||||
@@ -215,7 +215,7 @@ public final class BackgroundJob {
|
||||
if (executable.startsWith("/usr") || executable.startsWith("/bin")) {
|
||||
String[] parts = executable.split("/");
|
||||
String binary = parts[parts.length - 1];
|
||||
interpreter = TermuxService.PREFIX_PATH + "/bin/" + binary;
|
||||
interpreter = TermuxConstants.PREFIX_PATH + "/bin/" + binary;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ public final class BackgroundJob {
|
||||
}
|
||||
} else {
|
||||
// No shebang and no ELF, use standard shell.
|
||||
interpreter = TermuxService.PREFIX_PATH + "/bin/sh";
|
||||
interpreter = TermuxConstants.PREFIX_PATH + "/bin/sh";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,8 @@ import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.RUN_COMMAND_SERVICE;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@@ -77,12 +79,6 @@ import java.util.Properties;
|
||||
*/
|
||||
public class RunCommandService extends Service {
|
||||
|
||||
public static final String RUN_COMMAND_ACTION = "com.termux.RUN_COMMAND";
|
||||
public static final String RUN_COMMAND_PATH = "com.termux.RUN_COMMAND_PATH";
|
||||
public static final String RUN_COMMAND_ARGUMENTS = "com.termux.RUN_COMMAND_ARGUMENTS";
|
||||
public static final String RUN_COMMAND_WORKDIR = "com.termux.RUN_COMMAND_WORKDIR";
|
||||
public static final String RUN_COMMAND_BACKGROUND = "com.termux.RUN_COMMAND_BACKGROUND";
|
||||
|
||||
private static final String NOTIFICATION_CHANNEL_ID = "termux_run_command_notification_channel";
|
||||
private static final int NOTIFICATION_ID = 1338;
|
||||
|
||||
@@ -108,7 +104,7 @@ public class RunCommandService extends Service {
|
||||
runStartForeground();
|
||||
|
||||
// If wrong action passed, then just return
|
||||
if (!RUN_COMMAND_ACTION.equals(intent.getAction())) {
|
||||
if (!RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND.equals(intent.getAction())) {
|
||||
Log.e("termux", "Unexpected intent action to RunCommandService: " + intent.getAction());
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
@@ -119,16 +115,16 @@ public class RunCommandService extends Service {
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
|
||||
Uri programUri = new Uri.Builder().scheme("com.termux.file").path(getExpandedTermuxPath(intent.getStringExtra(RUN_COMMAND_PATH))).build();
|
||||
Uri programUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(getExpandedTermuxPath(intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_COMMAND_PATH))).build();
|
||||
|
||||
Intent execIntent = new Intent(TermuxService.ACTION_EXECUTE, programUri);
|
||||
Intent execIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, programUri);
|
||||
execIntent.setClass(this, TermuxService.class);
|
||||
execIntent.putExtra(TermuxService.EXTRA_ARGUMENTS, intent.getStringArrayExtra(RUN_COMMAND_ARGUMENTS));
|
||||
execIntent.putExtra(TermuxService.EXTRA_EXECUTE_IN_BACKGROUND, intent.getBooleanExtra(RUN_COMMAND_BACKGROUND, false));
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, intent.getStringArrayExtra(RUN_COMMAND_SERVICE.EXTRA_ARGUMENTS));
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, intent.getBooleanExtra(RUN_COMMAND_SERVICE.EXTRA_BACKGROUND, false));
|
||||
|
||||
String workingDirectory = intent.getStringExtra(RUN_COMMAND_WORKDIR);
|
||||
String workingDirectory = intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_WORKDIR);
|
||||
if (workingDirectory != null && !workingDirectory.isEmpty()) {
|
||||
execIntent.putExtra(TermuxService.EXTRA_CURRENT_WORKING_DIRECTORY, getExpandedTermuxPath(workingDirectory));
|
||||
execIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, getExpandedTermuxPath(workingDirectory));
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
@@ -188,9 +184,9 @@ public class RunCommandService extends Service {
|
||||
}
|
||||
|
||||
private boolean allowExternalApps() {
|
||||
File propsFile = new File(TermuxService.HOME_PATH + "/.termux/termux.properties");
|
||||
File propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_PRIMARY_PATH);
|
||||
if (!propsFile.exists())
|
||||
propsFile = new File(TermuxService.HOME_PATH + "/.config/termux/termux.properties");
|
||||
propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_SECONDARY_PATH);
|
||||
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
@@ -209,10 +205,10 @@ public class RunCommandService extends Service {
|
||||
/** Replace "$PREFIX/" or "~/" prefix with termux absolute paths */
|
||||
public static String getExpandedTermuxPath(String path) {
|
||||
if(path != null && !path.isEmpty()) {
|
||||
path = path.replaceAll("^\\$PREFIX$", TermuxService.PREFIX_PATH);
|
||||
path = path.replaceAll("^\\$PREFIX/", TermuxService.PREFIX_PATH + "/");
|
||||
path = path.replaceAll("^~/$", TermuxService.HOME_PATH);
|
||||
path = path.replaceAll("^~/", TermuxService.HOME_PATH + "/");
|
||||
path = path.replaceAll("^\\$PREFIX$", TermuxConstants.PREFIX_PATH);
|
||||
path = path.replaceAll("^\\$PREFIX/", TermuxConstants.PREFIX_PATH + "/");
|
||||
path = path.replaceAll("^~/$", TermuxConstants.HOME_PATH);
|
||||
path = path.replaceAll("^~/", TermuxConstants.HOME_PATH + "/");
|
||||
}
|
||||
|
||||
return path;
|
||||
|
@@ -2,7 +2,6 @@ package com.termux.app;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
@@ -48,6 +47,7 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY;
|
||||
import com.termux.terminal.EmulatorDebug;
|
||||
import com.termux.terminal.TerminalColors;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
@@ -84,8 +84,6 @@ 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;
|
||||
@@ -100,9 +98,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
|
||||
private static final int REQUESTCODE_PERMISSION_STORAGE = 1234;
|
||||
|
||||
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
|
||||
|
||||
private static final String BROADCAST_TERMUX_OPENED = "com.termux.app.OPENED";
|
||||
private static final String BROADCAST_TERMUX_OPENED = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.OPENED";
|
||||
|
||||
/** The main view of the activity showing the terminal. Initialized in onCreate(). */
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@@ -145,7 +142,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (mIsVisible) {
|
||||
String whatToReload = intent.getStringExtra(RELOAD_STYLE_ACTION);
|
||||
String whatToReload = intent.getStringExtra(TERMUX_ACTIVITY.EXTRA_RELOAD_STYLE);
|
||||
if ("storage".equals(whatToReload)) {
|
||||
if (ensureStoragePermissionGranted())
|
||||
TermuxInstaller.setupStorageSymlinks(TermuxActivity.this);
|
||||
@@ -163,8 +160,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
|
||||
void checkForFontAndColors() {
|
||||
try {
|
||||
@SuppressLint("SdCardPath") File fontFile = new File("/data/data/com.termux/files/home/.termux/font.ttf");
|
||||
@SuppressLint("SdCardPath") File colorsFile = new File("/data/data/com.termux/files/home/.termux/colors.properties");
|
||||
File colorsFile = new File(TermuxConstants.COLOR_PROPERTIES_PATH);
|
||||
File fontFile = new File(TermuxConstants.FONT_PATH);
|
||||
|
||||
final Properties props = new Properties();
|
||||
if (colorsFile.isFile()) {
|
||||
@@ -541,7 +538,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
Bundle bundle = getIntent().getExtras();
|
||||
boolean launchFailsafe = false;
|
||||
if (bundle != null) {
|
||||
launchFailsafe = bundle.getBoolean(TERMUX_FAILSAFE_SESSION_ACTION, false);
|
||||
launchFailsafe = bundle.getBoolean(TERMUX_ACTIVITY.ACTION_FAILSAFE_SESSION, false);
|
||||
}
|
||||
addNewSession(launchFailsafe, null);
|
||||
} catch (WindowManager.BadTokenException e) {
|
||||
@@ -556,7 +553,7 @@ 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.
|
||||
boolean failSafe = i.getBooleanExtra(TERMUX_FAILSAFE_SESSION_ACTION, false);
|
||||
boolean failSafe = i.getBooleanExtra(TERMUX_ACTIVITY.ACTION_FAILSAFE_SESSION, false);
|
||||
addNewSession(failSafe, null);
|
||||
} else {
|
||||
switchToSession(getStoredCurrentSessionOrLast());
|
||||
@@ -612,7 +609,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
mListViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
registerReceiver(mBroadcastReceiever, new IntentFilter(RELOAD_STYLE_ACTION));
|
||||
registerReceiver(mBroadcastReceiever, new IntentFilter(TERMUX_ACTIVITY.ACTION_RELOAD_STYLE));
|
||||
|
||||
// The current terminal session may have changed while being away, force
|
||||
// a refresh of the displayed terminal:
|
||||
@@ -914,14 +911,14 @@ public final class TermuxActivity extends Activity implements ServiceConnection
|
||||
}
|
||||
case CONTEXTMENU_STYLING_ID: {
|
||||
Intent stylingIntent = new Intent();
|
||||
stylingIntent.setClassName("com.termux.styling", "com.termux.styling.TermuxStyleActivity");
|
||||
stylingIntent.setClassName(TermuxConstants.TERMUX_STYLING_PACKAGE_NAME, TermuxConstants.TERMUX_STYLING.TERMUX_STYLING_ACTIVITY_NAME);
|
||||
try {
|
||||
startActivity(stylingIntent);
|
||||
} catch (ActivityNotFoundException | IllegalArgumentException e) {
|
||||
// The startActivity() call is not documented to throw IllegalArgumentException.
|
||||
// However, crash reporting shows that it sometimes does, so catch it here.
|
||||
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("https://f-droid.org/en/packages/com.termux.styling/")))).setNegativeButton(android.R.string.cancel, null).show();
|
||||
new AlertDialog.Builder(this).setMessage(getString(R.string.styling_not_installed))
|
||||
.setPositiveButton(R.string.styling_install, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://f-droid.org/en/packages/" + TermuxConstants.TERMUX_STYLING_PACKAGE_NAME + " /")))).setNegativeButton(android.R.string.cancel, null).show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
232
app/src/main/java/com/termux/app/TermuxConstants.java
Normal file
232
app/src/main/java/com/termux/app/TermuxConstants.java
Normal file
@@ -0,0 +1,232 @@
|
||||
package com.termux.app;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
// Version: v0.1.0
|
||||
|
||||
/**
|
||||
* A class that defines shared constants of the Termux app and its plugins.
|
||||
* This class will be hosted by termux-app and should be imported by other termux plugin apps as is
|
||||
* instead of copying constants to random classes. The 3rd party apps can also import it for
|
||||
* interacting with termux apps.
|
||||
*
|
||||
* Termux app default package name is "com.termux" and is used in PREFIX_PATH.
|
||||
* The binaries compiled for termux have PREFIX_PATH hardcoded in them but it can be changed during
|
||||
* compilation.
|
||||
*
|
||||
* The TERMUX_PACKAGE_NAME must be the same as the applicationId of termux-app build.gradle since
|
||||
* its also used by FILES_PATH.
|
||||
* If TERMUX_PACKAGE_NAME is changed, then binaries, specially used in bootstrap need to be compiled
|
||||
* appropriately. Check https://github.com/termux/termux-packages/wiki/Building-packages for more info.
|
||||
*
|
||||
* Ideally the only places where changes should be required if changing package name are the following:
|
||||
* - The TERMUX_PACKAGE_NAME in TermuxConstants.
|
||||
* - The "applicationId" in "build.gradle". This is package name that android and app stores will
|
||||
* use and is also the final package name stored in "AndroidManifest.xml".
|
||||
* - The "manifestPlaceholders" values for TERMUX_PACKAGE_NAME and *_APP_NAME in "build.gradle".
|
||||
* - The "ENTITY" values for TERMUX_PACKAGE_NAME and *_APP_NAME in "strings.xml".
|
||||
* - The "shortcut.xml" files like in termux-app since dynamic variables don't work in it.
|
||||
* - Optionally the "package" in "AndroidManifest.xml" if modifying project structure. This is
|
||||
* package name for java classes project structure and is prefixed if activity and service
|
||||
* names use dot (.) notation.
|
||||
* - Optionally the *_PATH variables in TermuxConstants containing the string "termux".
|
||||
*
|
||||
* Check https://developer.android.com/studio/build/application-id for info on "package" in
|
||||
* "AndroidManifest.xml" and "applicationId" in "build.gradle".
|
||||
*
|
||||
* TERMUX_PACKAGE_NAME must be used in source code of Termux app and its plugins instead of hardcoded
|
||||
* "com.termux" paths.
|
||||
*/
|
||||
|
||||
public final class TermuxConstants {
|
||||
|
||||
/**
|
||||
* Termux app and plugin app and package names.
|
||||
*/
|
||||
|
||||
public static final String TERMUX_APP_NAME = "Termux"; // Default: "Termux"
|
||||
public static final String TERMUX_PACKAGE_NAME = "com.termux"; // Default: "com.termux"
|
||||
|
||||
public static final String TERMUX_API_APP_NAME = "Termux:API"; // Default: "Termux:API"
|
||||
public static final String TERMUX_API_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".api"; // Default: "com.termux.api"
|
||||
|
||||
public static final String TERMUX_BOOT_APP_NAME = "Termux:Boot"; // Default: "Termux:Boot"
|
||||
public static final String TERMUX_BOOT_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".boot"; // Default: "com.termux.boot"
|
||||
|
||||
public static final String TERMUX_FLOAT_APP_NAME = "Termux:Float"; // Default: "Termux:Float"
|
||||
public static final String TERMUX_FLOAT_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".window"; // Default: "com.termux.window"
|
||||
|
||||
public static final String TERMUX_STYLING_APP_NAME = "Termux:Styling"; // Default: "Termux:Styling"
|
||||
public static final String TERMUX_STYLING_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".styling"; // Default: "com.termux.styling"
|
||||
|
||||
public static final String TERMUX_TASKER_APP_NAME = "Termux:Tasker"; // Default: "Termux:Tasker"
|
||||
public static final String TERMUX_TASKER_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".tasker"; // Default: "com.termux.tasker"
|
||||
|
||||
public static final String TERMUX_WIDGET_APP_NAME = "Termux:Widget"; // Default: "Termux:Widget"
|
||||
public static final String TERMUX_WIDGET_PACKAGE_NAME = TERMUX_PACKAGE_NAME + ".widget"; // Default: "com.termux.widget"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux app core paths.
|
||||
*/
|
||||
|
||||
@SuppressLint("SdCardPath")
|
||||
public static final String FILES_PATH = "/data/data/" + TERMUX_PACKAGE_NAME + "/files"; // Default: "/data/data/com.termux/files"
|
||||
public static final String PREFIX_PATH = FILES_PATH + "/usr"; // Termux $PREFIX path. Default: "/data/data/com.termux/files/usr"
|
||||
public static final String HOME_PATH = FILES_PATH + "/home"; // Termux $HOME path. Default: "/data/data/com.termux/files/home"
|
||||
public static final String DATA_HOME_PATH = HOME_PATH + "/.termux"; // Default: "/data/data/com.termux/files/home/.termux"
|
||||
public static final String CONFIG_HOME_PATH = HOME_PATH + "/.config/termux"; // Default: "/data/data/com.termux/files/home/.config/termux"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux app plugin specific paths.
|
||||
*/
|
||||
|
||||
// Path to store scripts to be run at boot by Termux:Boot
|
||||
public static final String BOOT_SCRIPTS_PATH = DATA_HOME_PATH + "/boot"; // Default: "/data/data/com.termux/files/home/.termux/boot"
|
||||
|
||||
// Path to store foreground scripts that can be run by the termux launcher widget provided by Termux:Widget
|
||||
public static final String SHORTCUT_SCRIPTS_PATH = DATA_HOME_PATH + "/shortcuts"; // Default: "/data/data/com.termux/files/home/.termux/shortcuts"
|
||||
|
||||
// Path to store background scripts that can be run by the termux launcher widget provided by Termux:Widget
|
||||
public static final String SHORTCUT_TASKS_SCRIPTS_PATH = DATA_HOME_PATH + "/shortcuts/tasks"; // Default: "/data/data/com.termux/files/home/.termux/shortcuts/tasks"
|
||||
|
||||
// Path to store scripts to be run by 3rd party twofortyfouram locale plugin host apps like Tasker app via the Termux:Tasker plugin client
|
||||
public static final String TASKER_SCRIPTS_PATH = DATA_HOME_PATH + "/tasker"; // Default: "/data/data/com.termux/files/home/.termux/tasker"
|
||||
|
||||
// Termux app termux.properties primary path
|
||||
public static final String TERMUX_PROPERTIES_PRIMARY_PATH = DATA_HOME_PATH + "/termux.properties"; // Default: "/data/data/com.termux/files/home/.termux/termux.properties"
|
||||
|
||||
// Termux app termux.properties secondary path
|
||||
public static final String TERMUX_PROPERTIES_SECONDARY_PATH = CONFIG_HOME_PATH + "/termux.properties"; // Default: "/data/data/com.termux/files/home/.config/termux/termux.properties"
|
||||
|
||||
// Termux app and Termux:Styling colors.properties path
|
||||
public static final String COLOR_PROPERTIES_PATH = DATA_HOME_PATH + "/colors.properties"; // Default: "/data/data/com.termux/files/home/.termux/colors.properties"
|
||||
|
||||
// Termux app and Termux:Styling font.ttf path
|
||||
public static final String FONT_PATH = DATA_HOME_PATH + "/font.ttf"; // Default: "/data/data/com.termux/files/home/.termux/font.ttf"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux app plugin specific path File objects.
|
||||
*/
|
||||
|
||||
public static final File FILES_DIR = new File(FILES_PATH);
|
||||
public static final File PREFIX_DIR = new File(PREFIX_PATH);
|
||||
public static final File HOME_DIR = new File(HOME_PATH);
|
||||
public static final File DATA_HOME_DIR = new File(DATA_HOME_PATH);
|
||||
public static final File CONFIG_HOME_DIR = new File(CONFIG_HOME_PATH);
|
||||
public static final File BOOT_SCRIPTS_DIR = new File(BOOT_SCRIPTS_PATH);
|
||||
public static final File SHORTCUT_SCRIPTS_DIR = new File(SHORTCUT_SCRIPTS_PATH);
|
||||
public static final File SHORTCUT_TASKS_SCRIPTS_DIR = new File(SHORTCUT_TASKS_SCRIPTS_PATH);
|
||||
public static final File TASKER_SCRIPTS_DIR = new File(TASKER_SCRIPTS_PATH);
|
||||
|
||||
|
||||
|
||||
// Android OS permission declared by Termux app in AndroidManifest.xml which can be requested by 3rd party apps to run various commands in Termux app context
|
||||
public static final String PERMISSION_RUN_COMMAND = TERMUX_PACKAGE_NAME + ".permission.RUN_COMMAND"; // Default: "com.termux.permission.RUN_COMMAND"
|
||||
|
||||
// Termux property defined in termux.properties file as a secondary check to PERMISSION_RUN_COMMAND to allow 3rd party apps to run various commands in Termux app context
|
||||
public static final String PROP_ALLOW_EXTERNAL_APPS = "allow-external-apps"; // Default: "allow-external-apps"
|
||||
public static final String PROP_DEFAULT_VALUE_ALLOW_EXTERNAL_APPS = "false"; // Default: "false"
|
||||
|
||||
|
||||
/**
|
||||
* Termux app constants.
|
||||
*/
|
||||
|
||||
public static final class TERMUX_APP {
|
||||
|
||||
/**
|
||||
* Termux app core activity.
|
||||
*/
|
||||
|
||||
public static final String TERMUX_ACTIVITY_NAME = TERMUX_PACKAGE_NAME + ".app.TermuxActivity"; // Default: "com.termux.app.TermuxActivity"
|
||||
public static final class TERMUX_ACTIVITY {
|
||||
|
||||
// Intent action to start termux failsafe session
|
||||
public static final String ACTION_FAILSAFE_SESSION = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.failsafe_session"; // Default: "com.termux.app.failsafe_session"
|
||||
|
||||
// Intent action to make termux reload its termux session styling
|
||||
public static final String ACTION_RELOAD_STYLE = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.reload_style"; // Default: "com.termux.app.reload_style"
|
||||
// Intent extra for what to reload for the TERMUX_ACTIVITY.ACTION_RELOAD_STYLE intent
|
||||
public static final String EXTRA_RELOAD_STYLE = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.reload_style"; // Default: "com.termux.app.reload_style"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux app core service.
|
||||
*/
|
||||
|
||||
public static final String TERMUX_SERVICE_NAME = TERMUX_PACKAGE_NAME + ".app.TermuxService"; // Default: "com.termux.app.TermuxService"
|
||||
public static final class TERMUX_SERVICE {
|
||||
|
||||
// Intent action to stop TERMUX_SERVICE
|
||||
public static final String ACTION_STOP_SERVICE = TERMUX_PACKAGE_NAME + ".service_stop"; // Default: "com.termux.service_stop"
|
||||
|
||||
// Intent action to make TERMUX_SERVICE acquire a wakelock
|
||||
public static final String ACTION_WAKE_LOCK = TERMUX_PACKAGE_NAME + ".service_wake_lock"; // Default: "com.termux.service_wake_lock"
|
||||
|
||||
// Intent action to make TERMUX_SERVICE release wakelock
|
||||
public static final String ACTION_WAKE_UNLOCK = TERMUX_PACKAGE_NAME + ".service_wake_unlock"; // Default: "com.termux.service_wake_unlock"
|
||||
|
||||
// Intent action to execute command with TERMUX_SERVICE
|
||||
public static final String ACTION_SERVICE_EXECUTE = TERMUX_PACKAGE_NAME + ".service_execute"; // Default: "com.termux.service_execute"
|
||||
// Uri scheme for paths sent via intent to TERMUX_SERVICE
|
||||
public static final String URI_SCHEME_SERVICE_EXECUTE = TERMUX_PACKAGE_NAME + ".file"; // Default: "com.termux.file"
|
||||
// Intent extra for command arguments for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent
|
||||
public static final String EXTRA_ARGUMENTS = TERMUX_PACKAGE_NAME + ".execute.arguments"; // Default: "com.termux.execute.arguments"
|
||||
// Intent extra for command current working directory for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent
|
||||
public static final String EXTRA_WORKDIR = TERMUX_PACKAGE_NAME + ".execute.cwd"; // Default: "com.termux.execute.cwd"
|
||||
// Intent extra for command background mode for the TERMUX_SERVICE.ACTION_SERVICE_EXECUTE intent
|
||||
public static final String EXTRA_BACKGROUND = TERMUX_PACKAGE_NAME + ".execute.background"; // Default: "com.termux.execute.background"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux app service to receive commands sent by 3rd party apps.
|
||||
*/
|
||||
|
||||
public static final String RUN_COMMAND_SERVICE_NAME = TERMUX_PACKAGE_NAME + ".app.RunCommandService"; // Termux app service to receive commands from 3rd party apps "com.termux.app.RunCommandService"
|
||||
public static final class RUN_COMMAND_SERVICE {
|
||||
|
||||
// Intent action to execute command with RUN_COMMAND_SERVICE
|
||||
public static final String ACTION_RUN_COMMAND = TERMUX_PACKAGE_NAME + ".RUN_COMMAND"; // Default: "com.termux.RUN_COMMAND"
|
||||
// Intent extra for command path for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent
|
||||
public static final String EXTRA_COMMAND_PATH = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_PATH"; // Default: "com.termux.RUN_COMMAND_PATH"
|
||||
// Intent extra for command arguments for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent
|
||||
public static final String EXTRA_ARGUMENTS = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_ARGUMENTS"; // Default: "com.termux.RUN_COMMAND_ARGUMENTS"
|
||||
// Intent extra for command current working directory for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent
|
||||
public static final String EXTRA_WORKDIR = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_WORKDIR"; // Default: "com.termux.RUN_COMMAND_WORKDIR"
|
||||
// Intent extra for command background mode for the RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND intent
|
||||
public static final String EXTRA_BACKGROUND = TERMUX_PACKAGE_NAME + ".RUN_COMMAND_BACKGROUND"; // Default: "com.termux.RUN_COMMAND_BACKGROUND"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Termux:Styling app constants.
|
||||
*/
|
||||
|
||||
public static final class TERMUX_STYLING {
|
||||
|
||||
/**
|
||||
* Termux:Styling app core activity constants.
|
||||
*/
|
||||
|
||||
public static final String TERMUX_STYLING_ACTIVITY_NAME = TERMUX_STYLING_PACKAGE_NAME + ".TermuxStyleActivity"; // Default: "com.termux.styling.TermuxStyleActivity"
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -58,7 +58,7 @@ final class TermuxInstaller {
|
||||
return;
|
||||
}
|
||||
|
||||
final File PREFIX_FILE = new File(TermuxService.PREFIX_PATH);
|
||||
final File PREFIX_FILE = new File(TermuxConstants.PREFIX_PATH);
|
||||
if (PREFIX_FILE.isDirectory()) {
|
||||
whenDone.run();
|
||||
return;
|
||||
@@ -69,7 +69,7 @@ final class TermuxInstaller {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final String STAGING_PREFIX_PATH = TermuxService.FILES_PATH + "/usr-staging";
|
||||
final String STAGING_PREFIX_PATH = TermuxConstants.FILES_PATH + "/usr-staging";
|
||||
final File STAGING_PREFIX_FILE = new File(STAGING_PREFIX_PATH);
|
||||
|
||||
if (STAGING_PREFIX_FILE.exists()) {
|
||||
@@ -194,7 +194,7 @@ final class TermuxInstaller {
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
File storageDir = new File(TermuxService.HOME_PATH, "storage");
|
||||
File storageDir = new File(TermuxConstants.HOME_PATH, "storage");
|
||||
|
||||
if (storageDir.exists()) {
|
||||
try {
|
||||
|
@@ -178,7 +178,7 @@ public class TermuxOpenReceiver extends BroadcastReceiver {
|
||||
String path = file.getCanonicalPath();
|
||||
String storagePath = Environment.getExternalStorageDirectory().getCanonicalPath();
|
||||
// See https://support.google.com/faqs/answer/7496913:
|
||||
if (!(path.startsWith(TermuxService.FILES_PATH) || path.startsWith(storagePath))) {
|
||||
if (!(path.startsWith(TermuxConstants.FILES_PATH) || path.startsWith(storagePath))) {
|
||||
throw new IllegalArgumentException("Invalid path: " + path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@@ -170,9 +170,9 @@ final class TermuxPreferences {
|
||||
}
|
||||
|
||||
void reloadFromProperties(Context context) {
|
||||
File propsFile = new File(TermuxService.HOME_PATH + "/.termux/termux.properties");
|
||||
File propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_PRIMARY_PATH);
|
||||
if (!propsFile.exists())
|
||||
propsFile = new File(TermuxService.HOME_PATH + "/.config/termux/termux.properties");
|
||||
propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_SECONDARY_PATH);
|
||||
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
@@ -213,12 +213,12 @@ final class TermuxPreferences {
|
||||
mUseFullScreen = "true".equals(props.getProperty("fullscreen", "false").toLowerCase());
|
||||
mUseFullScreenWorkAround = "true".equals(props.getProperty("use-fullscreen-workaround", "false").toLowerCase());
|
||||
|
||||
mDefaultWorkingDir = props.getProperty("default-working-directory", TermuxService.HOME_PATH);
|
||||
mDefaultWorkingDir = props.getProperty("default-working-directory", TermuxConstants.HOME_PATH);
|
||||
File workDir = new File(mDefaultWorkingDir);
|
||||
if (!workDir.exists() || !workDir.isDirectory()) {
|
||||
// Fallback to home directory if user configured working directory is not exist
|
||||
// or is a regular file.
|
||||
mDefaultWorkingDir = TermuxService.HOME_PATH;
|
||||
mDefaultWorkingDir = TermuxConstants.HOME_PATH;
|
||||
}
|
||||
|
||||
String defaultExtraKeys = "[[ESC, TAB, CTRL, ALT, {key: '-', popup: '|'}, DOWN, UP]]";
|
||||
|
@@ -22,6 +22,8 @@ import android.util.Log;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
|
||||
import com.termux.terminal.EmulatorDebug;
|
||||
import com.termux.terminal.TerminalSession;
|
||||
import com.termux.terminal.TerminalSession.SessionChangedCallback;
|
||||
@@ -45,26 +47,8 @@ import java.util.List;
|
||||
public final class TermuxService extends Service implements SessionChangedCallback {
|
||||
|
||||
private static final String NOTIFICATION_CHANNEL_ID = "termux_notification_channel";
|
||||
|
||||
/** Note that this is a symlink on the Android M preview. */
|
||||
@SuppressLint("SdCardPath")
|
||||
public static final String FILES_PATH = "/data/data/com.termux/files";
|
||||
public static final String PREFIX_PATH = FILES_PATH + "/usr";
|
||||
public static final String HOME_PATH = FILES_PATH + "/home";
|
||||
|
||||
private static final int NOTIFICATION_ID = 1337;
|
||||
|
||||
private static final String ACTION_STOP_SERVICE = "com.termux.service_stop";
|
||||
private static final String ACTION_LOCK_WAKE = "com.termux.service_wake_lock";
|
||||
private static final String ACTION_UNLOCK_WAKE = "com.termux.service_wake_unlock";
|
||||
/** Intent action to launch a new terminal session. Executed from TermuxWidgetProvider. */
|
||||
public static final String ACTION_EXECUTE = "com.termux.service_execute";
|
||||
|
||||
public static final String EXTRA_ARGUMENTS = "com.termux.execute.arguments";
|
||||
|
||||
public static final String EXTRA_CURRENT_WORKING_DIRECTORY = "com.termux.execute.cwd";
|
||||
public static final String EXTRA_EXECUTE_IN_BACKGROUND = "com.termux.execute.background";
|
||||
|
||||
/** This service is only bound from inside the same process and never uses IPC. */
|
||||
class LocalBinder extends Binder {
|
||||
public final TermuxService service = TermuxService.this;
|
||||
@@ -91,19 +75,19 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
private WifiManager.WifiLock mWifiLock;
|
||||
|
||||
/** If the user has executed the {@link #ACTION_STOP_SERVICE} intent. */
|
||||
/** If the user has executed the {@link TermuxConstants.TERMUX_APP.TERMUX_SERVICE#ACTION_STOP_SERVICE} intent. */
|
||||
boolean mWantsToStop = false;
|
||||
|
||||
@SuppressLint("Wakelock")
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
String action = intent.getAction();
|
||||
if (ACTION_STOP_SERVICE.equals(action)) {
|
||||
if (TERMUX_SERVICE.ACTION_STOP_SERVICE.equals(action)) {
|
||||
mWantsToStop = true;
|
||||
for (int i = 0; i < mTerminalSessions.size(); i++)
|
||||
mTerminalSessions.get(i).finishIfRunning();
|
||||
stopSelf();
|
||||
} else if (ACTION_LOCK_WAKE.equals(action)) {
|
||||
} else if (TERMUX_SERVICE.ACTION_WAKE_LOCK.equals(action)) {
|
||||
if (mWakeLock == null) {
|
||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, EmulatorDebug.LOG_TAG + ":service-wakelock");
|
||||
@@ -130,7 +114,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
|
||||
updateNotification();
|
||||
}
|
||||
} else if (ACTION_UNLOCK_WAKE.equals(action)) {
|
||||
} else if (TERMUX_SERVICE.ACTION_WAKE_UNLOCK.equals(action)) {
|
||||
if (mWakeLock != null) {
|
||||
mWakeLock.release();
|
||||
mWakeLock = null;
|
||||
@@ -140,19 +124,19 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
|
||||
updateNotification();
|
||||
}
|
||||
} else if (ACTION_EXECUTE.equals(action)) {
|
||||
} else if (TERMUX_SERVICE.ACTION_SERVICE_EXECUTE.equals(action)) {
|
||||
Uri executableUri = intent.getData();
|
||||
String executablePath = (executableUri == null ? null : executableUri.getPath());
|
||||
|
||||
String[] arguments = (executableUri == null ? null : intent.getStringArrayExtra(EXTRA_ARGUMENTS));
|
||||
String cwd = intent.getStringExtra(EXTRA_CURRENT_WORKING_DIRECTORY);
|
||||
String[] arguments = (executableUri == null ? null : intent.getStringArrayExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS));
|
||||
String cwd = intent.getStringExtra(TERMUX_SERVICE.EXTRA_WORKDIR);
|
||||
|
||||
if (intent.getBooleanExtra(EXTRA_EXECUTE_IN_BACKGROUND, false)) {
|
||||
if (intent.getBooleanExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, false)) {
|
||||
BackgroundJob task = new BackgroundJob(cwd, executablePath, arguments, this, intent.getParcelableExtra("pendingIntent"));
|
||||
mBackgroundTasks.add(task);
|
||||
updateNotification();
|
||||
} else {
|
||||
boolean failsafe = intent.getBooleanExtra(TermuxActivity.TERMUX_FAILSAFE_SESSION_ACTION, false);
|
||||
boolean failsafe = intent.getBooleanExtra(TERMUX_ACTIVITY.ACTION_FAILSAFE_SESSION, false);
|
||||
TerminalSession newSession = createTermSession(executablePath, arguments, cwd, failsafe);
|
||||
|
||||
// Transform executable path to session name, e.g. "/bin/do-something.sh" => "do something.sh".
|
||||
@@ -238,10 +222,10 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
}
|
||||
|
||||
Resources res = getResources();
|
||||
Intent exitIntent = new Intent(this, TermuxService.class).setAction(ACTION_STOP_SERVICE);
|
||||
Intent exitIntent = new Intent(this, TermuxService.class).setAction(TERMUX_SERVICE.ACTION_STOP_SERVICE);
|
||||
builder.addAction(android.R.drawable.ic_delete, res.getString(R.string.notification_action_exit), PendingIntent.getService(this, 0, exitIntent, 0));
|
||||
|
||||
String newWakeAction = wakeLockHeld ? ACTION_UNLOCK_WAKE : ACTION_LOCK_WAKE;
|
||||
String newWakeAction = wakeLockHeld ? TERMUX_SERVICE.ACTION_WAKE_UNLOCK : TERMUX_SERVICE.ACTION_WAKE_LOCK;
|
||||
Intent toggleWakeLockIntent = new Intent(this, TermuxService.class).setAction(newWakeAction);
|
||||
String actionTitle = res.getString(wakeLockHeld ?
|
||||
R.string.notification_action_wake_unlock :
|
||||
@@ -254,7 +238,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
File termuxTmpDir = new File(TermuxService.PREFIX_PATH + "/tmp");
|
||||
File termuxTmpDir = new File(TermuxConstants.PREFIX_PATH + "/tmp");
|
||||
|
||||
if (termuxTmpDir.exists()) {
|
||||
try {
|
||||
@@ -280,9 +264,9 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
}
|
||||
|
||||
TerminalSession createTermSession(String executablePath, String[] arguments, String cwd, boolean failSafe) {
|
||||
new File(HOME_PATH).mkdirs();
|
||||
new File(TermuxConstants.HOME_PATH).mkdirs();
|
||||
|
||||
if (cwd == null || cwd.isEmpty()) cwd = HOME_PATH;
|
||||
if (cwd == null || cwd.isEmpty()) cwd = TermuxConstants.HOME_PATH;
|
||||
|
||||
String[] env = BackgroundJob.buildEnvironment(failSafe, cwd);
|
||||
boolean isLoginShell = false;
|
||||
@@ -290,7 +274,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
if (executablePath == null) {
|
||||
if (!failSafe) {
|
||||
for (String shellBinary : new String[]{"login", "bash", "zsh"}) {
|
||||
File shellFile = new File(PREFIX_PATH + "/bin/" + shellBinary);
|
||||
File shellFile = new File(TermuxConstants.PREFIX_PATH + "/bin/" + shellBinary);
|
||||
if (shellFile.canExecute()) {
|
||||
executablePath = shellFile.getAbsolutePath();
|
||||
break;
|
||||
@@ -320,8 +304,8 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
||||
updateNotification();
|
||||
|
||||
// Make sure that terminal styling is always applied.
|
||||
Intent stylingIntent = new Intent("com.termux.app.reload_style");
|
||||
stylingIntent.putExtra("com.termux.app.reload_style", "styling");
|
||||
Intent stylingIntent = new Intent(TERMUX_ACTIVITY.ACTION_RELOAD_STYLE);
|
||||
stylingIntent.putExtra(TERMUX_ACTIVITY.EXTRA_RELOAD_STYLE, "styling");
|
||||
sendBroadcast(stylingIntent);
|
||||
|
||||
return session;
|
||||
|
@@ -12,7 +12,7 @@ import android.provider.DocumentsProvider;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.TermuxService;
|
||||
import com.termux.app.TermuxConstants;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -35,7 +35,7 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
|
||||
|
||||
private static final String ALL_MIME_TYPES = "*/*";
|
||||
|
||||
private static final File BASE_DIR = new File(TermuxService.HOME_PATH);
|
||||
private static final File BASE_DIR = new File(TermuxConstants.HOME_PATH);
|
||||
|
||||
|
||||
// The default columns to return information about a root if no specific
|
||||
@@ -171,7 +171,7 @@ public class TermuxDocumentsProvider extends DocumentsProvider {
|
||||
// through the whole SD card).
|
||||
boolean isInsideHome;
|
||||
try {
|
||||
isInsideHome = file.getCanonicalPath().startsWith(TermuxService.HOME_PATH);
|
||||
isInsideHome = file.getCanonicalPath().startsWith(TermuxConstants.HOME_PATH);
|
||||
} catch (IOException e) {
|
||||
isInsideHome = true;
|
||||
}
|
||||
|
@@ -11,6 +11,8 @@ import android.util.Patterns;
|
||||
|
||||
import com.termux.R;
|
||||
import com.termux.app.DialogUtils;
|
||||
import com.termux.app.TermuxConstants;
|
||||
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
|
||||
import com.termux.app.TermuxService;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -25,9 +27,9 @@ import java.util.regex.Pattern;
|
||||
|
||||
public class TermuxFileReceiverActivity extends Activity {
|
||||
|
||||
static final String TERMUX_RECEIVEDIR = TermuxService.FILES_PATH + "/home/downloads";
|
||||
static final String EDITOR_PROGRAM = TermuxService.HOME_PATH + "/bin/termux-file-editor";
|
||||
static final String URL_OPENER_PROGRAM = TermuxService.HOME_PATH + "/bin/termux-url-opener";
|
||||
static final String TERMUX_RECEIVEDIR = TermuxConstants.FILES_PATH + "/home/downloads";
|
||||
static final String EDITOR_PROGRAM = TermuxConstants.HOME_PATH + "/bin/termux-file-editor";
|
||||
static final String URL_OPENER_PROGRAM = TermuxConstants.HOME_PATH + "/bin/termux-url-opener";
|
||||
|
||||
/**
|
||||
* If the activity should be finished when the name input dialog is dismissed. This is disabled
|
||||
@@ -131,17 +133,17 @@ public class TermuxFileReceiverActivity extends Activity {
|
||||
|
||||
final Uri scriptUri = new Uri.Builder().scheme("file").path(EDITOR_PROGRAM).build();
|
||||
|
||||
Intent executeIntent = new Intent(TermuxService.ACTION_EXECUTE, scriptUri);
|
||||
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, scriptUri);
|
||||
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class);
|
||||
executeIntent.putExtra(TermuxService.EXTRA_ARGUMENTS, new String[]{outFile.getAbsolutePath()});
|
||||
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{outFile.getAbsolutePath()});
|
||||
startService(executeIntent);
|
||||
finish();
|
||||
},
|
||||
R.string.file_received_open_folder_button, text -> {
|
||||
if (saveStreamWithName(in, text) == null) return;
|
||||
|
||||
Intent executeIntent = new Intent(TermuxService.ACTION_EXECUTE);
|
||||
executeIntent.putExtra(TermuxService.EXTRA_CURRENT_WORKING_DIRECTORY, TERMUX_RECEIVEDIR);
|
||||
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE);
|
||||
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, TERMUX_RECEIVEDIR);
|
||||
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class);
|
||||
startService(executeIntent);
|
||||
finish();
|
||||
@@ -188,9 +190,9 @@ public class TermuxFileReceiverActivity extends Activity {
|
||||
|
||||
final Uri urlOpenerProgramUri = new Uri.Builder().scheme("file").path(URL_OPENER_PROGRAM).build();
|
||||
|
||||
Intent executeIntent = new Intent(TermuxService.ACTION_EXECUTE, urlOpenerProgramUri);
|
||||
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, urlOpenerProgramUri);
|
||||
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class);
|
||||
executeIntent.putExtra(TermuxService.EXTRA_ARGUMENTS, new String[]{url});
|
||||
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{url});
|
||||
startService(executeIntent);
|
||||
finish();
|
||||
}
|
||||
|
@@ -1,9 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!DOCTYPE resources [
|
||||
<!ENTITY TERMUX_PACKAGE_NAME "com.termux">
|
||||
<!ENTITY TERMUX_APP_NAME "Termux">
|
||||
<!ENTITY TERMUX_API_APP_NAME "Termux:API">
|
||||
<!ENTITY TERMUX_BOOT_APP_NAME "Termux:Boot">
|
||||
<!ENTITY TERMUX_FLOAT_APP_NAME "Termux:Float">
|
||||
<!ENTITY TERMUX_STYLING_APP_NAME "Termux:Styling">
|
||||
<!ENTITY TERMUX_TASKER_APP_NAME "Termux:Tasker">
|
||||
<!ENTITY TERMUX_WIDGET_APP_NAME "Termux:Widget">
|
||||
]>
|
||||
|
||||
<resources>
|
||||
<string name="application_name">Termux</string>
|
||||
<string name="shared_user_label">Termux user</string>
|
||||
<string name="run_command_permission_label">Run commands in Termux environment</string>
|
||||
<string name="run_command_permission_description">execute arbitrary commands within Termux environment</string>
|
||||
<string name="application_name">&TERMUX_APP_NAME;</string>
|
||||
<string name="shared_user_label">&TERMUX_APP_NAME; user</string>
|
||||
<string name="run_command_permission_label">Run commands in &TERMUX_APP_NAME; environment</string>
|
||||
<string name="run_command_permission_description">execute arbitrary commands within &TERMUX_APP_NAME; environment</string>
|
||||
<string name="new_session">New session</string>
|
||||
<string name="new_session_failsafe">Failsafe</string>
|
||||
<string name="toggle_soft_keyboard">Keyboard</string>
|
||||
@@ -16,10 +28,10 @@
|
||||
|
||||
<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.</string>
|
||||
<string name="bootstrap_error_body">&TERMUX_APP_NAME; was unable to install the bootstrap packages.</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_error_not_primary_user_message">&TERMUX_APP_NAME; 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>
|
||||
@@ -41,7 +53,7 @@
|
||||
<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_not_installed">The &TERMUX_STYLING_APP_NAME; Plugin App is not installed.</string>
|
||||
<string name="styling_install">Install</string>
|
||||
|
||||
<string name="notification_action_exit">Exit</string>
|
||||
|
@@ -1,6 +1,14 @@
|
||||
<shortcuts xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!--
|
||||
For shortcut.xml:
|
||||
If applicationId in build.gradle is changed from "com.termux", then targetPackage will
|
||||
need to be manually patched since ${applicationId} variable or resource string does not work.
|
||||
If package name in AndroidManifest is changed from "com.termux", then targetClass will
|
||||
need to be manually patched since dot (.) prefix does not work to automatically prefix the
|
||||
package name.
|
||||
-->
|
||||
<shortcut
|
||||
android:shortcutId="new_session"
|
||||
android:enabled="true"
|
||||
|
Reference in New Issue
Block a user