Add more options in the Select menu
Allow users to select all/none and automatically include new applications. Close #93 as completed. Co-authored-by: mywalk <66966897+mywalkb@users.noreply.github.com>
This commit is contained in:
parent
c5ff4c0e3a
commit
1339fc7d3c
|
|
@ -390,4 +390,23 @@ public class ConfigManager {
|
|||
return ILSPManagerService.DEX2OAT_CRASHED;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean getAutoInclude(String packageName) {
|
||||
try {
|
||||
return LSPManagerServiceHolder.getService().getAutoInclude(packageName);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(App.TAG, Log.getStackTraceString(e));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean setAutoInclude(String packageName, boolean enable) {
|
||||
try {
|
||||
LSPManagerServiceHolder.getService().setAutoInclude(packageName, enable);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(App.TAG, Log.getStackTraceString(e));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,6 +292,26 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
|||
fragment.showHint(R.string.enable_documentui, true);
|
||||
return false;
|
||||
}
|
||||
} else if (itemId == R.id.select_all) {
|
||||
var tmpChkList = new HashSet<ApplicationWithEquals>(ConfigManager.getModuleScope(module.packageName));
|
||||
for (AppInfo info : searchList) {
|
||||
if (info.packageName.equals("android")) {
|
||||
fragment.showHint(R.string.reboot_required, true, R.string.reboot, v -> ConfigManager.reboot());
|
||||
}
|
||||
tmpChkList.add(info.application);
|
||||
}
|
||||
ConfigManager.setModuleScope(module.packageName, module.legacy, tmpChkList);
|
||||
} else if (itemId == R.id.select_none) {
|
||||
var tmpChkList = new HashSet<ApplicationWithEquals>(ConfigManager.getModuleScope(module.packageName));
|
||||
for (AppInfo info : searchList) {
|
||||
if (tmpChkList.remove(info.application) && info.packageName.equals("android")) {
|
||||
fragment.showHint(R.string.reboot_required, true, R.string.reboot, v -> ConfigManager.reboot());
|
||||
}
|
||||
}
|
||||
ConfigManager.setModuleScope(module.packageName, module.legacy, tmpChkList);
|
||||
} else if (itemId == R.id.auto_include) {
|
||||
item.setChecked(!item.isChecked());
|
||||
ConfigManager.setAutoInclude(module.packageName, item.isChecked());
|
||||
} else if (!AppHelper.onOptionsItemSelected(item, preferences)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -371,6 +391,7 @@ public class ScopeAdapter extends EmptyStateRecyclerView.EmptyStateAdapter<Scope
|
|||
}
|
||||
case 0 -> menu.findItem(R.id.item_sort_by_name).setChecked(true);
|
||||
}
|
||||
menu.findItem(R.id.auto_include).setChecked(ConfigManager.getAutoInclude(module.packageName));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -29,32 +29,44 @@
|
|||
android:title="@android:string/search_go" />
|
||||
|
||||
<item
|
||||
android:id="@+id/use_recommended"
|
||||
android:title="@string/use_recommended" />
|
||||
android:showAsAction="never"
|
||||
android:title="@string/menu_select">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/use_recommended"
|
||||
android:title="@string/use_recommended" />
|
||||
<item
|
||||
android:id="@+id/select_all"
|
||||
android:title="@string/menu_select_all" />
|
||||
<item
|
||||
android:id="@+id/select_none"
|
||||
android:title="@string/menu_select_none" />
|
||||
<item
|
||||
android:id="@+id/auto_include"
|
||||
android:checkable="true"
|
||||
android:title="@string/menu_auto_include" />
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:showAsAction="never"
|
||||
android:title="@string/menu_hide">
|
||||
<menu>
|
||||
|
||||
<item
|
||||
android:id="@+id/item_filter_games"
|
||||
android:checkable="true"
|
||||
android:checked="true"
|
||||
android:title="@string/menu_show_games" />
|
||||
|
||||
<item
|
||||
android:id="@+id/item_filter_modules"
|
||||
android:checkable="true"
|
||||
android:checked="true"
|
||||
android:title="@string/menu_show_modules" />
|
||||
|
||||
<item
|
||||
android:id="@+id/item_filter_system"
|
||||
android:checkable="true"
|
||||
android:checked="true"
|
||||
android:title="@string/menu_show_system_apps" />
|
||||
|
||||
<item
|
||||
android:id="@+id/item_filter_denylist"
|
||||
android:checkable="true"
|
||||
|
|
|
|||
|
|
@ -141,9 +141,13 @@
|
|||
<string name="menu_show_denylist">Denylist</string>
|
||||
<string name="failed_to_save_scope_list">Failed to save scope list</string>
|
||||
<string name="app_version">Version: %1$s</string>
|
||||
<string name="menu_select">Select</string>
|
||||
<string name="use_recommended">Recommended</string>
|
||||
<string name="no_scope_selected_has_recommended">You did not select any app. Select recommended apps?</string>
|
||||
<string name="use_recommended_message">Select recommended apps?</string>
|
||||
<string name="menu_select_all">All</string>
|
||||
<string name="menu_select_none">None</string>
|
||||
<string name="menu_auto_include">Auto-Include</string>
|
||||
<string name="module_is_not_activated_yet">Xposed module is not activated yet</string>
|
||||
<string name="requested_by_module">Recommended</string>
|
||||
<string name="update_available">Update available: %1$s</string>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import android.content.pm.PackageInfo;
|
|||
import android.content.pm.PackageParser;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteStatement;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -141,7 +142,9 @@ public class ConfigManager {
|
|||
"module_pkg_name text NOT NULL UNIQUE," +
|
||||
"apk_path text NOT NULL, " +
|
||||
"enabled BOOLEAN DEFAULT 0 " +
|
||||
"CHECK (enabled IN (0, 1))" +
|
||||
"CHECK (enabled IN (0, 1))," +
|
||||
"auto_include BOOLEAN DEFAULT 0 " +
|
||||
"CHECK (auto_include IN (0, 1))" +
|
||||
");");
|
||||
private final SQLiteStatement createScopeTable = db.compileStatement("CREATE TABLE IF NOT EXISTS scope (" +
|
||||
"mid integer," +
|
||||
|
|
@ -420,6 +423,20 @@ public class ConfigManager {
|
|||
db.compileStatement("UPDATE scope SET app_pkg_name = 'system' WHERE app_pkg_name = 'android';").execute();
|
||||
db.setVersion(3);
|
||||
});
|
||||
case 3:
|
||||
try {
|
||||
executeInTransaction(() -> {
|
||||
db.compileStatement("ALTER TABLE modules ADD COLUMN auto_include BOOLEAN DEFAULT 0 CHECK (auto_include IN (0, 1));").execute();
|
||||
db.setVersion(4);
|
||||
});
|
||||
} catch (SQLiteException ex) {
|
||||
// Fix wrong init code for new column auto_include
|
||||
if (ex.getMessage().startsWith("duplicate column name: auto_include")) {
|
||||
db.setVersion(4);
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -894,20 +911,7 @@ public class ConfigManager {
|
|||
|
||||
|
||||
public String[] enabledModules() {
|
||||
try (Cursor cursor = db.query("modules", new String[]{"module_pkg_name"}, "enabled = 1", null, null, null, null)) {
|
||||
if (cursor == null) {
|
||||
Log.e(TAG, "query enabled modules failed");
|
||||
return null;
|
||||
}
|
||||
int modulePkgNameIdx = cursor.getColumnIndex("module_pkg_name");
|
||||
HashSet<String> result = new HashSet<>();
|
||||
while (cursor.moveToNext()) {
|
||||
var pkgName = cursor.getString(modulePkgNameIdx);
|
||||
if (pkgName.equals("lspd")) continue;
|
||||
result.add(pkgName);
|
||||
}
|
||||
return result.toArray(new String[0]);
|
||||
}
|
||||
return listModules("enabled");
|
||||
}
|
||||
|
||||
public boolean removeModule(String packageName) {
|
||||
|
|
@ -1223,4 +1227,41 @@ public class ConfigManager {
|
|||
synchronized SharedMemory getPreloadDex() {
|
||||
return ConfigFileManager.getPreloadDex(dexObfuscate);
|
||||
}
|
||||
|
||||
public boolean getAutoInclude(String packageName) {
|
||||
try (Cursor cursor = db.query("modules", new String[]{"auto_include"},
|
||||
"module_pkg_name = ? and auto_include = 1", new String[]{packageName}, null, null, null, null)) {
|
||||
return cursor == null || cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setAutoInclude(String packageName, boolean enable) {
|
||||
boolean changed = executeInTransaction(() -> {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("auto_include", enable ? 1 : 0);
|
||||
return db.update("modules", values, "module_pkg_name = ?", new String[]{packageName}) > 0;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public String[] getAutoIncludeModules() {
|
||||
return listModules("auto_include");
|
||||
}
|
||||
|
||||
private String[] listModules(String column) {
|
||||
try (Cursor cursor = db.query("modules", new String[]{"module_pkg_name"}, column + " = 1", null, null, null, null)) {
|
||||
if (cursor == null) {
|
||||
Log.e(TAG, "query " + column + " modules failed");
|
||||
return null;
|
||||
}
|
||||
int modulePkgNameIdx = cursor.getColumnIndex("module_pkg_name");
|
||||
HashSet<String> result = new HashSet<>();
|
||||
while (cursor.moveToNext()) {
|
||||
var pkgName = cursor.getString(modulePkgNameIdx);
|
||||
if (pkgName.equals("lspd")) continue;
|
||||
result.add(pkgName);
|
||||
}
|
||||
return result.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -556,4 +556,14 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
|||
public boolean isLogWatchdogEnabled() {
|
||||
return ConfigManager.getInstance().isLogWatchdogEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAutoInclude(String packageName, boolean enabled) {
|
||||
return ConfigManager.getInstance().setAutoInclude(packageName, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoInclude(String packageName) {
|
||||
return ConfigManager.getInstance().getAutoInclude(packageName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import android.telephony.TelephonyManager;
|
|||
import android.util.Log;
|
||||
|
||||
import org.lsposed.daemon.BuildConfig;
|
||||
import org.lsposed.lspd.models.Application;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -151,8 +152,10 @@ public class LSPosedService extends ILSPosedService.Stub {
|
|||
if (moduleName != null) {
|
||||
LSPNotificationManager.cancelNotification(UPDATED_CHANNEL_ID, moduleName, userId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_CHANGED -> {
|
||||
var configManager = ConfigManager.getInstance();
|
||||
// make sure that the change is for the complete package, not only a
|
||||
// component
|
||||
String[] components = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
|
||||
|
|
@ -164,10 +167,32 @@ public class LSPosedService extends ILSPosedService.Stub {
|
|||
// module to send a broadcast when modules that have not been activated are
|
||||
// uninstalled.
|
||||
// If cache not updated, assume it's not xposed module
|
||||
isXposedModule = ConfigManager.getInstance().updateModuleApkPath(moduleName, ConfigManager.getInstance().getModuleApkPath(applicationInfo), false);
|
||||
} else if (ConfigManager.getInstance().isUidHooked(uid)) {
|
||||
// it will auto update obsolete scope from database
|
||||
ConfigManager.getInstance().updateAppCache();
|
||||
isXposedModule = configManager.updateModuleApkPath(moduleName, ConfigManager.getInstance().getModuleApkPath(applicationInfo), false);
|
||||
} else {
|
||||
if (configManager.isUidHooked(uid)) {
|
||||
// it will automatically remove obsolete app from database
|
||||
configManager.updateAppCache();
|
||||
}
|
||||
if (intentAction.equals(Intent.ACTION_PACKAGE_ADDED) && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
|
||||
for (String xposedModule : configManager.getAutoIncludeModules()) {
|
||||
// For Xposed modules with auto_include set, we always add new applications
|
||||
// to its scope
|
||||
var list = configManager.getModuleScope(xposedModule);
|
||||
if (list != null) {
|
||||
Application scope = new Application();
|
||||
scope.packageName = moduleName;
|
||||
scope.userId = userId;
|
||||
list.add(scope);
|
||||
try {
|
||||
if (!configManager.setModuleScope(xposedModule, list)) {
|
||||
Log.e(TAG, "failed to set scope for " + xposedModule);
|
||||
}
|
||||
} catch(RemoteException re) {
|
||||
Log.e(TAG, "failed to set scope for " + xposedModule, re);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
broadcastAndShowNotification(moduleName, userId, intent, isXposedModule);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,4 +91,8 @@ interface ILSPManagerService {
|
|||
void setLogWatchdog(boolean enable) = 49;
|
||||
|
||||
boolean isLogWatchdogEnabled() = 50;
|
||||
|
||||
boolean getAutoInclude(String packageName) = 51;
|
||||
|
||||
boolean setAutoInclude(String packageName, boolean enable) = 52;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue