Added: Allow users to disable termux file view and share receivers

The user can add `disable-file-share-receiver=true` entry to `termux.properties` file to disable termux from showing in Android file `Share With` apps list.
The user can add `disable-file-view-receiver=true` entry to `termux.properties` file to disable termux from showing in Android file `Open With` apps list.

The default value is `false`. Restarting termux app or running `termux-reload-settings` command will update the behaviour instantaneously if changed.

Closes #2549
This commit is contained in:
agnostic-apollo
2022-06-14 03:56:00 +05:00
parent 79d799a99d
commit af6ac30bb1
7 changed files with 109 additions and 17 deletions

View File

@@ -109,14 +109,19 @@
android:documentLaunchMode="intoExisting" /> android:documentLaunchMode="intoExisting" />
<activity <activity
android:name=".filepicker.TermuxFileReceiverActivity" android:name=".app.api.file.FileReceiverActivity"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:exported="true" android:exported="false"
android:label="@string/application_name"
android:noHistory="true" android:noHistory="true"
android:resizeableActivity="true" android:resizeableActivity="true"
android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver" android:taskAffinity="${TERMUX_PACKAGE_NAME}.filereceiver"
tools:targetApi="n"> tools:targetApi="n">
</activity>
<activity-alias
android:name=".app.api.file.FileShareReceiverActivity"
android:exported="true"
android:targetActivity=".app.api.file.FileReceiverActivity">
<!-- Accept multiple file types when sending. --> <!-- Accept multiple file types when sending. -->
<intent-filter> <intent-filter>
@@ -132,6 +137,13 @@
<data android:mimeType="text/*" /> <data android:mimeType="text/*" />
<data android:mimeType="video/*" /> <data android:mimeType="video/*" />
</intent-filter> </intent-filter>
</activity-alias>
<activity-alias
android:name=".app.api.file.FileViewReceiverActivity"
android:exported="true"
android:targetActivity=".app.api.file.FileReceiverActivity">
<!-- Accept multiple file types to let Termux be usable as generic file viewer. --> <!-- Accept multiple file types to let Termux be usable as generic file viewer. -->
<intent-filter tools:ignore="AppLinkUrlError"> <intent-filter tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
@@ -144,8 +156,7 @@
<data android:mimeType="text/*" /> <data android:mimeType="text/*" />
<data android:mimeType="video/*" /> <data android:mimeType="video/*" />
</intent-filter> </intent-filter>
</activity> </activity-alias>
<provider <provider
android:name=".filepicker.TermuxDocumentsProvider" android:name=".filepicker.TermuxDocumentsProvider"

View File

