Skip to content

Commit 14c4986

Browse files
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.
1 parent 395759c commit 14c4986

14 files changed

+361
-120
lines changed

app/build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ android {
2121
versionCode 108
2222
versionName "0.108"
2323

24+
manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux"
25+
manifestPlaceholders.TERMUX_APP_NAME = "Termux"
26+
manifestPlaceholders.TERMUX_API_APP_NAME = "Termux:API"
27+
manifestPlaceholders.TERMUX_BOOT_APP_NAME = "Termux:Boot"
28+
manifestPlaceholders.TERMUX_FLOAT_APP_NAME = "Termux:Float"
29+
manifestPlaceholders.TERMUX_STYLING_APP_NAME = "Termux:Styling"
30+
manifestPlaceholders.TERMUX_TASKER_APP_NAME = "Termux:Tasker"
31+
manifestPlaceholders.TERMUX_WIDGET_APP_NAME = "Termux:Widget"
32+
2433
externalNativeBuild {
2534
ndkBuild {
2635
cFlags "-std=c11", "-Wall", "-Wextra", "-Werror", "-Os", "-fno-stack-protector", "-Wl,--gc-sections"

app/src/main/AndroidManifest.xml

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
xmlns:tools="http://schemas.android.com/tools"
33
package="com.termux"
44
android:installLocation="internalOnly"
5-
android:sharedUserId="com.termux"
5+
android:sharedUserId="${TERMUX_PACKAGE_NAME}"
66
android:sharedUserLabel="@string/shared_user_label" >
77

88
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
99
<uses-feature android:name="android.software.leanback" android:required="false" />
1010

11-
<permission android:name="com.termux.permission.RUN_COMMAND"
11+
<permission android:name="${TERMUX_PACKAGE_NAME}.permission.RUN_COMMAND"
1212
android:label="@string/run_command_permission_label"
1313
android:description="@string/run_command_permission_description"
1414
android:icon="@mipmap/ic_launcher"
@@ -28,21 +28,22 @@
2828
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
2929

3030
<application
31-
android:extractNativeLibs="true"
32-
android:allowBackup="false"
31+
android:label="@string/application_name"
3332
android:icon="@mipmap/ic_launcher"
3433
android:roundIcon="@mipmap/ic_launcher_round"
3534
android:banner="@drawable/banner"
36-
android:label="@string/application_name"
3735
android:theme="@style/Theme.Termux"
36+
37+
android:extractNativeLibs="true"
38+
android:allowBackup="false"
3839
android:supportsRtl="false" >
3940

4041
<!-- This (or rather, value 2.1 or higher) is needed to make the Samsung Galaxy S8
4142
mark the app with "This app is optimized to run in full screen." -->
4243
<meta-data android:name="android.max_aspect" android:value="10.0" />
4344

4445
<activity
45-
android:name="com.termux.app.TermuxActivity"
46+
android:name=".app.TermuxActivity"
4647
android:label="@string/application_name"
4748
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation"
4849
android:launchMode="singleTask"
@@ -60,17 +61,17 @@
6061
</activity>
6162

6263
<activity
63-
android:name="com.termux.app.TermuxHelpActivity"
64+
android:name=".app.TermuxHelpActivity"
6465
android:exported="false"
6566
android:theme="@android:style/Theme.Material.Light.DarkActionBar"
6667
android:parentActivityName=".app.TermuxActivity"
6768
android:resizeableActivity="true"
6869
android:label="@string/application_name" />
6970

7071
<activity
71-
android:name="com.termux.filepicker.TermuxFileReceiverActivity"
72+
android:name=".filepicker.TermuxFileReceiverActivity"
7273
android:label="@string/application_name"
73-
android:taskAffinity="com.termux.filereceiver"
74+
android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver"
7475
android:excludeFromRecents="true"
7576
android:resizeableActivity="true"
7677
android:noHistory="true">
@@ -100,7 +101,7 @@
100101

101102
<activity-alias
102103
android:name=".HomeActivity"
103-
android:targetActivity="com.termux.app.TermuxActivity">
104+
android:targetActivity=".app.TermuxActivity">
104105

105106
<!-- Launch activity automatically on boot on Android Things devices -->
106107
<intent-filter>
@@ -112,7 +113,7 @@
112113

113114
<provider
114115
android:name=".filepicker.TermuxDocumentsProvider"
115-
android:authorities="com.termux.documents"
116+
android:authorities="${TERMUX_PACKAGE_NAME}.documents"
116117
android:grantUriPermissions="true"
117118
android:exported="true"
118119
android:permission="android.permission.MANAGE_DOCUMENTS">
@@ -122,25 +123,25 @@
122123
</provider>
123124

124125
<service
125-
android:name="com.termux.app.TermuxService"
126+
android:name=".app.TermuxService"
126127
android:exported="false" />
127128

128129
<service
129130
android:name=".app.RunCommandService"
130131
android:exported="true"
131-
android:permission="com.termux.permission.RUN_COMMAND" >
132+
android:permission="${TERMUX_PACKAGE_NAME}.permission.RUN_COMMAND" >
132133
<intent-filter>
133-
<action android:name="com.termux.RUN_COMMAND" />
134+
<action android:name="${TERMUX_PACKAGE_NAME}.RUN_COMMAND" />
134135
</intent-filter>
135136
</service>
136137

137138
<receiver android:name=".app.TermuxOpenReceiver" />
138139

139-
<provider android:authorities="com.termux.files"
140+
<provider android:authorities="${TERMUX_PACKAGE_NAME}.files"
140141
android:readPermission="android.permission.permRead"
141142
android:exported="true"
142143
android:grantUriPermissions="true"
143-
android:name="com.termux.app.TermuxOpenReceiver$ContentProvider" />
144+
android:name=".app.TermuxOpenReceiver$ContentProvider" />
144145
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
145146
<meta-data android:name="com.samsung.android.multidisplay.keep_process_alive" android:value="true"/>
146147
</application>

app/src/main/java/com/termux/app/BackgroundJob.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public BackgroundJob(String cwd, String fileToExecute, final String[] args, fina
3636

3737
public BackgroundJob(String cwd, String fileToExecute, final String[] args, final TermuxService service, PendingIntent pendingIntent) {
3838
String[] env = buildEnvironment(false, cwd);
39-
if (cwd == null || cwd.isEmpty()) cwd = TermuxService.HOME_PATH;
39+
if (cwd == null || cwd.isEmpty()) cwd = TermuxConstants.HOME_PATH;
4040

4141
final String[] progArray = setupProcessArgs(fileToExecute, args);
4242
final String processDescription = Arrays.toString(progArray);
@@ -134,17 +134,17 @@ private static void addToEnvIfPresent(List<String> environment, String name) {
134134
}
135135

136136
static String[] buildEnvironment(boolean failSafe, String cwd) {
137-
new File(TermuxService.HOME_PATH).mkdirs();
137+
new File(TermuxConstants.HOME_PATH).mkdirs();
138138

139-
if (cwd == null || cwd.isEmpty()) cwd = TermuxService.HOME_PATH;
139+
if (cwd == null || cwd.isEmpty()) cwd = TermuxConstants.HOME_PATH;
140140

141141
List<String> environment = new ArrayList<>();
142142

143143
environment.add("TERMUX_VERSION=" + BuildConfig.VERSION_NAME);
144144
environment.add("TERM=xterm-256color");
145145
environment.add("COLORTERM=truecolor");
146-
environment.add("HOME=" + TermuxService.HOME_PATH);
147-
environment.add("PREFIX=" + TermuxService.PREFIX_PATH);
146+
environment.add("HOME=" + TermuxConstants.HOME_PATH);
147+
environment.add("PREFIX=" + TermuxConstants.PREFIX_PATH);
148148
environment.add("BOOTCLASSPATH=" + System.getenv("BOOTCLASSPATH"));
149149
environment.add("ANDROID_ROOT=" + System.getenv("ANDROID_ROOT"));
150150
environment.add("ANDROID_DATA=" + System.getenv("ANDROID_DATA"));
@@ -164,9 +164,9 @@ static String[] buildEnvironment(boolean failSafe, String cwd) {
164164
environment.add("PATH= " + System.getenv("PATH"));
165165
} else {
166166
environment.add("LANG=en_US.UTF-8");
167-
environment.add("PATH=" + TermuxService.PREFIX_PATH + "/bin");
167+
environment.add("PATH=" + TermuxConstants.PREFIX_PATH + "/bin");
168168
environment.add("PWD=" + cwd);
169-
environment.add("TMPDIR=" + TermuxService.PREFIX_PATH + "/tmp");
169+
environment.add("TMPDIR=" + TermuxConstants.PREFIX_PATH + "/tmp");
170170
}
171171

172172
return environment.toArray(new String[0]);
@@ -215,7 +215,7 @@ static String[] setupProcessArgs(String fileToExecute, String[] args) {
215215
if (executable.startsWith("/usr") || executable.startsWith("/bin")) {
216216
String[] parts = executable.split("/");
217217
String binary = parts[parts.length - 1];
218-
interpreter = TermuxService.PREFIX_PATH + "/bin/" + binary;
218+
interpreter = TermuxConstants.PREFIX_PATH + "/bin/" + binary;
219219
}
220220
break;
221221
}
@@ -225,7 +225,7 @@ static String[] setupProcessArgs(String fileToExecute, String[] args) {
225225
}
226226
} else {
227227
// No shebang and no ELF, use standard shell.
228-
interpreter = TermuxService.PREFIX_PATH + "/bin/sh";
228+
interpreter = TermuxConstants.PREFIX_PATH + "/bin/sh";
229229
}
230230
}
231231
}

app/src/main/java/com/termux/app/RunCommandService.java

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import android.util.Log;
1414

1515
import com.termux.R;
16+
import com.termux.app.TermuxConstants.TERMUX_APP.RUN_COMMAND_SERVICE;
17+
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
1618

1719
import java.io.File;
1820
import java.io.FileInputStream;
@@ -77,12 +79,6 @@
7779
*/
7880
public class RunCommandService extends Service {
7981

80-
public static final String RUN_COMMAND_ACTION = "com.termux.RUN_COMMAND";
81-
public static final String RUN_COMMAND_PATH = "com.termux.RUN_COMMAND_PATH";
82-
public static final String RUN_COMMAND_ARGUMENTS = "com.termux.RUN_COMMAND_ARGUMENTS";
83-
public static final String RUN_COMMAND_WORKDIR = "com.termux.RUN_COMMAND_WORKDIR";
84-
public static final String RUN_COMMAND_BACKGROUND = "com.termux.RUN_COMMAND_BACKGROUND";
85-
8682
private static final String NOTIFICATION_CHANNEL_ID = "termux_run_command_notification_channel";
8783
private static final int NOTIFICATION_ID = 1338;
8884

@@ -108,7 +104,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
108104
runStartForeground();
109105

110106
// If wrong action passed, then just return
111-
if (!RUN_COMMAND_ACTION.equals(intent.getAction())) {
107+
if (!RUN_COMMAND_SERVICE.ACTION_RUN_COMMAND.equals(intent.getAction())) {
112108
Log.e("termux", "Unexpected intent action to RunCommandService: " + intent.getAction());
113109
return Service.START_NOT_STICKY;
114110
}
@@ -119,16 +115,16 @@ public int onStartCommand(Intent intent, int flags, int startId) {
119115
return Service.START_NOT_STICKY;
120116
}
121117

122-
Uri programUri = new Uri.Builder().scheme("com.termux.file").path(getExpandedTermuxPath(intent.getStringExtra(RUN_COMMAND_PATH))).build();
118+
Uri programUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(getExpandedTermuxPath(intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_COMMAND_PATH))).build();
123119

124-
Intent execIntent = new Intent(TermuxService.ACTION_EXECUTE, programUri);
120+
Intent execIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, programUri);
125121
execIntent.setClass(this, TermuxService.class);
126-
execIntent.putExtra(TermuxService.EXTRA_ARGUMENTS, intent.getStringArrayExtra(RUN_COMMAND_ARGUMENTS));
127-
execIntent.putExtra(TermuxService.EXTRA_EXECUTE_IN_BACKGROUND, intent.getBooleanExtra(RUN_COMMAND_BACKGROUND, false));
122+
execIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, intent.getStringArrayExtra(RUN_COMMAND_SERVICE.EXTRA_ARGUMENTS));
123+
execIntent.putExtra(TERMUX_SERVICE.EXTRA_BACKGROUND, intent.getBooleanExtra(RUN_COMMAND_SERVICE.EXTRA_BACKGROUND, false));
128124

129-
String workingDirectory = intent.getStringExtra(RUN_COMMAND_WORKDIR);
125+
String workingDirectory = intent.getStringExtra(RUN_COMMAND_SERVICE.EXTRA_WORKDIR);
130126
if (workingDirectory != null && !workingDirectory.isEmpty()) {
131-
execIntent.putExtra(TermuxService.EXTRA_CURRENT_WORKING_DIRECTORY, getExpandedTermuxPath(workingDirectory));
127+
execIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, getExpandedTermuxPath(workingDirectory));
132128
}
133129

134130
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -188,9 +184,9 @@ private void setupNotificationChannel() {
188184
}
189185

190186
private boolean allowExternalApps() {
191-
File propsFile = new File(TermuxService.HOME_PATH + "/.termux/termux.properties");
187+
File propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_PRIMARY_PATH);
192188
if (!propsFile.exists())
193-
propsFile = new File(TermuxService.HOME_PATH + "/.config/termux/termux.properties");
189+
propsFile = new File(TermuxConstants.TERMUX_PROPERTIES_SECONDARY_PATH);
194190

195191
Properties props = new Properties();
196192
try {
@@ -209,10 +205,10 @@ private boolean allowExternalApps() {
209205
/** Replace "$PREFIX/" or "~/" prefix with termux absolute paths */
210206
public static String getExpandedTermuxPath(String path) {
211207
if(path != null && !path.isEmpty()) {
212-
path = path.replaceAll("^\\$PREFIX$", TermuxService.PREFIX_PATH);
213-
path = path.replaceAll("^\\$PREFIX/", TermuxService.PREFIX_PATH + "/");
214-
path = path.replaceAll("^~/$", TermuxService.HOME_PATH);
215-
path = path.replaceAll("^~/", TermuxService.HOME_PATH + "/");
208+
path = path.replaceAll("^\\$PREFIX$", TermuxConstants.PREFIX_PATH);
209+
path = path.replaceAll("^\\$PREFIX/", TermuxConstants.PREFIX_PATH + "/");
210+
path = path.replaceAll("^~/$", TermuxConstants.HOME_PATH);
211+
path = path.replaceAll("^~/", TermuxConstants.HOME_PATH + "/");
216212
}
217213

218214
return path;

app/src/main/java/com/termux/app/TermuxActivity.java

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import android.Manifest;
44
import android.annotation.SuppressLint;
5-
import android.annotation.TargetApi;
65
import android.app.Activity;
76
import android.app.AlertDialog;
87
import android.content.ActivityNotFoundException;
@@ -48,6 +47,7 @@
4847
import android.widget.Toast;
4948

5049
import com.termux.R;
50+
import com.termux.app.TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY;
5151
import com.termux.terminal.EmulatorDebug;
5252
import com.termux.terminal.TerminalColors;
5353
import com.termux.terminal.TerminalSession;
@@ -84,8 +84,6 @@
8484
*/
8585
public final class TermuxActivity extends Activity implements ServiceConnection {
8686

87-
public static final String TERMUX_FAILSAFE_SESSION_ACTION = "com.termux.app.failsafe_session";
88-
8987
private static final int CONTEXTMENU_SELECT_URL_ID = 0;
9088
private static final int CONTEXTMENU_SHARE_TRANSCRIPT_ID = 1;
9189
private static final int CONTEXTMENU_PASTE_ID = 3;
@@ -100,9 +98,8 @@ public final class TermuxActivity extends Activity implements ServiceConnection
10098

10199
private static final int REQUESTCODE_PERMISSION_STORAGE = 1234;
102100

103-
private static final String RELOAD_STYLE_ACTION = "com.termux.app.reload_style";
104101

105-
private static final String BROADCAST_TERMUX_OPENED = "com.termux.app.OPENED";
102+
private static final String BROADCAST_TERMUX_OPENED = TermuxConstants.TERMUX_PACKAGE_NAME + ".app.OPENED";
106103

107104
/** The main view of the activity showing the terminal. Initialized in onCreate(). */
108105
@SuppressWarnings("NullableProblems")
@@ -145,7 +142,7 @@ public final class TermuxActivity extends Activity implements ServiceConnection
145142
@Override
146143
public void onReceive(Context context, Intent intent) {
147144
if (mIsVisible) {
148-
String whatToReload = intent.getStringExtra(RELOAD_STYLE_ACTION);
145+
String whatToReload = intent.getStringExtra(TERMUX_ACTIVITY.EXTRA_RELOAD_STYLE);
149146
if ("storage".equals(whatToReload)) {
150147
if (ensureStoragePermissionGranted())
151148
TermuxInstaller.setupStorageSymlinks(TermuxActivity.this);
@@ -163,8 +160,8 @@ public void onReceive(Context context, Intent intent) {
163160

164161
void checkForFontAndColors() {
165162
try {
166-
@SuppressLint("SdCardPath") File fontFile = new File("/data/data/com.termux/files/home/.termux/font.ttf");
167-
@SuppressLint("SdCardPath") File colorsFile = new File("/data/data/com.termux/files/home/.termux/colors.properties");
163+
File colorsFile = new File(TermuxConstants.COLOR_PROPERTIES_PATH);
164+
File fontFile = new File(TermuxConstants.FONT_PATH);
168165

169166
final Properties props = new Properties();
170167
if (colorsFile.isFile()) {
@@ -541,7 +538,7 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
541538
Bundle bundle = getIntent().getExtras();
542539
boolean launchFailsafe = false;
543540
if (bundle != null) {
544-
launchFailsafe = bundle.getBoolean(TERMUX_FAILSAFE_SESSION_ACTION, false);
541+
launchFailsafe = bundle.getBoolean(TERMUX_ACTIVITY.ACTION_FAILSAFE_SESSION, false);
545542
}
546543
addNewSession(launchFailsafe, null);
547544
} catch (WindowManager.BadTokenException e) {
@@ -556,7 +553,7 @@ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
556553
Intent i = getIntent();
557554
if (i != null && Intent.ACTION_RUN.equals(i.getAction())) {
558555
// Android 7.1 app shortcut from res/xml/shortcuts.xml.
559-
boolean failSafe = i.getBooleanExtra(TERMUX_FAILSAFE_SESSION_ACTION, false);
556+
boolean failSafe = i.getBooleanExtra(TERMUX_ACTIVITY.ACTION_FAILSAFE_SESSION, false);
560557
addNewSession(failSafe, null);
561558
} else {
562559
switchToSession(getStoredCurrentSessionOrLast());
@@ -612,7 +609,7 @@ public void onStart() {
612609
mListViewAdapter.notifyDataSetChanged();
613610
}
614611

615-
registerReceiver(mBroadcastReceiever, new IntentFilter(RELOAD_STYLE_ACTION));
612+
registerReceiver(mBroadcastReceiever, new IntentFilter(TERMUX_ACTIVITY.ACTION_RELOAD_STYLE));
616613

617614
// The current terminal session may have changed while being away, force
618615
// a refresh of the displayed terminal:
@@ -914,14 +911,14 @@ public boolean onContextItemSelected(MenuItem item) {
914911
}
915912
case CONTEXTMENU_STYLING_ID: {
916913
Intent stylingIntent = new Intent();
917-
stylingIntent.setClassName("com.termux.styling", "com.termux.styling.TermuxStyleActivity");
914+
stylingIntent.setClassName(TermuxConstants.TERMUX_STYLING_PACKAGE_NAME, TermuxConstants.TERMUX_STYLING.TERMUX_STYLING_ACTIVITY_NAME);
918915
try {
919916
startActivity(stylingIntent);
920917
} catch (ActivityNotFoundException | IllegalArgumentException e) {
921918
// The startActivity() call is not documented to throw IllegalArgumentException.
922919
// However, crash reporting shows that it sometimes does, so catch it here.
923-
new AlertDialog.Builder(this).setMessage(R.string.styling_not_installed)
924-
.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();
920+
new AlertDialog.Builder(this).setMessage(getString(R.string.styling_not_installed))
921+
.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();
925922
}
926923
return true;
927924
}

0 commit comments

Comments
 (0)