Removed direct static usages of database from app
This commit is contained in:
parent
d4561507b8
commit
c275326d59
@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -29,8 +28,6 @@ open class App : Application(), Application.ActivityLifecycleCallbacks {
|
|||||||
|
|
||||||
lateinit var protectedContext: Context
|
lateinit var protectedContext: Context
|
||||||
|
|
||||||
@Deprecated("Use dependency injection", level = DeprecationLevel.ERROR)
|
|
||||||
val prefs: SharedPreferences by inject()
|
|
||||||
@Deprecated("Use dependency injection", level = DeprecationLevel.ERROR)
|
@Deprecated("Use dependency injection", level = DeprecationLevel.ERROR)
|
||||||
val DB: MagiskDB by inject()
|
val DB: MagiskDB by inject()
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk;
|
package com.topjohnwu.magisk;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
@ -15,26 +16,29 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.collection.ArrayMap;
|
import androidx.collection.ArrayMap;
|
||||||
|
|
||||||
public class Config {
|
import static com.topjohnwu.magisk.ConfigLeanback.getPrefs;
|
||||||
|
import static com.topjohnwu.magisk.utils.XAndroidKt.getPackageName;
|
||||||
|
|
||||||
// Current status
|
public final class Config {
|
||||||
public static String magiskVersionString;
|
|
||||||
|
private static final ArrayMap<String, Object> defs = new ArrayMap<>();
|
||||||
public static int magiskVersionCode = -1;
|
public static int magiskVersionCode = -1;
|
||||||
private static boolean magiskHide;
|
// Current status
|
||||||
|
public static String magiskVersionString = "";
|
||||||
// Update Info
|
// Update Info
|
||||||
public static String remoteMagiskVersionString;
|
public static String remoteMagiskVersionString = "";
|
||||||
public static int remoteMagiskVersionCode = -1;
|
public static int remoteMagiskVersionCode = -1;
|
||||||
public static String magiskLink;
|
public static String magiskLink = "";
|
||||||
public static String magiskNoteLink;
|
public static String magiskNoteLink = "";
|
||||||
public static String magiskMD5;
|
public static String magiskMD5 = "";
|
||||||
public static String remoteManagerVersionString;
|
public static String remoteManagerVersionString = "";
|
||||||
public static int remoteManagerVersionCode = -1;
|
public static int remoteManagerVersionCode = -1;
|
||||||
public static String managerLink;
|
public static String managerLink = "";
|
||||||
public static String managerNoteLink;
|
public static String managerNoteLink = "";
|
||||||
public static String uninstallerLink;
|
public static String uninstallerLink = "";
|
||||||
|
|
||||||
// Install flags
|
// Install flags
|
||||||
public static boolean keepVerity = false;
|
public static boolean keepVerity = false;
|
||||||
@ -98,25 +102,76 @@ public class Config {
|
|||||||
public static final int ORDER_DATE = 1;
|
public static final int ORDER_DATE = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean magiskHide = false;
|
||||||
|
|
||||||
public static void loadMagiskInfo() {
|
public static void loadMagiskInfo() {
|
||||||
try {
|
try {
|
||||||
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
|
magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0];
|
||||||
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
|
magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V"));
|
||||||
magiskHide = Shell.su("magiskhide --status").exec().isSuccess();
|
magiskHide = Shell.su("magiskhide --status").exec().isSuccess();
|
||||||
} catch (NumberFormatException ignored) {}
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void export() {
|
public static void export() {
|
||||||
// Flush prefs to disk
|
// Flush prefs to disk
|
||||||
App app = App.self;
|
getPrefs().edit().apply();
|
||||||
app.getPrefs().edit().commit();
|
Context context = ConfigLeanback.getProtectedContext();
|
||||||
File xml = new File(App.deContext.getFilesDir().getParent() + "/shared_prefs",
|
File xml = new File(context.getFilesDir().getParent() + "/shared_prefs",
|
||||||
app.getPackageName() + "_preferences.xml");
|
getPackageName() + "_preferences.xml");
|
||||||
Shell.su(Utils.fmt("cat %s > /data/adb/%s", xml, Const.MANAGER_CONFIGS)).exec();
|
Shell.su(Utils.fmt("cat %s > /data/adb/%s", xml, Const.MANAGER_CONFIGS)).exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int PREF_INT = 0;
|
||||||
|
private static final int PREF_STR_INT = 1;
|
||||||
|
private static final int PREF_BOOL = 2;
|
||||||
|
private static final int PREF_STR = 3;
|
||||||
|
private static final int DB_INT = 4;
|
||||||
|
private static final int DB_BOOL = 5;
|
||||||
|
private static final int DB_STR = 6;
|
||||||
|
|
||||||
|
private static int getConfigType(String key) {
|
||||||
|
switch (key) {
|
||||||
|
case Key.REPO_ORDER:
|
||||||
|
return PREF_INT;
|
||||||
|
|
||||||
|
case Key.SU_REQUEST_TIMEOUT:
|
||||||
|
case Key.SU_AUTO_RESPONSE:
|
||||||
|
case Key.SU_NOTIFICATION:
|
||||||
|
case Key.UPDATE_CHANNEL:
|
||||||
|
return PREF_STR_INT;
|
||||||
|
|
||||||
|
case Key.DARK_THEME:
|
||||||
|
case Key.SU_REAUTH:
|
||||||
|
case Key.CHECK_UPDATES:
|
||||||
|
case Key.MAGISKHIDE:
|
||||||
|
case Key.COREONLY:
|
||||||
|
case Key.SHOW_SYSTEM_APP:
|
||||||
|
return PREF_BOOL;
|
||||||
|
|
||||||
|
case Key.CUSTOM_CHANNEL:
|
||||||
|
case Key.LOCALE:
|
||||||
|
case Key.ETAG_KEY:
|
||||||
|
return PREF_STR;
|
||||||
|
|
||||||
|
case Key.ROOT_ACCESS:
|
||||||
|
case Key.SU_MNT_NS:
|
||||||
|
case Key.SU_MULTIUSER_MODE:
|
||||||
|
return DB_INT;
|
||||||
|
|
||||||
|
case Key.SU_FINGERPRINT:
|
||||||
|
return DB_BOOL;
|
||||||
|
|
||||||
|
case Key.SU_MANAGER:
|
||||||
|
return DB_STR;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
SharedPreferences pref = App.self.getPrefs();
|
SharedPreferences pref = getPrefs();
|
||||||
SharedPreferences.Editor editor = pref.edit();
|
SharedPreferences.Editor editor = pref.edit();
|
||||||
File config = SuFile.open("/data/adb", Const.MANAGER_CONFIGS);
|
File config = SuFile.open("/data/adb", Const.MANAGER_CONFIGS);
|
||||||
if (config.exists()) {
|
if (config.exists()) {
|
||||||
@ -185,125 +240,72 @@ public class Config {
|
|||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int PREF_INT = 0;
|
|
||||||
private static final int PREF_STR_INT = 1;
|
|
||||||
private static final int PREF_BOOL = 2;
|
|
||||||
private static final int PREF_STR = 3;
|
|
||||||
private static final int DB_INT = 4;
|
|
||||||
private static final int DB_BOOL = 5;
|
|
||||||
private static final int DB_STR = 6;
|
|
||||||
|
|
||||||
private static int getConfigType(String key) {
|
|
||||||
switch (key) {
|
|
||||||
case Key.REPO_ORDER:
|
|
||||||
return PREF_INT;
|
|
||||||
|
|
||||||
case Key.SU_REQUEST_TIMEOUT:
|
|
||||||
case Key.SU_AUTO_RESPONSE:
|
|
||||||
case Key.SU_NOTIFICATION:
|
|
||||||
case Key.UPDATE_CHANNEL:
|
|
||||||
return PREF_STR_INT;
|
|
||||||
|
|
||||||
case Key.DARK_THEME:
|
|
||||||
case Key.SU_REAUTH:
|
|
||||||
case Key.CHECK_UPDATES:
|
|
||||||
case Key.MAGISKHIDE:
|
|
||||||
case Key.COREONLY:
|
|
||||||
case Key.SHOW_SYSTEM_APP:
|
|
||||||
return PREF_BOOL;
|
|
||||||
|
|
||||||
case Key.CUSTOM_CHANNEL:
|
|
||||||
case Key.LOCALE:
|
|
||||||
case Key.ETAG_KEY:
|
|
||||||
return PREF_STR;
|
|
||||||
|
|
||||||
case Key.ROOT_ACCESS:
|
|
||||||
case Key.SU_MNT_NS:
|
|
||||||
case Key.SU_MULTIUSER_MODE:
|
|
||||||
return DB_INT;
|
|
||||||
|
|
||||||
case Key.SU_FINGERPRINT:
|
|
||||||
return DB_BOOL;
|
|
||||||
|
|
||||||
case Key.SU_MANAGER:
|
|
||||||
return DB_STR;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T get(String key) {
|
public static <T> T get(String key) {
|
||||||
App app = App.self;
|
|
||||||
switch (getConfigType(key)) {
|
switch (getConfigType(key)) {
|
||||||
case PREF_INT:
|
case PREF_INT:
|
||||||
return (T) (Integer) app.getPrefs().getInt(key, getDef(key));
|
return (T) (Integer) getPrefs().getInt(key, getDef(key));
|
||||||
case PREF_STR_INT:
|
case PREF_STR_INT:
|
||||||
return (T) (Integer) Utils.getPrefsInt(app.getPrefs(), key, getDef(key));
|
return (T) (Integer) Utils.getPrefsInt(getPrefs(), key, getDef(key));
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
return (T) (Boolean) app.getPrefs().getBoolean(key, getDef(key));
|
return (T) (Boolean) getPrefs().getBoolean(key, getDef(key));
|
||||||
case PREF_STR:
|
case PREF_STR:
|
||||||
return (T) app.getPrefs().getString(key, getDef(key));
|
return (T) getPrefs().getString(key, getDef(key));
|
||||||
case DB_INT:
|
case DB_INT:
|
||||||
return (T) (Integer) app.getDB().getSettings(key, getDef(key));
|
return (T) (Integer) ConfigLeanback.get(key, (Integer) getDef(key));
|
||||||
case DB_BOOL:
|
case DB_BOOL:
|
||||||
return (T) (Boolean) (app.getDB().getSettings(key, getDef(key) ? 1 : 0) != 0);
|
return (T) (Boolean) (ConfigLeanback.get(key, getDef(key) ? 1 : 0) != 0);
|
||||||
case DB_STR:
|
case DB_STR:
|
||||||
return (T) app.getDB().getStrings(key, getDef(key));
|
return (T) ConfigLeanback.get(key, getDef(key));
|
||||||
}
|
}
|
||||||
/* Will never get here (IllegalArgumentException in getConfigType) */
|
/* Will never get here (IllegalArgumentException in getConfigType) */
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void set(String key, Object val) {
|
public static void set(String key, Object val) {
|
||||||
App app = App.self;
|
|
||||||
switch (getConfigType(key)) {
|
switch (getConfigType(key)) {
|
||||||
case PREF_INT:
|
case PREF_INT:
|
||||||
app.getPrefs().edit().putInt(key, (int) val).apply();
|
getPrefs().edit().putInt(key, (int) val).apply();
|
||||||
break;
|
break;
|
||||||
case PREF_STR_INT:
|
case PREF_STR_INT:
|
||||||
app.getPrefs().edit().putString(key, String.valueOf(val)).apply();
|
getPrefs().edit().putString(key, String.valueOf(val)).apply();
|
||||||
break;
|
break;
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
app.getPrefs().edit().putBoolean(key, (boolean) val).apply();
|
getPrefs().edit().putBoolean(key, (boolean) val).apply();
|
||||||
break;
|
break;
|
||||||
case PREF_STR:
|
case PREF_STR:
|
||||||
app.getPrefs().edit().putString(key, (String) val).apply();
|
getPrefs().edit().putString(key, (String) val).apply();
|
||||||
break;
|
break;
|
||||||
case DB_INT:
|
case DB_INT:
|
||||||
app.getDB().setSettings(key, (int) val);
|
ConfigLeanback.put(key, (int) val);
|
||||||
break;
|
break;
|
||||||
case DB_BOOL:
|
case DB_BOOL:
|
||||||
app.getDB().setSettings(key, (boolean) val ? 1 : 0);
|
ConfigLeanback.put(key, (boolean) val ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
case DB_STR:
|
case DB_STR:
|
||||||
app.getDB().setStrings(key, (String) val);
|
ConfigLeanback.put(key, (String) val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void remove(String key) {
|
public static void remove(String key) {
|
||||||
App app = App.self;
|
|
||||||
switch (getConfigType(key)) {
|
switch (getConfigType(key)) {
|
||||||
case PREF_INT:
|
case PREF_INT:
|
||||||
case PREF_STR_INT:
|
case PREF_STR_INT:
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
case PREF_STR:
|
case PREF_STR:
|
||||||
app.getPrefs().edit().remove(key).apply();
|
getPrefs().edit().remove(key).apply();
|
||||||
break;
|
break;
|
||||||
case DB_BOOL:
|
case DB_BOOL:
|
||||||
case DB_INT:
|
case DB_INT:
|
||||||
app.getDB().rmSettings(key);
|
ConfigLeanback.delete(key);
|
||||||
break;
|
break;
|
||||||
case DB_STR:
|
case DB_STR:
|
||||||
app.getDB().setStrings(key, null);
|
ConfigLeanback.put(key, null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ArrayMap<String, Object> defs = new ArrayMap<>();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
/* Set default configurations */
|
/* Set default configurations */
|
||||||
|
|
||||||
@ -340,7 +342,9 @@ public class Config {
|
|||||||
//defs.put(Key.SU_MANAGER, null);
|
//defs.put(Key.SU_MANAGER, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T getDef(String key) {
|
@SuppressWarnings("unchecked")
|
||||||
|
@Nullable
|
||||||
|
private static <T> T getDef(String key) throws IllegalArgumentException {
|
||||||
Object val = defs.get(key);
|
Object val = defs.get(key);
|
||||||
switch (getConfigType(key)) {
|
switch (getConfigType(key)) {
|
||||||
case PREF_INT:
|
case PREF_INT:
|
||||||
@ -359,36 +363,35 @@ public class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void setDefs(SharedPreferences pref, SharedPreferences.Editor editor) {
|
private static void setDefs(SharedPreferences pref, SharedPreferences.Editor editor) {
|
||||||
App app = App.self;
|
|
||||||
for (String key : defs.keySet()) {
|
for (String key : defs.keySet()) {
|
||||||
|
Object value = defs.get(key);
|
||||||
int type = getConfigType(key);
|
int type = getConfigType(key);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DB_INT:
|
case DB_INT:
|
||||||
editor.putString(key, String.valueOf(
|
editor.putString(key, String.valueOf(ConfigLeanback.get(key, (Integer) value)));
|
||||||
app.getDB().getSettings(key, (Integer) defs.get(key))));
|
|
||||||
continue;
|
continue;
|
||||||
case DB_STR:
|
case DB_STR:
|
||||||
editor.putString(key, app.getDB().getStrings(key, (String) defs.get(key)));
|
editor.putString(key, ConfigLeanback.get(key, String.valueOf(value)));
|
||||||
continue;
|
continue;
|
||||||
case DB_BOOL:
|
case DB_BOOL:
|
||||||
int bs = app.getDB().getSettings(key, -1);
|
int bs = ConfigLeanback.get(key, -1);
|
||||||
editor.putBoolean(key, bs < 0 ? (Boolean) defs.get(key) : bs != 0);
|
editor.putBoolean(key, bs < 0 ? (Boolean) value : bs != 0);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pref.contains(key))
|
if (pref.contains(key))
|
||||||
continue;
|
continue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case PREF_INT:
|
case PREF_INT:
|
||||||
editor.putInt(key, (Integer) defs.get(key));
|
editor.putInt(key, (Integer) value);
|
||||||
break;
|
break;
|
||||||
case PREF_STR_INT:
|
case PREF_STR_INT:
|
||||||
editor.putString(key, String.valueOf(defs.get(key)));
|
editor.putString(key, String.valueOf(value));
|
||||||
break;
|
break;
|
||||||
case PREF_STR:
|
case PREF_STR:
|
||||||
editor.putString(key, (String) defs.get(key));
|
editor.putString(key, (String) value);
|
||||||
break;
|
break;
|
||||||
case PREF_BOOL:
|
case PREF_BOOL:
|
||||||
editor.putBoolean(key, (Boolean) defs.get(key));
|
editor.putBoolean(key, (Boolean) value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
52
app/src/main/java/com/topjohnwu/magisk/ConfigLeanback.kt
Normal file
52
app/src/main/java/com/topjohnwu/magisk/ConfigLeanback.kt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package com.topjohnwu.magisk
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.annotation.AnyThread
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
|
import com.skoumal.teanity.extensions.subscribeK
|
||||||
|
import com.topjohnwu.magisk.data.repository.SettingRepository
|
||||||
|
import com.topjohnwu.magisk.data.repository.StringRepository
|
||||||
|
import com.topjohnwu.magisk.di.Protected
|
||||||
|
import com.topjohnwu.magisk.utils.inject
|
||||||
|
|
||||||
|
object ConfigLeanback {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val protectedContext: Context by inject(Protected)
|
||||||
|
@JvmStatic
|
||||||
|
val prefs: SharedPreferences by inject()
|
||||||
|
|
||||||
|
private val settingRepo: SettingRepository by inject()
|
||||||
|
private val stringRepo: StringRepository by inject()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@AnyThread
|
||||||
|
fun put(key: String, value: Int) {
|
||||||
|
settingRepo.put(key, value).subscribeK()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@WorkerThread
|
||||||
|
fun get(key: String, defaultValue: Int): Int =
|
||||||
|
settingRepo.fetch(key, defaultValue).blockingGet()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@AnyThread
|
||||||
|
fun put(key: String, value: String?) {
|
||||||
|
val task = value?.let { stringRepo.put(key, it) } ?: stringRepo.delete(key)
|
||||||
|
task.subscribeK()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@WorkerThread
|
||||||
|
fun get(key: String, defaultValue: String?): String =
|
||||||
|
stringRepo.fetch(key, defaultValue.orEmpty()).blockingGet()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@AnyThread
|
||||||
|
fun delete(key: String) {
|
||||||
|
settingRepo.delete(key).subscribeK()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,8 +14,8 @@ class SettingsDao : BaseDao() {
|
|||||||
values(key to value.toString())
|
values(key to value.toString())
|
||||||
}.ignoreElement()
|
}.ignoreElement()
|
||||||
|
|
||||||
fun fetch(key: String) = query<Select> {
|
fun fetch(key: String, default: Int = -1) = query<Select> {
|
||||||
condition { equals("key", key) }
|
condition { equals("key", key) }
|
||||||
}.map { it.first().values.first().toIntOrNull() ?: -1 }
|
}.map { it.firstOrNull()?.values?.firstOrNull()?.toIntOrNull() ?: default }
|
||||||
|
|
||||||
}
|
}
|
@ -31,6 +31,8 @@ class LogRepository(
|
|||||||
.toSingle()
|
.toSingle()
|
||||||
.map { it.exec() }
|
.map { it.exec() }
|
||||||
|
|
||||||
|
fun put(log: MagiskLog) = logDao.put(log)
|
||||||
|
|
||||||
private fun List<MagiskLog>.wrap(): List<WrappedMagiskLog> {
|
private fun List<MagiskLog>.wrap(): List<WrappedMagiskLog> {
|
||||||
val day = TimeUnit.DAYS.toMillis(1)
|
val day = TimeUnit.DAYS.toMillis(1)
|
||||||
return groupBy { it.date.time / day }
|
return groupBy { it.date.time / day }
|
||||||
|
@ -4,7 +4,7 @@ import com.topjohnwu.magisk.data.database.SettingsDao
|
|||||||
|
|
||||||
class SettingRepository(private val settingsDao: SettingsDao) {
|
class SettingRepository(private val settingsDao: SettingsDao) {
|
||||||
|
|
||||||
fun fetch(key: String) = settingsDao.fetch(key)
|
fun fetch(key: String, default: Int) = settingsDao.fetch(key, default)
|
||||||
fun put(key: String, value: Int) = settingsDao.put(key, value)
|
fun put(key: String, value: Int) = settingsDao.put(key, value)
|
||||||
fun delete(key: String) = settingsDao.delete(key)
|
fun delete(key: String) = settingsDao.delete(key)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import com.topjohnwu.magisk.data.database.StringDao
|
|||||||
|
|
||||||
class StringRepository(private val stringDao: StringDao) {
|
class StringRepository(private val stringDao: StringDao) {
|
||||||
|
|
||||||
fun fetch(key: String) = stringDao.fetch(key)
|
fun fetch(key: String, default: String) = stringDao.fetch(key, default)
|
||||||
fun put(key: String, value: String) = stringDao.put(key, value)
|
fun put(key: String, value: String) = stringDao.put(key, value)
|
||||||
fun delete(key: String) = stringDao.delete(key)
|
fun delete(key: String) = stringDao.delete(key)
|
||||||
|
|
||||||
|
@ -12,8 +12,7 @@ val applicationModule = module {
|
|||||||
factory { get<Context>().resources }
|
factory { get<Context>().resources }
|
||||||
factory { get<Context>() as App }
|
factory { get<Context>() as App }
|
||||||
factory { get<Context>().packageManager }
|
factory { get<Context>().packageManager }
|
||||||
single(SUTimeout) {
|
factory(Protected) { get<App>().protectedContext }
|
||||||
get<App>().protectedContext.getSharedPreferences("su_timeout", 0)
|
single(SUTimeout) { get<Context>(Protected).getSharedPreferences("su_timeout", 0) }
|
||||||
}
|
single { PreferenceManager.getDefaultSharedPreferences(get<Context>(Protected)) }
|
||||||
single { PreferenceManager.getDefaultSharedPreferences(get<App>().protectedContext) }
|
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,4 @@ package com.topjohnwu.magisk.di
|
|||||||
import org.koin.core.qualifier.named
|
import org.koin.core.qualifier.named
|
||||||
|
|
||||||
val SUTimeout = named("su_timeout")
|
val SUTimeout = named("su_timeout")
|
||||||
|
val Protected = named("protected")
|
@ -1,5 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
package com.topjohnwu.magisk.model.entity
|
||||||
|
|
||||||
|
import com.topjohnwu.magisk.model.entity.MagiskPolicy.Companion.ALLOW
|
||||||
import com.topjohnwu.magisk.utils.timeFormatTime
|
import com.topjohnwu.magisk.utils.timeFormatTime
|
||||||
import com.topjohnwu.magisk.utils.toTime
|
import com.topjohnwu.magisk.utils.toTime
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -48,3 +49,10 @@ fun MagiskLog.toMap() = mapOf(
|
|||||||
"action" to action,
|
"action" to action,
|
||||||
"time" to date
|
"time" to date
|
||||||
).mapValues { it.toString() }
|
).mapValues { it.toString() }
|
||||||
|
|
||||||
|
fun MagiskPolicy.toLog(
|
||||||
|
toUid: Int,
|
||||||
|
fromPid: Int,
|
||||||
|
command: String,
|
||||||
|
date: Date
|
||||||
|
) = MagiskLog(uid, toUid, fromPid, packageName, appName, command, policy == ALLOW, date)
|
||||||
|
@ -2,18 +2,27 @@ package com.topjohnwu.magisk.model.entity
|
|||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import com.topjohnwu.magisk.model.entity.MagiskPolicy.Companion.INTERACTIVE
|
||||||
|
|
||||||
|
|
||||||
data class MagiskPolicy(
|
data class MagiskPolicy(
|
||||||
val uid: Int,
|
val uid: Int,
|
||||||
val packageName: String,
|
val packageName: String,
|
||||||
val appName: String,
|
val appName: String,
|
||||||
val policy: Int,
|
val policy: Int = INTERACTIVE,
|
||||||
val until: Long,
|
val until: Long = -1L,
|
||||||
val logging: Boolean,
|
val logging: Boolean = true,
|
||||||
val notification: Boolean,
|
val notification: Boolean = true,
|
||||||
val applicationInfo: ApplicationInfo
|
val applicationInfo: ApplicationInfo
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val INTERACTIVE = 0
|
||||||
|
const val DENY = 1
|
||||||
|
const val ALLOW = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*@Throws(PackageManager.NameNotFoundException::class)
|
/*@Throws(PackageManager.NameNotFoundException::class)
|
||||||
fun ContentValues.toPolicy(pm: PackageManager): MagiskPolicy {
|
fun ContentValues.toPolicy(pm: PackageManager): MagiskPolicy {
|
||||||
@ -64,7 +73,7 @@ fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
|||||||
return MagiskPolicy(
|
return MagiskPolicy(
|
||||||
uid = uid,
|
uid = uid,
|
||||||
packageName = packageName,
|
packageName = packageName,
|
||||||
policy = get("policy")?.toIntOrNull() ?: -1,
|
policy = get("policy")?.toIntOrNull() ?: INTERACTIVE,
|
||||||
until = get("until")?.toLongOrNull() ?: -1L,
|
until = get("until")?.toLongOrNull() ?: -1L,
|
||||||
logging = get("logging")?.toIntOrNull() != 0,
|
logging = get("logging")?.toIntOrNull() != 0,
|
||||||
notification = get("notification")?.toIntOrNull() != 0,
|
notification = get("notification")?.toIntOrNull() != 0,
|
||||||
@ -72,3 +81,16 @@ fun Map<String, String>.toPolicy(pm: PackageManager): MagiskPolicy {
|
|||||||
appName = info.loadLabel(pm).toString()
|
appName = info.loadLabel(pm).toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(PackageManager.NameNotFoundException::class)
|
||||||
|
fun Int.toPolicy(pm: PackageManager): MagiskPolicy {
|
||||||
|
val pkg = pm.getPackagesForUid(this)?.firstOrNull()
|
||||||
|
?: throw PackageManager.NameNotFoundException()
|
||||||
|
val info = pm.getApplicationInfo(pkg, 0)
|
||||||
|
return MagiskPolicy(
|
||||||
|
uid = this,
|
||||||
|
packageName = pkg,
|
||||||
|
applicationInfo = info,
|
||||||
|
appName = info.loadLabel(pm).toString()
|
||||||
|
)
|
||||||
|
}
|
@ -15,11 +15,11 @@ public class SuLogEntry {
|
|||||||
public boolean action;
|
public boolean action;
|
||||||
public Date date;
|
public Date date;
|
||||||
|
|
||||||
public SuLogEntry(Policy policy) {
|
public SuLogEntry(MagiskPolicy policy) {
|
||||||
fromUid = policy.uid;
|
fromUid = policy.getUid();
|
||||||
packageName = policy.packageName;
|
packageName = policy.getPackageName();
|
||||||
appName = policy.appName;
|
appName = policy.getAppName();
|
||||||
action = policy.policy == Policy.ALLOW;
|
action = policy.getPolicy() == Policy.ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SuLogEntry(ContentValues values) {
|
public SuLogEntry(ContentValues values) {
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.receiver;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.App;
|
|
||||||
import com.topjohnwu.magisk.ClassMap;
|
|
||||||
import com.topjohnwu.magisk.Config;
|
|
||||||
import com.topjohnwu.magisk.Const;
|
|
||||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity;
|
|
||||||
import com.topjohnwu.magisk.utils.DownloadApp;
|
|
||||||
import com.topjohnwu.magisk.utils.SuLogger;
|
|
||||||
import com.topjohnwu.magisk.view.Notifications;
|
|
||||||
import com.topjohnwu.magisk.view.Shortcuts;
|
|
||||||
import com.topjohnwu.superuser.Shell;
|
|
||||||
|
|
||||||
public class GeneralReceiver extends BroadcastReceiver {
|
|
||||||
|
|
||||||
private String getPkg(Intent i) {
|
|
||||||
return i.getData() == null ? "" : i.getData().getEncodedSchemeSpecificPart();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
App app = App.self;
|
|
||||||
if (intent == null)
|
|
||||||
return;
|
|
||||||
String action = intent.getAction();
|
|
||||||
if (action == null)
|
|
||||||
return;
|
|
||||||
switch (action) {
|
|
||||||
case Intent.ACTION_REBOOT:
|
|
||||||
case Intent.ACTION_BOOT_COMPLETED:
|
|
||||||
action = intent.getStringExtra("action");
|
|
||||||
if (action == null) {
|
|
||||||
// Actual boot completed event
|
|
||||||
Shell.su("mm_patch_dtbo").submit(result -> {
|
|
||||||
if (result.isSuccess())
|
|
||||||
Notifications.dtboPatched();
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (action) {
|
|
||||||
case SuRequestActivity.REQUEST:
|
|
||||||
Intent i = new Intent(app, ClassMap.get(SuRequestActivity.class))
|
|
||||||
.setAction(action)
|
|
||||||
.putExtra("socket", intent.getStringExtra("socket"))
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
|
||||||
app.startActivity(i);
|
|
||||||
break;
|
|
||||||
case SuRequestActivity.LOG:
|
|
||||||
SuLogger.handleLogs(intent);
|
|
||||||
break;
|
|
||||||
case SuRequestActivity.NOTIFY:
|
|
||||||
SuLogger.handleNotify(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Intent.ACTION_PACKAGE_REPLACED:
|
|
||||||
// This will only work pre-O
|
|
||||||
if (Config.get(Config.Key.SU_REAUTH)) {
|
|
||||||
app.getDB().deletePolicy(getPkg(intent));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Intent.ACTION_PACKAGE_FULLY_REMOVED:
|
|
||||||
String pkg = getPkg(intent);
|
|
||||||
app.getDB().deletePolicy(pkg);
|
|
||||||
Shell.su("magiskhide --rm " + pkg).submit();
|
|
||||||
break;
|
|
||||||
case Intent.ACTION_LOCALE_CHANGED:
|
|
||||||
Shortcuts.setup(context);
|
|
||||||
break;
|
|
||||||
case Const.Key.BROADCAST_MANAGER_UPDATE:
|
|
||||||
Config.managerLink = intent.getStringExtra(Const.Key.INTENT_SET_LINK);
|
|
||||||
DownloadApp.upgrade(intent.getStringExtra(Const.Key.INTENT_SET_NAME));
|
|
||||||
break;
|
|
||||||
case Const.Key.BROADCAST_REBOOT:
|
|
||||||
Shell.su("/system/bin/reboot").submit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.topjohnwu.magisk.model.receiver
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import com.topjohnwu.magisk.ClassMap
|
||||||
|
import com.topjohnwu.magisk.Config
|
||||||
|
import com.topjohnwu.magisk.Const
|
||||||
|
import com.topjohnwu.magisk.data.database.base.su
|
||||||
|
import com.topjohnwu.magisk.data.repository.AppRepository
|
||||||
|
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||||
|
import com.topjohnwu.magisk.utils.DownloadApp
|
||||||
|
import com.topjohnwu.magisk.utils.SuLogger
|
||||||
|
import com.topjohnwu.magisk.utils.inject
|
||||||
|
import com.topjohnwu.magisk.view.Notifications
|
||||||
|
import com.topjohnwu.magisk.view.Shortcuts
|
||||||
|
import com.topjohnwu.superuser.Shell
|
||||||
|
|
||||||
|
open class GeneralReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
private val appRepo: AppRepository by inject()
|
||||||
|
|
||||||
|
private fun getPkg(i: Intent): String {
|
||||||
|
return if (i.data == null) "" else i.data!!.encodedSchemeSpecificPart
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent?) {
|
||||||
|
if (intent == null)
|
||||||
|
return
|
||||||
|
var action: String? = intent.action ?: return
|
||||||
|
when (action) {
|
||||||
|
Intent.ACTION_REBOOT, Intent.ACTION_BOOT_COMPLETED -> {
|
||||||
|
action = intent.getStringExtra("action")
|
||||||
|
if (action == null) {
|
||||||
|
// Actual boot completed event
|
||||||
|
Shell.su("mm_patch_dtbo").submit { result ->
|
||||||
|
if (result.isSuccess)
|
||||||
|
Notifications.dtboPatched()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
when (action) {
|
||||||
|
SuRequestActivity.REQUEST -> {
|
||||||
|
val i = Intent(context, ClassMap.get<Any>(SuRequestActivity::class.java))
|
||||||
|
.setAction(action)
|
||||||
|
.putExtra("socket", intent.getStringExtra("socket"))
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
|
||||||
|
context.startActivity(i)
|
||||||
|
}
|
||||||
|
SuRequestActivity.LOG -> SuLogger.handleLogs(intent)
|
||||||
|
SuRequestActivity.NOTIFY -> SuLogger.handleNotify(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Intent.ACTION_PACKAGE_REPLACED ->
|
||||||
|
// This will only work pre-O
|
||||||
|
if (Config.get<Boolean>(Config.Key.SU_REAUTH)!!) {
|
||||||
|
appRepo.delete(getPkg(intent)).blockingGet()
|
||||||
|
}
|
||||||
|
Intent.ACTION_PACKAGE_FULLY_REMOVED -> {
|
||||||
|
val pkg = getPkg(intent)
|
||||||
|
appRepo.delete(pkg).blockingGet()
|
||||||
|
"magiskhide --rm $pkg".su().blockingGet()
|
||||||
|
}
|
||||||
|
Intent.ACTION_LOCALE_CHANGED -> Shortcuts.setup(context)
|
||||||
|
Const.Key.BROADCAST_MANAGER_UPDATE -> {
|
||||||
|
Config.managerLink = intent.getStringExtra(Const.Key.INTENT_SET_LINK)
|
||||||
|
DownloadApp.upgrade(intent.getStringExtra(Const.Key.INTENT_SET_NAME))
|
||||||
|
}
|
||||||
|
Const.Key.BROADCAST_REBOOT -> Shell.su("/system/bin/reboot").submit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,88 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.utils;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Process;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.App;
|
|
||||||
import com.topjohnwu.magisk.Config;
|
|
||||||
import com.topjohnwu.magisk.R;
|
|
||||||
import com.topjohnwu.magisk.model.entity.Policy;
|
|
||||||
import com.topjohnwu.magisk.model.entity.SuLogEntry;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class SuLogger {
|
|
||||||
|
|
||||||
public static void handleLogs(Intent intent) {
|
|
||||||
|
|
||||||
int fromUid = intent.getIntExtra("from.uid", -1);
|
|
||||||
if (fromUid < 0) return;
|
|
||||||
if (fromUid == Process.myUid()) return;
|
|
||||||
|
|
||||||
App app = App.self;
|
|
||||||
PackageManager pm = app.getPackageManager();
|
|
||||||
Policy policy;
|
|
||||||
|
|
||||||
boolean notify;
|
|
||||||
Bundle data = intent.getExtras();
|
|
||||||
if (data.containsKey("notify")) {
|
|
||||||
notify = data.getBoolean("notify");
|
|
||||||
try {
|
|
||||||
policy = new Policy(fromUid, pm);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Doesn't report whether notify or not, check database ourselves
|
|
||||||
policy = app.getDB().getPolicy(fromUid);
|
|
||||||
if (policy == null)
|
|
||||||
return;
|
|
||||||
notify = policy.notification;
|
|
||||||
}
|
|
||||||
|
|
||||||
policy.policy = data.getInt("policy", -1);
|
|
||||||
if (policy.policy < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (notify)
|
|
||||||
handleNotify(policy);
|
|
||||||
|
|
||||||
SuLogEntry log = new SuLogEntry(policy);
|
|
||||||
|
|
||||||
int toUid = intent.getIntExtra("to.uid", -1);
|
|
||||||
if (toUid < 0) return;
|
|
||||||
int pid = intent.getIntExtra("pid", -1);
|
|
||||||
if (pid < 0) return;
|
|
||||||
String command = intent.getStringExtra("command");
|
|
||||||
if (command == null) return;
|
|
||||||
log.toUid = toUid;
|
|
||||||
log.fromPid = pid;
|
|
||||||
log.command = command;
|
|
||||||
log.date = new Date();
|
|
||||||
app.getDB().addLog(log);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void handleNotify(Policy policy) {
|
|
||||||
if (policy.notification &&
|
|
||||||
(int) Config.get(Config.Key.SU_NOTIFICATION) == Config.Value.NOTIFICATION_TOAST) {
|
|
||||||
Utils.toast(App.self.getString(policy.policy == Policy.ALLOW ?
|
|
||||||
R.string.su_allow_toast : R.string.su_deny_toast, policy.appName),
|
|
||||||
Toast.LENGTH_SHORT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void handleNotify(Intent intent) {
|
|
||||||
int fromUid = intent.getIntExtra("from.uid", -1);
|
|
||||||
if (fromUid < 0) return;
|
|
||||||
if (fromUid == Process.myUid()) return;
|
|
||||||
try {
|
|
||||||
Policy policy = new Policy(fromUid, App.self.getPackageManager());
|
|
||||||
policy.policy = intent.getIntExtra("policy", -1);
|
|
||||||
if (policy.policy >= 0)
|
|
||||||
handleNotify(policy);
|
|
||||||
} catch (PackageManager.NameNotFoundException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
|
94
app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt
Normal file
94
app/src/main/java/com/topjohnwu/magisk/utils/SuLogger.kt
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package com.topjohnwu.magisk.utils
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Process
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.topjohnwu.magisk.App
|
||||||
|
import com.topjohnwu.magisk.Config
|
||||||
|
import com.topjohnwu.magisk.R
|
||||||
|
import com.topjohnwu.magisk.data.repository.AppRepository
|
||||||
|
import com.topjohnwu.magisk.data.repository.LogRepository
|
||||||
|
import com.topjohnwu.magisk.model.entity.MagiskPolicy
|
||||||
|
import com.topjohnwu.magisk.model.entity.Policy
|
||||||
|
import com.topjohnwu.magisk.model.entity.toLog
|
||||||
|
import com.topjohnwu.magisk.model.entity.toPolicy
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object SuLogger {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun handleLogs(intent: Intent) {
|
||||||
|
|
||||||
|
val fromUid = intent.getIntExtra("from.uid", -1)
|
||||||
|
if (fromUid < 0) return
|
||||||
|
if (fromUid == Process.myUid()) return
|
||||||
|
|
||||||
|
val pm: PackageManager by inject()
|
||||||
|
|
||||||
|
val notify: Boolean
|
||||||
|
val data = intent.extras
|
||||||
|
val policy: MagiskPolicy = if (data!!.containsKey("notify")) {
|
||||||
|
notify = data.getBoolean("notify")
|
||||||
|
runCatching {
|
||||||
|
fromUid.toPolicy(pm)
|
||||||
|
}.getOrElse { return }
|
||||||
|
} else {
|
||||||
|
// Doesn't report whether notify or not, check database ourselves
|
||||||
|
val appRepo: AppRepository by inject()
|
||||||
|
val policy = appRepo.fetch(fromUid).blockingGet() ?: return
|
||||||
|
notify = policy.notification
|
||||||
|
policy
|
||||||
|
}.copy(policy = data.getInt("policy", -1))
|
||||||
|
|
||||||
|
if (policy.policy < 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (notify)
|
||||||
|
handleNotify(policy)
|
||||||
|
|
||||||
|
val toUid = intent.getIntExtra("to.uid", -1)
|
||||||
|
if (toUid < 0) return
|
||||||
|
|
||||||
|
val pid = intent.getIntExtra("pid", -1)
|
||||||
|
if (pid < 0) return
|
||||||
|
|
||||||
|
val command = intent.getStringExtra("command") ?: return
|
||||||
|
val log = policy.toLog(
|
||||||
|
toUid = toUid,
|
||||||
|
fromPid = pid,
|
||||||
|
command = command,
|
||||||
|
date = Date()
|
||||||
|
)
|
||||||
|
|
||||||
|
val logRepo: LogRepository by inject()
|
||||||
|
logRepo.put(log).blockingGet()?.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleNotify(policy: MagiskPolicy) {
|
||||||
|
if (policy.notification && Config.get<Any>(Config.Key.SU_NOTIFICATION) as Int == Config.Value.NOTIFICATION_TOAST) {
|
||||||
|
Utils.toast(
|
||||||
|
App.self.getString(
|
||||||
|
if (policy.policy == Policy.ALLOW)
|
||||||
|
R.string.su_allow_toast
|
||||||
|
else
|
||||||
|
R.string.su_deny_toast, policy.appName
|
||||||
|
),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleNotify(intent: Intent) {
|
||||||
|
val fromUid = intent.getIntExtra("from.uid", -1)
|
||||||
|
if (fromUid < 0) return
|
||||||
|
if (fromUid == Process.myUid()) return
|
||||||
|
runCatching {
|
||||||
|
val packageManager: PackageManager by inject()
|
||||||
|
val policy = fromUid.toPolicy(packageManager)
|
||||||
|
.copy(policy = intent.getIntExtra("policy", -1))
|
||||||
|
if (policy.policy >= 0)
|
||||||
|
handleNotify(policy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user