@@ -29,6 +29,7 @@ import android.widget.RelativeLayout;
import android.widget.Toast; import android.widget.Toast;
import com.termux.R; import com.termux.R;
import com.termux.app.api.file.FileReceiverActivity;
import com.termux.app.terminal.TermuxActivityRootView; import com.termux.app.terminal.TermuxActivityRootView;
import com.termux.app.terminal.TermuxTerminalSessionActivityClient; import com.termux.app.terminal.TermuxTerminalSessionActivityClient;
import com.termux.app.terminal.io.TermuxTerminalExtraKeys; import com.termux.app.terminal.io.TermuxTerminalExtraKeys;
@@ -251,6 +252,8 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
registerForContextMenu(mTerminalView); registerForContextMenu(mTerminalView);
FileReceiverActivity.updateFileReceiverActivityComponentsState(this);
try { try {
// Start the {@link TermuxService} and make it run regardless of who is bound to it // Start the {@link TermuxService} and make it run regardless of who is bound to it
Intent serviceIntent = new Intent(this, TermuxService.class); Intent serviceIntent = new Intent(this, TermuxService.class);
@@ -974,6 +977,8 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
setMargins(); setMargins();
setTerminalToolbarHeight(); setTerminalToolbarHeight();
FileReceiverActivity.updateFileReceiverActivityComponentsState(this);
if (mTermuxTerminalSessionActivityClient != null) if (mTermuxTerminalSessionActivityClient != null)
mTermuxTerminalSessionActivityClient.onReloadActivityStyling(); mTermuxTerminalSessionActivityClient.onReloadActivityStyling();

View File

@@ -1,5 +1,6 @@
package com.termux.filepicker; package com.termux.app.api.file;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
@@ -10,6 +11,7 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.termux.R; import com.termux.R;
import com.termux.shared.android.PackageUtils;
import com.termux.shared.data.DataUtils; import com.termux.shared.data.DataUtils;
import com.termux.shared.data.IntentUtils; import com.termux.shared.data.IntentUtils;
import com.termux.shared.net.uri.UriUtils; import com.termux.shared.net.uri.UriUtils;
@@ -17,9 +19,12 @@ import com.termux.shared.interact.MessageDialogUtils;
import com.termux.shared.net.uri.UriScheme; import com.termux.shared.net.uri.UriScheme;
import com.termux.shared.termux.interact.TextInputDialogUtils; import com.termux.shared.termux.interact.TextInputDialogUtils;
import com.termux.shared.termux.TermuxConstants; import com.termux.shared.termux.TermuxConstants;
import com.termux.shared.termux.TermuxConstants.TERMUX_APP;
import com.termux.shared.termux.TermuxConstants.TERMUX_APP.TERMUX_SERVICE; import com.termux.shared.termux.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
import com.termux.app.TermuxService; import com.termux.app.TermuxService;
import com.termux.shared.logger.Logger; import com.termux.shared.logger.Logger;
import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties;
import com.termux.shared.termux.settings.properties.TermuxPropertyConstants;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
@@ -31,7 +36,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class TermuxFileReceiverActivity extends AppCompatActivity { public class FileReceiverActivity extends AppCompatActivity {
static final String TERMUX_RECEIVEDIR = TermuxConstants.TERMUX_FILES_DIR_PATH + "/home/downloads"; static final String TERMUX_RECEIVEDIR = TermuxConstants.TERMUX_FILES_DIR_PATH + "/home/downloads";
static final String EDITOR_PROGRAM = TermuxConstants.TERMUX_HOME_DIR_PATH + "/bin/termux-file-editor"; static final String EDITOR_PROGRAM = TermuxConstants.TERMUX_HOME_DIR_PATH + "/bin/termux-file-editor";
@@ -47,7 +52,7 @@ public class TermuxFileReceiverActivity extends AppCompatActivity {
private static final String API_TAG = TermuxConstants.TERMUX_APP_NAME + "FileReceiver"; private static final String API_TAG = TermuxConstants.TERMUX_APP_NAME + "FileReceiver";
private static final String LOG_TAG = "TermuxFileReceiverActivity"; private static final String LOG_TAG = "FileReceiverActivity";
static boolean isSharedTextAnUrl(String sharedText) { static boolean isSharedTextAnUrl(String sharedText) {
return Patterns.WEB_URL.matcher(sharedText).matches() return Patterns.WEB_URL.matcher(sharedText).matches()
@@ -172,7 +177,7 @@ public class TermuxFileReceiverActivity extends AppCompatActivity {
final Uri scriptUri = UriUtils.getFileUri(EDITOR_PROGRAM); final Uri scriptUri = UriUtils.getFileUri(EDITOR_PROGRAM);
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, scriptUri); Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, scriptUri);
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class); executeIntent.setClass(FileReceiverActivity.this, TermuxService.class);
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{outFile.getAbsolutePath()}); executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{outFile.getAbsolutePath()});
startService(executeIntent); startService(executeIntent);
finish(); finish();
@@ -182,7 +187,7 @@ public class TermuxFileReceiverActivity extends AppCompatActivity {
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE); Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE);
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, TERMUX_RECEIVEDIR); executeIntent.putExtra(TERMUX_SERVICE.EXTRA_WORKDIR, TERMUX_RECEIVEDIR);
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class); executeIntent.setClass(FileReceiverActivity.this, TermuxService.class);
startService(executeIntent); startService(executeIntent);
finish(); finish();
}, },
@@ -236,10 +241,45 @@ public class TermuxFileReceiverActivity extends AppCompatActivity {
final Uri urlOpenerProgramUri = UriUtils.getFileUri(URL_OPENER_PROGRAM); final Uri urlOpenerProgramUri = UriUtils.getFileUri(URL_OPENER_PROGRAM);
Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, urlOpenerProgramUri); Intent executeIntent = new Intent(TERMUX_SERVICE.ACTION_SERVICE_EXECUTE, urlOpenerProgramUri);
executeIntent.setClass(TermuxFileReceiverActivity.this, TermuxService.class); executeIntent.setClass(FileReceiverActivity.this, TermuxService.class);
executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{url}); executeIntent.putExtra(TERMUX_SERVICE.EXTRA_ARGUMENTS, new String[]{url});
startService(executeIntent); startService(executeIntent);
finish(); finish();
} }
/**
* Update {@link TERMUX_APP#FILE_SHARE_RECEIVER_ACTIVITY_CLASS_NAME} component state depending on
* {@link TermuxPropertyConstants#KEY_DISABLE_FILE_SHARE_RECEIVER} value and
* {@link TERMUX_APP#FILE_VIEW_RECEIVER_ACTIVITY_CLASS_NAME} component state depending on
* {@link TermuxPropertyConstants#KEY_DISABLE_FILE_VIEW_RECEIVER} value.
*/
public static void updateFileReceiverActivityComponentsState(@NonNull Context context) {
new Thread() {
@Override
public void run() {
TermuxAppSharedProperties properties = TermuxAppSharedProperties.getProperties();
String errmsg;
boolean state;
state = !properties.isFileShareReceiverDisabled();
Logger.logVerbose(LOG_TAG, "Setting " + TERMUX_APP.FILE_SHARE_RECEIVER_ACTIVITY_CLASS_NAME + " component state to " + state);
errmsg = PackageUtils.setComponentState(context,TermuxConstants.TERMUX_PACKAGE_NAME,
TERMUX_APP.FILE_SHARE_RECEIVER_ACTIVITY_CLASS_NAME,
state, null, false, false);
if (errmsg != null)
Logger.logError(LOG_TAG, errmsg);
state = !properties.isFileViewReceiverDisabled();
Logger.logVerbose(LOG_TAG, "Setting " + TERMUX_APP.FILE_VIEW_RECEIVER_ACTIVITY_CLASS_NAME + " component state to " + state);
errmsg = PackageUtils.setComponentState(context,TermuxConstants.TERMUX_PACKAGE_NAME,
TERMUX_APP.FILE_VIEW_RECEIVER_ACTIVITY_CLASS_NAME,
state, null, false, false);
if (errmsg != null)
Logger.logError(LOG_TAG, errmsg);
}
}.start();
}
} }

