diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0fffc13..56072fa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,6 +10,8 @@ + + @@ -22,6 +24,11 @@ + + + + + { if (adapter instanceof SettingsRecyclerAdapter) { - Boolean isGranted = EditorUtils.checkSettingsPermission(this, ((SettingsRecyclerAdapter) adapter).getSettingsType()); + @SettingsType String settingsType = ((SettingsRecyclerAdapter) adapter).getSettingsType(); + Boolean isGranted = EditorUtils.checkSettingsPermission(this, settingsType); if (isGranted == null) return; if (isGranted) { addNewItemDialog(); } else { - EditorUtils.displayGrantPermissionMessage(this); + EditorUtils.displayGrantPermissionMessage(this, settingsType); } } }); diff --git a/app/src/main/java/io/github/muntashirakon/setedit/EditorUtils.java b/app/src/main/java/io/github/muntashirakon/setedit/EditorUtils.java index 6019b95..dd8770c 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/EditorUtils.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/EditorUtils.java @@ -34,8 +34,8 @@ public class EditorUtils { */ @Nullable public static Boolean checkSettingsPermission(@NonNull Context context, @SettingsType String settingsType) { - String permission = SettingsType.SYSTEM_SETTINGS.equals(settingsType) - ? Manifest.permission.WRITE_SETTINGS : Manifest.permission.WRITE_SECURE_SETTINGS; + String permission = requiredPermission(settingsType); + if (SettingsType.SYSTEM_SETTINGS.equals(settingsType)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.System.canWrite(context)) { if (Boolean.TRUE.equals(Shell.isAppGrantedRoot())) { @@ -60,19 +60,38 @@ public static Boolean checkSettingsPermission(@NonNull Context context, @Setting } @SuppressLint({"InflateParams", "SetTextI18n"}) - public static void displayGrantPermissionMessage(@NonNull Context context) { + public static void displayGrantPermissionMessage(@NonNull Context context, @SettingsType String settingsType) { View view = LayoutInflater.from(context).inflate(R.layout.dialog_unsupported, null); TextView tv = view.findViewById(R.id.txt); - tv.setText("pm grant " + BuildConfig.APPLICATION_ID + " " + Manifest.permission.WRITE_SECURE_SETTINGS); + tv.setText("pm grant " + BuildConfig.APPLICATION_ID + " " + requiredPermission(settingsType)); tv.setKeyListener(null); tv.setSelectAllOnFocus(true); tv.requestFocus(); + + new MaterialAlertDialogBuilder(context) .setView(view) .setNegativeButton(R.string.close, null) .show(); } + @NonNull + private static String requiredPermission(@SettingsType String settingsType) { + switch (settingsType) { + case SettingsType.SYSTEM_SETTINGS: return Manifest.permission.WRITE_SETTINGS; + case SettingsType.SECURE_SETTINGS: + case SettingsType.GLOBAL_SETTINGS: return Manifest.permission.WRITE_SECURE_SETTINGS; + case SettingsType.MOTO_GLOBAL_SETTINGS: + case SettingsType.MOTO_SECURE_SETTINGS: + case SettingsType.MOTO_SYSTEM_SETTINGS: return "com.motorola.permission.WRITE_SECURE_SETTINGS"; + case SettingsType.LINEAGE_GLOBAL_SETTINGS: + case SettingsType.LINEAGE_SECURE_SETTINGS: + case SettingsType.LINEAGE_SYSTEM_SETTINGS: return "lineageos.permission.WRITE_SETTINGS"; + default: + throw new UnsupportedOperationException("Unexpected Value: " + settingsType); + } + } + @NonNull public static String getJson(@NonNull List> items, @Nullable String settingsType) throws JSONException { @@ -105,6 +124,18 @@ public static String toTableType(@TableTypeInt int tableTypeInt) { return TableType.TABLE_BOOT; case TableTypeInt.TABLE_SHORTCUTS: return TableType.TABLE_SHORTCUTS; + case TableTypeInt.TABLE_MOTO_SYSTEM: + return TableType.TABLE_MOTO_SYSTEM; + case TableTypeInt.TABLE_MOTO_SECURE: + return TableType.TABLE_MOTO_SECURE; + case TableTypeInt.TABLE_MOTO_GLOBAL: + return TableType.TABLE_MOTO_GLOBAL; + case TableTypeInt.TABLE_LINEAGE_SYSTEM: + return TableType.TABLE_LINEAGE_SYSTEM; + case TableTypeInt.TABLE_LINEAGE_SECURE: + return TableType.TABLE_LINEAGE_SECURE; + case TableTypeInt.TABLE_LINEAGE_GLOBAL: + return TableType.TABLE_LINEAGE_GLOBAL; default: throw new IllegalArgumentException("Invalid table type: " + tableTypeInt); } diff --git a/app/src/main/java/io/github/muntashirakon/setedit/SettingsType.java b/app/src/main/java/io/github/muntashirakon/setedit/SettingsType.java index a6ed1f7..28397c6 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/SettingsType.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/SettingsType.java @@ -5,10 +5,19 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -@StringDef({SettingsType.SYSTEM_SETTINGS, SettingsType.SECURE_SETTINGS, SettingsType.GLOBAL_SETTINGS}) +@StringDef({SettingsType.SYSTEM_SETTINGS, SettingsType.SECURE_SETTINGS, SettingsType.GLOBAL_SETTINGS, + SettingsType.MOTO_SYSTEM_SETTINGS, SettingsType.MOTO_SECURE_SETTINGS, SettingsType.MOTO_GLOBAL_SETTINGS, + SettingsType.LINEAGE_SYSTEM_SETTINGS, SettingsType.LINEAGE_SECURE_SETTINGS, SettingsType.LINEAGE_GLOBAL_SETTINGS}) @Retention(RetentionPolicy.SOURCE) public @interface SettingsType { - String SYSTEM_SETTINGS = "system"; - String SECURE_SETTINGS = "secure"; - String GLOBAL_SETTINGS = "global"; + String SYSTEM_SETTINGS = "settings/system"; + String SECURE_SETTINGS = "settings/secure"; + String GLOBAL_SETTINGS = "settings/global"; + + String MOTO_SYSTEM_SETTINGS = "com.motorola.android.providers.settings/system"; + String MOTO_SECURE_SETTINGS = "com.motorola.android.providers.settings/secure"; + String MOTO_GLOBAL_SETTINGS = "com.motorola.android.providers.settings/global"; + String LINEAGE_SYSTEM_SETTINGS = "lineagesettings/system"; + String LINEAGE_SECURE_SETTINGS = "lineagesettings/secure"; + String LINEAGE_GLOBAL_SETTINGS = "lineagesettings/global"; } diff --git a/app/src/main/java/io/github/muntashirakon/setedit/TableType.java b/app/src/main/java/io/github/muntashirakon/setedit/TableType.java index 7150daa..281d6da 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/TableType.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/TableType.java @@ -5,12 +5,18 @@ @Retention(RetentionPolicy.SOURCE) public @interface TableType { - String TABLE_SYSTEM = "system"; - String TABLE_SECURE = "secure"; - String TABLE_GLOBAL = "global"; + String TABLE_SYSTEM = "settings/system"; + String TABLE_SECURE = "settings/secure"; + String TABLE_GLOBAL = "settings/global"; String TABLE_PROPERTIES = "property"; String TABLE_JAVA = "java"; String TABLE_ENV = "env"; String TABLE_BOOT = "boot"; String TABLE_SHORTCUTS = "shortcuts"; + String TABLE_MOTO_SYSTEM = "com.motorola.android.providers.settings/system"; + String TABLE_MOTO_SECURE = "com.motorola.android.providers.settings/secure"; + String TABLE_MOTO_GLOBAL = "com.motorola.android.providers.settings/global"; + String TABLE_LINEAGE_SYSTEM = "lineagesettings/system"; + String TABLE_LINEAGE_SECURE = "lineagesettings/secure"; + String TABLE_LINEAGE_GLOBAL = "lineagesettings/global"; } diff --git a/app/src/main/java/io/github/muntashirakon/setedit/TableTypeInt.java b/app/src/main/java/io/github/muntashirakon/setedit/TableTypeInt.java index e42e8c8..468a948 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/TableTypeInt.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/TableTypeInt.java @@ -13,4 +13,10 @@ int TABLE_ENV = 5; int TABLE_BOOT = 6; int TABLE_SHORTCUTS = 7; + int TABLE_MOTO_SYSTEM = 8; + int TABLE_MOTO_SECURE = 9; + int TABLE_MOTO_GLOBAL = 10; + int TABLE_LINEAGE_SYSTEM = 11; + int TABLE_LINEAGE_SECURE = 12; + int TABLE_LINEAGE_GLOBAL = 13; } diff --git a/app/src/main/java/io/github/muntashirakon/setedit/adapters/AdapterProvider.java b/app/src/main/java/io/github/muntashirakon/setedit/adapters/AdapterProvider.java index 8923a2d..2878258 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/adapters/AdapterProvider.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/adapters/AdapterProvider.java @@ -30,6 +30,18 @@ public AbsRecyclerAdapter getRecyclerAdapter(@TableTypeInt int position) { return new BootItemsRecyclerAdapter(context); case TableTypeInt.TABLE_SHORTCUTS: return new ShortcutsRecyclerAdapter(context); + case TableTypeInt.TABLE_MOTO_SYSTEM: + return new SettingsRecyclerAdapter(context, SettingsType.MOTO_SYSTEM_SETTINGS); + case TableTypeInt.TABLE_MOTO_SECURE: + return new SettingsRecyclerAdapter(context, SettingsType.MOTO_SECURE_SETTINGS); + case TableTypeInt.TABLE_MOTO_GLOBAL: + return new SettingsRecyclerAdapter(context, SettingsType.MOTO_GLOBAL_SETTINGS); + case TableTypeInt.TABLE_LINEAGE_SYSTEM: + return new SettingsRecyclerAdapter(context, SettingsType.LINEAGE_SYSTEM_SETTINGS); + case TableTypeInt.TABLE_LINEAGE_SECURE: + return new SettingsRecyclerAdapter(context, SettingsType.LINEAGE_SECURE_SETTINGS); + case TableTypeInt.TABLE_LINEAGE_GLOBAL: + return new SettingsRecyclerAdapter(context, SettingsType.LINEAGE_GLOBAL_SETTINGS); default: throw new IllegalArgumentException("Invalid position " + position); } diff --git a/app/src/main/java/io/github/muntashirakon/setedit/adapters/SettingsRecyclerAdapter.java b/app/src/main/java/io/github/muntashirakon/setedit/adapters/SettingsRecyclerAdapter.java index 7c0b119..b2214ec 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/adapters/SettingsRecyclerAdapter.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/adapters/SettingsRecyclerAdapter.java @@ -14,11 +14,14 @@ import androidx.core.util.Pair; import androidx.fragment.app.FragmentActivity; +import com.topjohnwu.superuser.Shell; + import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; +import io.github.muntashirakon.setedit.EditorUtils; import io.github.muntashirakon.setedit.R; import io.github.muntashirakon.setedit.SettingsType; import io.github.muntashirakon.setedit.TableTypeInt; @@ -77,34 +80,56 @@ public int getListType() { return TableTypeInt.TABLE_SECURE; case SettingsType.GLOBAL_SETTINGS: return TableTypeInt.TABLE_GLOBAL; + case SettingsType.MOTO_SYSTEM_SETTINGS: + return TableTypeInt.TABLE_MOTO_SYSTEM; + case SettingsType.MOTO_SECURE_SETTINGS: + return TableTypeInt.TABLE_MOTO_SECURE; + case SettingsType.MOTO_GLOBAL_SETTINGS: + return TableTypeInt.TABLE_MOTO_GLOBAL; + case SettingsType.LINEAGE_SYSTEM_SETTINGS: + return TableTypeInt.TABLE_LINEAGE_SYSTEM; + case SettingsType.LINEAGE_SECURE_SETTINGS: + return TableTypeInt.TABLE_LINEAGE_SECURE; + case SettingsType.LINEAGE_GLOBAL_SETTINGS: + return TableTypeInt.TABLE_LINEAGE_GLOBAL; } } @Override public boolean canSetOnReboot() { - return true; + return canEdit(); } @Override public boolean canCreateShortcut() { - return true; + return canEdit(); } @Override public boolean canCreate() { - return true; + return canEdit(); } @Override public boolean canEdit() { - return true; + switch (mSettingsType) { + case SettingsType.MOTO_GLOBAL_SETTINGS: + case SettingsType.MOTO_SECURE_SETTINGS: + case SettingsType.MOTO_SYSTEM_SETTINGS: + return Boolean.TRUE.equals(Shell.isAppGrantedRoot()) || + Boolean.TRUE.equals(EditorUtils.checkSettingsPermission(context, mSettingsType)); + default: + return true; + } } @Override public boolean canDelete() { - return true; + return canEdit(); } + + @Override public void create(String keyName, String newValue) { ActionResult result = SettingsUtils.create(context, mSettingsType, keyName, newValue); @@ -223,9 +248,11 @@ protected FilterResults performFiltering(CharSequence constraint) { @Override protected void publishResults(CharSequence constraint, FilterResults results) { - //noinspection unchecked - AdapterUtils.notifyDataSetChanged(SettingsRecyclerAdapter.this, mMatchedPositions, - (List) results.values); + if (results.values!=null) { + //noinspection unchecked + AdapterUtils.notifyDataSetChanged(SettingsRecyclerAdapter.this, mMatchedPositions, + (List) results.values); + } } }; } @@ -237,7 +264,7 @@ private static Cursor getCursor(Context context, String settingsType) { try { ContentResolver contentResolver = context.getContentResolver(); @Nullable - Cursor query = contentResolver.query(Uri.parse("content://settings/" + settingsType), + Cursor query = contentResolver.query(Uri.parse("content://" + settingsType), columns, null, null, null); return new SettingsCursor(query); } catch (Throwable th) { diff --git a/app/src/main/java/io/github/muntashirakon/setedit/utils/SettingsUtils.java b/app/src/main/java/io/github/muntashirakon/setedit/utils/SettingsUtils.java index 24ab6c3..4f1a1d7 100644 --- a/app/src/main/java/io/github/muntashirakon/setedit/utils/SettingsUtils.java +++ b/app/src/main/java/io/github/muntashirakon/setedit/utils/SettingsUtils.java @@ -30,7 +30,7 @@ public static ActionResult update(@NonNull Context context, @SettingsType String public static ActionResult delete(@NonNull Context context, @SettingsType String settingsType, @NonNull String keyName) { if (Boolean.TRUE.equals(Shell.isAppGrantedRoot())) { - Shell.Result result = Shell.cmd("settings delete " + settingsType + " " + keyName).exec(); + Shell.Result result = Shell.cmd(commandBuilder(settingsType) +" delete " + settingsType + " " + keyName).exec(); ActionResult r = new ActionResult(ActionResult.TYPE_DELETE, result.isSuccess()); r.setLogs(TextUtils.join("\n", result.getErr())); return r; @@ -38,13 +38,13 @@ public static ActionResult delete(@NonNull Context context, @SettingsType String Boolean isGranted = EditorUtils.checkSettingsPermission(context, settingsType); if (isGranted == null) return new ActionResult(ActionResult.TYPE_DELETE, false); if (!isGranted) { - EditorUtils.displayGrantPermissionMessage(context); + EditorUtils.displayGrantPermissionMessage(context, settingsType); return new ActionResult(ActionResult.TYPE_DELETE, false); } ContentResolver contentResolver = context.getContentResolver(); try { String[] strArr = {keyName}; - contentResolver.delete(Uri.parse("content://settings/" + settingsType), "name = ?", strArr); + contentResolver.delete(Uri.parse("content://" + settingsType), "name = ?", strArr); return new ActionResult(ActionResult.TYPE_DELETE, true); } catch (Throwable th) { th.printStackTrace(); @@ -59,7 +59,7 @@ private static ActionResult updateInternal(@NonNull Context context, @SettingsTy @NonNull String keyName, @NonNull String newValue, @ActionResult.ActionType int actionType) { if (Boolean.TRUE.equals(Shell.isAppGrantedRoot())) { - Shell.Result result = Shell.cmd("settings put " + settingsType + " " + keyName + " \"" + newValue + "\"").exec(); + Shell.Result result = Shell.cmd(commandBuilder(settingsType) + " put " + settingsType + " " + keyName + " \"" + newValue + "\"").exec(); ActionResult r = new ActionResult(actionType, result.isSuccess()); r.setLogs(TextUtils.join("\n", result.getErr())); return r; @@ -67,7 +67,7 @@ private static ActionResult updateInternal(@NonNull Context context, @SettingsTy Boolean isGranted = EditorUtils.checkSettingsPermission(context, settingsType); if (isGranted == null) return new ActionResult(actionType, false); if (!isGranted) { - EditorUtils.displayGrantPermissionMessage(context); + EditorUtils.displayGrantPermissionMessage(context, settingsType); return new ActionResult(actionType, false); } ContentResolver contentResolver = context.getContentResolver(); @@ -75,7 +75,7 @@ private static ActionResult updateInternal(@NonNull Context context, @SettingsTy ContentValues contentValues = new ContentValues(2); contentValues.put("name", keyName); contentValues.put("value", newValue); - contentResolver.insert(Uri.parse("content://settings/" + settingsType), contentValues); + contentResolver.insert(Uri.parse("content://" + settingsType), contentValues); return new ActionResult(actionType, true); } catch (Throwable th) { th.printStackTrace(); @@ -84,4 +84,22 @@ private static ActionResult updateInternal(@NonNull Context context, @SettingsTy return r; } } + + private static String commandBuilder(@SettingsType String settingsType) { + switch (settingsType) { + case SettingsType.GLOBAL_SETTINGS: + case SettingsType.SYSTEM_SETTINGS: + case SettingsType.SECURE_SETTINGS: + return "settings"; + case SettingsType.MOTO_GLOBAL_SETTINGS: + case SettingsType.MOTO_SYSTEM_SETTINGS: + case SettingsType.MOTO_SECURE_SETTINGS: + return "motsettings"; + case SettingsType.LINEAGE_GLOBAL_SETTINGS: + case SettingsType.LINEAGE_SECURE_SETTINGS: + case SettingsType.LINEAGE_SYSTEM_SETTINGS: + return "settings --lineage"; + default: return null; + } + } } diff --git a/app/src/main/res/layout/dialog_unsupported.xml b/app/src/main/res/layout/dialog_unsupported.xml index 9fb79da..9d9e811 100644 --- a/app/src/main/res/layout/dialog_unsupported.xml +++ b/app/src/main/res/layout/dialog_unsupported.xml @@ -10,10 +10,11 @@ android:paddingEnd="16dp"> + android:text="@string/error_no_support" /> @string/linux_environment @string/boot_items @string/shortcuts + @string/moto_system_table + @string/moto_secure_table + @string/moto_global_table + @string/lineage_system_table + @string/lineage_secure_table + @string/lineage_global_table @string/create_new_shortcut diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2e0bb7b..cfc981f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,6 +9,12 @@ System Table Secure Table Global Table + Moto System Table + Moto Secure Table + Moto Global Table + Lineage System Table + Lineage Secure Table + Lineage Global Table Android Properties Java Properties Linux Environments