Skip to content

Commit 32f344e

Browse files
Changed: Use termux-shared
- All hardcoded `com.termux` constants have been removed and will be handled by `TermuxConstants` and `TermuxPreferenceConstants`. - Removed `token.xml` `SharedPreferences` management and use the one in `termux-shared` provided by `TermuxWidgetAppSharedPreferences`. This will invalidate all previous user shortcuts and they will have to created again. This is necessary due to various reasons including design changes added in this commit and for usage of android's internal `ShortcutManager` APIs to create pinned shortcut to be added later. - Use action constants defined in `TermuxConstants` for `TermuxWidgetProvider`. - Remove duplicated code and handle sending execution intent in the single function `TermuxWidgetProvider.sendExecutionIntentToTermuxService()` which will also do proper validation of termux app access and shortcut file. - Implement logging system based on `Logger` class. Log levels can be changed in `termux-app` settings. - Added crash handler so that crash notifications can be shown in `termux-app` at startup. - Update naming convention of resources.
1 parent 135742b commit 32f344e

12 files changed

Lines changed: 268 additions & 154 deletions

app/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ android {
88
targetSdkVersion project.properties.targetSdkVersion.toInteger()
99
versionCode 12
1010
versionName "0.12"
11+
12+
manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux"
13+
manifestPlaceholders.TERMUX_APP_NAME = "Termux"
14+
manifestPlaceholders.TERMUX_WIDGET_APP_NAME = "Termux:Widget"
1115
}
1216

