Skip to content

Commit

Permalink
Define TermuxConstants class to store all shared constants of Termu…
Browse files Browse the repository at this point in the history
…x 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.
  • Loading branch information
agnostic-apollo committed Mar 8, 2021
1 parent 395759c commit 14c4986
Show file tree
Hide file tree
Showing 14 changed files with 361 additions and 120 deletions.
9 changes: 9 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
33 changes: 17 additions & 16 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -28,21 +28,22 @@
<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
mark the app with "This app is optimized to run in full screen." -->
<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"
Expand All @@ -60,17 +61,17 @@
</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"
android:resizeableActivity="true"
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">
Expand Down Expand Up @@ -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>
Expand All @@ -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">
Expand All @@ -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>
Expand Down
18 changes: 9 additions & 9 deletions app/src/main/java/com/termux/app/BackgroundJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public BackgroundJob(String cwd, String fileToExecute, final String[] args, fina

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);
Expand Down Expand Up @@ -134,17 +134,17 @@ private static void addToEnvIfPresent(List<String> environment, String name) {
}

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"));
Expand All @@ -164,9 +164,9 @@ static String[] buildEnvironment(boolean failSafe, String cwd) {
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]);
Expand Down Expand Up @@ -215,7 +215,7 @@ static String[] setupProcessArgs(String fileToExecute, String[] args) {
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;
}
Expand All @@ -225,7 +225,7 @@ static String[] setupProcessArgs(String fileToExecute, String[] args) {
}
} else {
// No shebang and no ELF, use standard shell.
interpreter = TermuxService.PREFIX_PATH + "/bin/sh";
interpreter = TermuxConstants.PREFIX_PATH + "/bin/sh";
}
}
}
Expand Down
34 changes: 15 additions & 19 deletions app/src/main/java/com/termux/app/RunCommandService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
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;
Expand Down Expand Up @@ -77,12 +79,6 @@
*/
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;

Expand All @@ -108,7 +104,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
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;
}
Expand All @@ -119,16 +115,16 @@ public int onStartCommand(Intent intent, int flags, int startId) {
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) {
Expand Down Expand Up @@ -188,9 +184,9 @@ private void setupNotificationChannel() {
}

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 {
Expand All @@ -209,10 +205,10 @@ private boolean allowExternalApps() {
/** 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;
Expand Down
25 changes: 11 additions & 14 deletions app/src/main/java/com/termux/app/TermuxActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
Expand Down Expand Up @@ -48,6 +47,7 @@
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;
Expand Down Expand Up @@ -84,8 +84,6 @@
*/
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;
Expand All @@ -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")
Expand Down Expand Up @@ -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);
Expand All @@ -163,8 +160,8 @@ public void onReceive(Context context, Intent intent) {

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()) {
Expand Down Expand Up @@ -541,7 +538,7 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
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) {
Expand All @@ -556,7 +553,7 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
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());
Expand Down Expand Up @@ -612,7 +609,7 @@ public void onStart() {
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:
Expand Down Expand Up @@ -914,14 +911,14 @@ public boolean onContextItemSelected(MenuItem item) {
}
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;
}
Expand Down
Loading

0 comments on commit 14c4986

Please sign in to comment.