View File

@@ -1,4 +1,6 @@
package com.termux.filepicker; package com.termux.app.api.file;
import com.termux.app.api.file.FileReceiverActivity;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@@ -9,7 +11,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class TermuxFileReceiverActivityTest { public class FileReceiverActivityTest {
@Test @Test
public void testIsSharedTextAnUrl() { public void testIsSharedTextAnUrl() {
@@ -19,13 +21,13 @@ public class TermuxFileReceiverActivityTest {
validUrls.add("https://example.com/path/parameter=foo"); validUrls.add("https://example.com/path/parameter=foo");
validUrls.add("magnet:?xt=urn:btih:d540fc48eb12f2833163eed6421d449dd8f1ce1f&dn=Ubuntu+desktop+19.04+%2864bit%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80"); validUrls.add("magnet:?xt=urn:btih:d540fc48eb12f2833163eed6421d449dd8f1ce1f&dn=Ubuntu+desktop+19.04+%2864bit%29&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.ccc.de%3A80");
for (String url : validUrls) { for (String url : validUrls) {
Assert.assertTrue(TermuxFileReceiverActivity.isSharedTextAnUrl(url)); Assert.assertTrue(FileReceiverActivity.isSharedTextAnUrl(url));
} }
List<String> invalidUrls = new ArrayList<>(); List<String> invalidUrls = new ArrayList<>();
invalidUrls.add("a test with example.com"); invalidUrls.add("a test with example.com");
for (String url : invalidUrls) { for (String url : invalidUrls) {
Assert.assertFalse(TermuxFileReceiverActivity.isSharedTextAnUrl(url)); Assert.assertFalse(FileReceiverActivity.isSharedTextAnUrl(url));
} }
} }

View File

@@ -11,7 +11,7 @@ import java.util.Formatter;
import java.util.List; import java.util.List;
/* /*
* Version: v0.50.0 * Version: v0.51.0
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* Changelog * Changelog
@@ -271,6 +271,9 @@ import java.util.List;
* *
* - 0.50.0 (2022-06-11) * - 0.50.0 (2022-06-11)
* - Added `TERMUX_CONFIG_PREFIX_DIR_PATH`, `TERMUX_ENV_FILE_PATH` and `TERMUX_ENV_TEMP_FILE_PATH`. * - Added `TERMUX_CONFIG_PREFIX_DIR_PATH`, `TERMUX_ENV_FILE_PATH` and `TERMUX_ENV_TEMP_FILE_PATH`.
*
* - 0.51.0 (2022-06-13)
* - Added `TERMUX_APP.FILE_SHARE_RECEIVER_ACTIVITY_CLASS_NAME` and `TERMUX_APP.FILE_VIEW_RECEIVER_ACTIVITY_CLASS_NAME`.
*/ */
/** /**
@@ -907,9 +910,16 @@ public final class TermuxConstants {
/** termux-am socket file path */ /** termux-am socket file path */
public static final String TERMUX_AM_SOCKET_FILE_PATH = APPS_DIR_PATH + "/termux-am/am.sock"; // Default: "/data/data/com.termux/files/apps/com.termux/termux-am/am.sock" public static final String TERMUX_AM_SOCKET_FILE_PATH = APPS_DIR_PATH + "/termux-am/am.sock"; // Default: "/data/data/com.termux/files/apps/com.termux/termux-am/am.sock"
/** Termux app BuildConfig class name */ /** Termux app BuildConfig class name */
public static final String BUILD_CONFIG_CLASS_NAME = TERMUX_PACKAGE_NAME + ".BuildConfig"; // Default: "com.termux.BuildConfig" public static final String BUILD_CONFIG_CLASS_NAME = TERMUX_PACKAGE_NAME + ".BuildConfig"; // Default: "com.termux.BuildConfig"
/** Termux app FileShareReceiverActivity class name */
public static final String FILE_SHARE_RECEIVER_ACTIVITY_CLASS_NAME = TERMUX_PACKAGE_NAME + ".app.api.file.FileShareReceiverActivity"; // Default: "com.termux.app.api.file.FileShareReceiverActivity"
/** Termux app FileViewReceiverActivity class name */
public static final String FILE_VIEW_RECEIVER_ACTIVITY_CLASS_NAME = TERMUX_PACKAGE_NAME + ".app.api.file.FileViewReceiverActivity"; // Default: "com.termux.app.api.file.FileViewReceiverActivity"
/** Termux app core activity name. */ /** Termux app core activity name. */
public static final String TERMUX_ACTIVITY_NAME = TERMUX_PACKAGE_NAME + ".app.TermuxActivity"; // Default: "com.termux.app.TermuxActivity" public static final String TERMUX_ACTIVITY_NAME = TERMUX_PACKAGE_NAME + ".app.TermuxActivity"; // Default: "com.termux.app.TermuxActivity"

View File

@@ -18,7 +18,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
/* /*
* Version: v0.17.0 * Version: v0.18.0
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
* Changelog * Changelog
@@ -77,6 +77,9 @@ import java.util.Set;
* *
* - 0.17.0 (2022-03-17) * - 0.17.0 (2022-03-17)
* - Add `KEY_DELETE_TMPDIR_FILES_OLDER_THAN_X_DAYS_ON_EXIT`. * - Add `KEY_DELETE_TMPDIR_FILES_OLDER_THAN_X_DAYS_ON_EXIT`.
*
* - 0.18.0 (2022-06-13)
* - Add `KEY_DISABLE_FILE_SHARE_RECEIVER` and `KEY_DISABLE_FILE_VIEW_RECEIVER`.
*/ */
/** /**
@@ -96,6 +99,14 @@ public final class TermuxPropertyConstants {
/* boolean */ /* boolean */
/** Defines the key for whether file share receiver of the app is enabled. */
public static final String KEY_DISABLE_FILE_SHARE_RECEIVER = "disable-file-share-receiver"; // Default: "disable-file-share-receiver"
/** Defines the key for whether file view receiver of the app is enabled. */
public static final String KEY_DISABLE_FILE_VIEW_RECEIVER = "disable-file-view-receiver"; // Default: "disable-file-view-receiver"
/** Defines the key for whether hardware keyboard shortcuts are enabled. */ /** Defines the key for whether hardware keyboard shortcuts are enabled. */
public static final String KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS = "disable-hardware-keyboard-shortcuts"; // Default: "disable-hardware-keyboard-shortcuts" public static final String KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS = "disable-hardware-keyboard-shortcuts"; // Default: "disable-hardware-keyboard-shortcuts"
@@ -380,6 +391,8 @@ public final class TermuxPropertyConstants {
* */ * */
public static final Set<String> TERMUX_APP_PROPERTIES_LIST = new HashSet<>(Arrays.asList( public static final Set<String> TERMUX_APP_PROPERTIES_LIST = new HashSet<>(Arrays.asList(
/* boolean */ /* boolean */
KEY_DISABLE_FILE_SHARE_RECEIVER,
KEY_DISABLE_FILE_VIEW_RECEIVER,
KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS, KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS,
KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST, KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST,
KEY_ENFORCE_CHAR_BASED_INPUT, KEY_ENFORCE_CHAR_BASED_INPUT,
@@ -426,6 +439,8 @@ public final class TermuxPropertyConstants {
* default: false * default: false
*/ */
public static final Set<String> TERMUX_DEFAULT_FALSE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList( public static final Set<String> TERMUX_DEFAULT_FALSE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList(
KEY_DISABLE_FILE_SHARE_RECEIVER,
KEY_DISABLE_FILE_VIEW_RECEIVER,
KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS, KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS,
KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST, KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST,
KEY_ENFORCE_CHAR_BASED_INPUT, KEY_ENFORCE_CHAR_BASED_INPUT,

View File

@@ -563,6 +563,15 @@ public abstract class TermuxSharedProperties {
public boolean shouldAllowExternalApps() { public boolean shouldAllowExternalApps() {
return (boolean) getInternalPropertyValue(TermuxConstants.PROP_ALLOW_EXTERNAL_APPS, true); return (boolean) getInternalPropertyValue(TermuxConstants.PROP_ALLOW_EXTERNAL_APPS, true);
} }
public boolean isFileShareReceiverDisabled() {
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_FILE_SHARE_RECEIVER, true);
}
public boolean isFileViewReceiverDisabled() {
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_FILE_VIEW_RECEIVER, true);
}
public boolean areHardwareKeyboardShortcutsDisabled() { public boolean areHardwareKeyboardShortcutsDisabled() {
return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS, true); return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_HARDWARE_KEYBOARD_SHORTCUTS, true);
} }