1317
signingConfigs {
@@ -56,4 +60,10 @@ dependencies {
5660
// required for TermuxWidgetControlsProviderService
5761
implementation "org.reactivestreams:reactive-streams:1.0.3"
5862
implementation 'io.reactivex.rxjava2:rxjava:2.2.10'
63+
64+
implementation 'com.termux.termux-app:termux-shared:23b707a819'
65+
66+
// Use if below libraries are published locally by termux-app with `./gradlew publishReleasePublicationToMavenLocal` and used with `mavenLocal()`.
67+
// If updates are done, republish there and sync project with gradle files here
68+
//implementation 'com.termux:termux-shared:0.117'
5969
}

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:tools="http://schemas.android.com/tools"
44
package="com.termux.widget"
5-
android:sharedUserId="com.termux">
5+
android:sharedUserId="${TERMUX_PACKAGE_NAME}">
66

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

1111
<application
12+
android:name=".TermuxWidgetApplication"
1213
android:allowBackup="false"
1314
android:icon="@drawable/ic_launcher"
1415
android:label="@string/app_name"
1516
android:theme="@android:style/Theme.Material.Light.DarkActionBar"
1617
tools:ignore="GoogleAppIndexingWarning">
1718
<receiver
1819
android:name=".TermuxWidgetProvider"
19-
android:label="@string/shortcut_widget_name" >
20+
android:label="@string/title_shortcut_widget_name" >
2021
<intent-filter>
2122
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
2223
</intent-filter>
@@ -28,7 +29,7 @@
2829

2930
<activity
3031
android:name=".TermuxCreateShortcutActivity"
31-
android:label="@string/single_shortcut_name">
32+
android:label="@string/title_single_shortcut_name">
3233
<intent-filter>
3334
<action android:name="android.intent.action.CREATE_SHORTCUT" />
3435
<category android:name="android.intent.category.DEFAULT" />
@@ -47,7 +48,7 @@
4748

4849
<service
4950
android:name=".TermuxWidgetControlsProviderService"
50-
android:label="@string/termux_shortcuts"
51+
android:label="@string/title_termux_shortcuts"
5152
android:permission="android.permission.BIND_CONTROLS">
5253
<intent-filter>
5354
<action android:name="android.service.controls.ControlsProviderService" />

app/src/main/java/com/termux/widget/TermuxCreateShortcutActivity.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
import android.widget.ArrayAdapter;
1313
import android.widget.ListView;
1414

15+
import com.termux.shared.settings.preferences.TermuxWidgetAppSharedPreferences;
16+
import com.termux.shared.termux.TermuxConstants;
17+
import com.termux.shared.termux.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
18+
import com.termux.shared.termux.TermuxConstants.TERMUX_WIDGET;
19+
1520
import java.io.File;
1621
import java.util.Arrays;
1722

@@ -32,7 +37,7 @@ protected void onCreate(Bundle savedInstanceState) {
3237
protected void onResume() {
3338
super.onResume();
3439

35-
updateListview(TermuxWidgetService.SHORTCUTS_DIR);
40+
updateListview(TermuxConstants.TERMUX_SHORTCUT_SCRIPTS_DIR);
3641

3742
mListView.setOnItemClickListener((parent, view, position, id) -> {
3843
final Context context = TermuxCreateShortcutActivity.this;
@@ -44,17 +49,17 @@ protected void onResume() {
4449

4550
Intent.ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(context, R.drawable.ic_launcher);
4651

47-
Uri scriptUri = new Uri.Builder().scheme("com.termux.file").path(clickedFile.getAbsolutePath()).build();
52+
Uri scriptUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(clickedFile.getAbsolutePath()).build();
4853
Intent executeIntent = new Intent(context, TermuxLaunchShortcutActivity.class);
4954
executeIntent.setData(scriptUri);
50-
executeIntent.putExtra(TermuxLaunchShortcutActivity.TOKEN_NAME, TermuxLaunchShortcutActivity.getGeneratedToken(context));
55+
executeIntent.putExtra(TERMUX_WIDGET.EXTRA_TOKEN_NAME, TermuxWidgetAppSharedPreferences.getGeneratedToken(context));
5156

5257
Intent intent = new Intent();
5358
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, executeIntent);
5459
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, clickedFile.getName());
5560

56-
File scriptIcon = new File(TermuxWidgetService.SHORTCUTS_DIR_PATH + "/" +
57-
TermuxWidgetService.SHORTCUT_ICONS_DIR_BASENAME + "/" + clickedFile.getName() + ".png");
61+
File scriptIcon = new File(TermuxConstants.TERMUX_SHORTCUT_SCRIPT_ICONS_DIR_PATH +
62+
"/" + clickedFile.getName() + ".png");
5863
if (scriptIcon.exists()) {
5964
BitmapDrawable bitmapDrawable = (BitmapDrawable)Drawable.createFromPath(scriptIcon.getAbsolutePath());
6065
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmapDrawable.getBitmap());
@@ -75,14 +80,14 @@ private void updateListview(File directory) {
7580

7681
Arrays.sort(mCurrentFiles, (f1, f2) -> f1.getName().compareTo(f2.getName()));
7782

78-
final boolean isTopDir = directory.equals(TermuxWidgetService.SHORTCUTS_DIR);
83+
final boolean isTopDir = directory.equals(TermuxConstants.TERMUX_SHORTCUT_SCRIPTS_DIR);
7984
getActionBar().setDisplayHomeAsUpEnabled(!isTopDir);
8085

8186
if (isTopDir && mCurrentFiles.length == 0) {
8287
// Create if necessary so user can more easily add.
83-
TermuxWidgetService.SHORTCUTS_DIR.mkdirs();
88+
TermuxConstants.TERMUX_SHORTCUT_SCRIPTS_DIR.mkdirs();
8489
new AlertDialog.Builder(this)
85-
.setMessage(R.string.no_shortcut_scripts)
90+
.setMessage(R.string.msg_no_shortcut_scripts)
8691
.setOnDismissListener(dialog -> finish()).show();
8792
return;
8893
}
@@ -104,4 +109,5 @@ public boolean onOptionsItemSelected(MenuItem item) {
104109
}
105110
return super.onOptionsItemSelected(item);
106111
}
112+
107113
}
Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,24 @@
11
package com.termux.widget;
22

33
import android.app.Activity;
4-
import android.content.Context;
5-
import android.content.Intent;
6-
import android.content.SharedPreferences;
7-
import android.net.Uri;
8-
import android.util.Log;
9-
import android.view.Gravity;
10-
import android.widget.Toast;
11-
12-
import java.io.File;
13-
import java.util.UUID;
144

155
/**
166
* An activity to launch a shortcut. We want to a launch a service directly, but a shortcut
177
* cannot be used to launch a service, only activities, so have to go through this activity.
188
*/
199
public class TermuxLaunchShortcutActivity extends Activity {
2010

21-
static final String TOKEN_NAME = "com.termux.shortcut.token";
22-
23-
public static String getGeneratedToken(Context context) {
24-
SharedPreferences prefs = context.getSharedPreferences("token", Context.MODE_PRIVATE);
25-
String token = prefs.getString("token", null);
26-
if (token == null) {
27-
token = UUID.randomUUID().toString();
28-
prefs.edit().putString("token", token).apply();
29-
}
30-
return token;
31-
}
11+
private static final String LOG_TAG = "TermuxLaunchShortcutActivity";
3212

3313
@Override
3414
protected void onResume() {
3515
super.onResume();
3616

37-
Intent intent = getIntent();
38-
String token = intent.getStringExtra(TOKEN_NAME);
39-
if (token == null || !token.equals(getGeneratedToken(this))) {
40-
Log.w("termux", "Strange token: " + token);
41-
Toast.makeText(this, R.string.bad_token_message, Toast.LENGTH_LONG).show();
42-
finish();
43-
return;
44-
}
45-
TermuxWidgetProvider.handleTermuxShortcutExecuteIntent(this, intent);
17+
// Set log level for the app
18+
TermuxWidgetApplication.setLogLevel(this, true);
19+
20+
TermuxWidgetProvider.handleTermuxShortcutExecutionIntent(this, getIntent(), LOG_TAG);
4621
finish();
4722
}
23+
4824
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.termux.widget;
2+
3+
import android.app.Application;
4+
import android.content.Context;
5+
6+
import com.termux.shared.crash.TermuxCrashUtils;
7+
import com.termux.shared.logger.Logger;
8+
import com.termux.shared.settings.preferences.TermuxWidgetAppSharedPreferences;
9+
10+
11+
public class TermuxWidgetApplication extends Application {
12+
13+
public void onCreate() {
14+
super.onCreate();
15+
16+
// Set crash handler for the app
17+
TermuxCrashUtils.setCrashHandler(this);
18+
19+
// Set log level for the app
20+
setLogLevel(getApplicationContext(), true);
21+
22+
Logger.logDebug("Starting Application");
23+
}
24+
25+
public static void setLogLevel(Context context, boolean commitToFile) {
26+
// Load the log level from shared preferences and set it to the {@link Logger.CURRENT_LOG_LEVEL}
27+
TermuxWidgetAppSharedPreferences preferences = TermuxWidgetAppSharedPreferences.build(context);
28+
if (preferences == null) return;
29+
preferences.setLogLevel(null, preferences.getLogLevel(true), commitToFile);
30+
}
31+
32+
}

app/src/main/java/com/termux/widget/TermuxWidgetControlExecutorReceiver.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@
33
import android.content.BroadcastReceiver;
44
import android.content.Context;
55
import android.content.Intent;
6-
import android.util.Log;
7-
import android.widget.Toast;
8-
9-
import static com.termux.widget.TermuxLaunchShortcutActivity.TOKEN_NAME;
10-
import static com.termux.widget.TermuxLaunchShortcutActivity.getGeneratedToken;
116

127
public class TermuxWidgetControlExecutorReceiver extends BroadcastReceiver {
138

9+
private static final String LOG_TAG = "TermuxWidgetControlExecutorReceiver";
10+
1411
@Override
1512
public void onReceive(Context context, Intent intent) {
16-
String token = intent.getStringExtra(TOKEN_NAME);
17-
if (token == null || !token.equals(getGeneratedToken(context))) {
18-
Log.w("termux", "Strange token: " + token);
19-
Toast.makeText(context, R.string.bad_token_message, Toast.LENGTH_LONG).show();
20-
return;
21-
}
22-
TermuxWidgetProvider.handleTermuxShortcutExecuteIntent(context, intent);
13+
// Set log level for the receiver
14+
TermuxWidgetApplication.setLogLevel(context, true);
15+
16+
TermuxWidgetProvider.handleTermuxShortcutExecutionIntent(context, intent, LOG_TAG);
2317
}
18+
2419
}

app/src/main/java/com/termux/widget/TermuxWidgetControlsProviderService.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
import android.service.controls.templates.ControlTemplate;
1515
import android.service.controls.templates.StatelessTemplate;
1616

17+
import com.termux.shared.settings.preferences.TermuxWidgetAppSharedPreferences;
18+
import com.termux.shared.termux.TermuxConstants;
19+
import com.termux.shared.termux.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
20+
import com.termux.shared.termux.TermuxConstants.TERMUX_WIDGET;
21+
1722
import org.reactivestreams.FlowAdapters;
1823

1924
import java.io.File;
@@ -26,8 +31,6 @@
2631
import io.reactivex.Flowable;
2732
import io.reactivex.processors.ReplayProcessor;
2833

29-
import static com.termux.widget.TermuxLaunchShortcutActivity.TOKEN_NAME;
30-
3134
/**
3235
* ControlProviderService for Android 11+ Device Control which allows running
3336
* Termux Widget shortcuts from device Power Menu.
@@ -36,6 +39,7 @@
3639
*/
3740
@TargetApi(Build.VERSION_CODES.R)
3841
public class TermuxWidgetControlsProviderService extends ControlsProviderService {
42+
3943
private static final int WIDGET_REQUEST_CODE = 2233;
4044
private static final String STATELESS_TEMPLATE_ID = "2";
4145

@@ -206,10 +210,9 @@ private PendingIntent createPendingIntentForShortcutFile(File file) {
206210
}
207211

208212
private void addShortcutFileExtrasToIntent(File file, Intent intent) {
209-
String token = TermuxLaunchShortcutActivity.getGeneratedToken(getBaseContext());
210-
intent.putExtra(TOKEN_NAME, token);
213+
intent.putExtra(TERMUX_WIDGET.EXTRA_TOKEN_NAME, TermuxWidgetAppSharedPreferences.getGeneratedToken(getBaseContext()));
211214

212-
Uri scriptUri = new Uri.Builder().scheme("com.termux.file").path(file.getAbsolutePath()).build();
215+
Uri scriptUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(file.getAbsolutePath()).build();
213216
intent.setData(scriptUri);
214217
}
215218

@@ -220,11 +223,11 @@ private Intent createBroadcastIntentForShortcutFile(File file) {
220223
}
221224

222225
/**
223-
* Recursively finds shortcut files starting from {@link TermuxWidgetService#SHORTCUTS_DIR}
226+
* Recursively finds shortcut files starting from {@link TermuxConstants#TERMUX_SHORTCUT_SCRIPTS_DIR}
224227
* @return List<File>
225228
*/
226229
private List<File> createShortcutFilesList() {
227-
File shortcutDir = TermuxWidgetService.SHORTCUTS_DIR;
230+
File shortcutDir = TermuxConstants.TERMUX_SHORTCUT_SCRIPTS_DIR;
228231

229232
List<File> shortcutFiles = new ArrayList<>();
230233
addShortcutFile(shortcutDir, shortcutFiles, 0);
@@ -259,4 +262,5 @@ private void addShortcutFile(File dir, List<File> shortcutFiles, int depth) {
259262
}
260263
}
261264
}
265+
262266
}

0 commit comments

Comments
 (0)