Add more secure method of vold app data isolation (needs testing - enabled as default), try to fix the corrupted config issue
This commit is contained in:
parent
eab22b12c8
commit
2a00fe9b13
16 changed files with 163 additions and 51 deletions
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
|
|
@ -44,7 +44,6 @@ jobs:
|
|||
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
echo officialBuild=true >> local.properties
|
||||
echo buildWithGitSuffix=true >> local.properties
|
||||
echo storePassword='${{ secrets.KEY_STORE_PASSWORD }}' >> local.properties
|
||||
echo keyAlias='${{ secrets.ALIAS }}' >> local.properties
|
||||
echo keyPassword='${{ secrets.ALIAS_KEY_PASSWORD }}' >> local.properties
|
||||
|
|
|
|||
2
.github/workflows/pull_request.yml
vendored
2
.github/workflows/pull_request.yml
vendored
|
|
@ -30,7 +30,7 @@ jobs:
|
|||
|
||||
- name: Prepare env
|
||||
run: |
|
||||
echo buildWithGitSuffix=true >> local.properties
|
||||
touch local.properties
|
||||
mkdir -p ~/.config/.android
|
||||
ln -s ~/.config/.android ~/.android
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.appcompat.app.AppCompatDelegate
|
|||
import icu.nullptr.hidemyapplist.receiver.AppChangeReceiver
|
||||
import icu.nullptr.hidemyapplist.service.ConfigManager
|
||||
import icu.nullptr.hidemyapplist.service.PrefManager
|
||||
import icu.nullptr.hidemyapplist.ui.util.makeToast
|
||||
import icu.nullptr.hidemyapplist.ui.util.showToast
|
||||
import icu.nullptr.hidemyapplist.util.ConfigUtils.Companion.getLocale
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -29,7 +29,7 @@ class MyApp : Application() {
|
|||
super.onCreate()
|
||||
hmaApp = this
|
||||
if (!filesDir.absolutePath.startsWith("/data/user/0/")) {
|
||||
makeToast(R.string.do_not_dual)
|
||||
showToast(R.string.do_not_dual)
|
||||
exitProcess(0)
|
||||
}
|
||||
AppChangeReceiver.register(this)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import android.os.Build
|
|||
import android.util.Log
|
||||
import icu.nullptr.hidemyapplist.common.JsonConfig
|
||||
import icu.nullptr.hidemyapplist.hmaApp
|
||||
import icu.nullptr.hidemyapplist.ui.util.makeToast
|
||||
import icu.nullptr.hidemyapplist.ui.util.showToast
|
||||
import org.frknkrc44.hma_oss.R
|
||||
import org.frknkrc44.hma_oss.common.BuildConfig
|
||||
import java.io.File
|
||||
|
|
@ -19,25 +19,36 @@ object ConfigManager {
|
|||
val configFile = File("${hmaApp.filesDir.absolutePath}/config.json")
|
||||
|
||||
fun init() {
|
||||
if (!configFile.exists()) {
|
||||
configFile.writeText(JsonConfig().toString())
|
||||
val configFileIsNew = !configFile.exists()
|
||||
if (configFileIsNew) {
|
||||
config = JsonConfig()
|
||||
configFile.writeText(config.toString())
|
||||
}
|
||||
runCatching {
|
||||
config = JsonConfig.parse(configFile.readText())
|
||||
if (!configFileIsNew) config = JsonConfig.parse(configFile.readText())
|
||||
val configVersion = config.configVersion
|
||||
if (configVersion < BuildConfig.MIN_BACKUP_VERSION) throw RuntimeException("Config version too old")
|
||||
config.configVersion = BuildConfig.CONFIG_VERSION
|
||||
}.onSuccess {
|
||||
saveConfig()
|
||||
}.onFailure {
|
||||
makeToast(R.string.config_damaged)
|
||||
throw RuntimeException("Config file too old or damaged", it)
|
||||
}.onFailure { catch ->
|
||||
runCatching {
|
||||
config = JsonConfig.parse(ServiceClient.readConfig() ?: throw RuntimeException("Service config is unavailable"))
|
||||
config.configVersion = BuildConfig.CONFIG_VERSION
|
||||
showToast(R.string.home_restore_config)
|
||||
}.onSuccess {
|
||||
saveConfig()
|
||||
}.onFailure {
|
||||
showToast(R.string.config_damaged)
|
||||
throw RuntimeException("Config file too old or damaged", catch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveConfig() {
|
||||
val text = config.toString()
|
||||
ServiceClient.writeConfig(text)
|
||||
configFile.writeText(text)
|
||||
ServiceClient.syncConfig(text)
|
||||
}
|
||||
|
||||
var detailLog: Boolean
|
||||
|
|
@ -84,6 +95,13 @@ object ConfigManager {
|
|||
saveConfig()
|
||||
}
|
||||
|
||||
var skipSystemAppDataIsolation: Boolean
|
||||
get() = config.skipSystemAppDataIsolation
|
||||
set(value) {
|
||||
config.skipSystemAppDataIsolation = value
|
||||
saveConfig()
|
||||
}
|
||||
|
||||
fun importConfig(json: String) {
|
||||
config = JsonConfig.parse(json)
|
||||
config.configVersion = BuildConfig.CONFIG_VERSION
|
||||
|
|
|
|||
|
|
@ -91,8 +91,10 @@ object ServiceClient : IHMAService, IBinder.DeathRecipient {
|
|||
override fun getPackagesForPreset(presetName: String) =
|
||||
getServiceLegacy()?.getPackagesForPreset(presetName)
|
||||
|
||||
override fun syncConfig(json: String) {
|
||||
getServiceLegacy()?.syncConfig(json)
|
||||
override fun readConfig() = getServiceLegacy()?.readConfig()
|
||||
|
||||
override fun writeConfig(json: String) {
|
||||
getServiceLegacy()?.writeConfig(json)
|
||||
}
|
||||
|
||||
override fun stopService(cleanEnv: Boolean) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ import icu.nullptr.hidemyapplist.hmaApp
|
|||
import icu.nullptr.hidemyapplist.service.PrefManager
|
||||
import icu.nullptr.hidemyapplist.service.ServiceClient
|
||||
import icu.nullptr.hidemyapplist.ui.adapter.LogAdapter
|
||||
import icu.nullptr.hidemyapplist.ui.util.makeToast
|
||||
import icu.nullptr.hidemyapplist.ui.util.navController
|
||||
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
|
||||
import icu.nullptr.hidemyapplist.ui.util.showToast
|
||||
import kotlinx.coroutines.launch
|
||||
import org.frknkrc44.hma_oss.R
|
||||
import org.frknkrc44.hma_oss.databinding.FragmentLogsBinding
|
||||
|
|
@ -36,14 +36,14 @@ class LogsFragment : Fragment(R.layout.fragment_logs) {
|
|||
registerForActivityResult(ActivityResultContracts.CreateDocument("text/x-log")) save@{ uri ->
|
||||
if (uri == null) return@save
|
||||
if (logCache.isNullOrEmpty()) {
|
||||
makeToast(R.string.logs_empty)
|
||||
showToast(R.string.logs_empty)
|
||||
return@save
|
||||
}
|
||||
hmaApp.contentResolver.openOutputStream(uri).use { output ->
|
||||
if (output == null) makeToast(R.string.home_export_failed)
|
||||
if (output == null) showToast(R.string.home_export_failed)
|
||||
else output.write(logCache!!.toByteArray())
|
||||
}
|
||||
makeToast(R.string.logs_saved)
|
||||
showToast(R.string.logs_saved)
|
||||
}
|
||||
|
||||
private fun updateLogs() {
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import icu.nullptr.hidemyapplist.service.PrefManager
|
|||
import icu.nullptr.hidemyapplist.service.ServiceClient
|
||||
import icu.nullptr.hidemyapplist.ui.activity.AboutActivity
|
||||
import icu.nullptr.hidemyapplist.ui.util.enabledString
|
||||
import icu.nullptr.hidemyapplist.ui.util.makeToast
|
||||
import icu.nullptr.hidemyapplist.ui.util.navController
|
||||
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
|
||||
import icu.nullptr.hidemyapplist.ui.util.showToast
|
||||
import icu.nullptr.hidemyapplist.util.ConfigUtils.Companion.getLocale
|
||||
import icu.nullptr.hidemyapplist.util.LangList
|
||||
import icu.nullptr.hidemyapplist.util.SuUtils
|
||||
|
|
@ -100,6 +100,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
"bypassRiskyPackageWarning" -> PrefManager.bypassRiskyPackageWarning
|
||||
"appDataIsolation" -> ConfigManager.altAppDataIsolation
|
||||
"voldAppDataIsolation" -> ConfigManager.altVoldAppDataIsolation
|
||||
"skipSystemAppDataIsolation" -> ConfigManager.skipSystemAppDataIsolation
|
||||
"disableActivityLaunchProtection" -> ConfigManager.disableActivityLaunchProtection
|
||||
"forceMountData" -> ConfigManager.forceMountData
|
||||
else -> throw IllegalArgumentException("Invalid key: $key")
|
||||
|
|
@ -127,6 +128,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
"disableActivityLaunchProtection" -> ConfigManager.disableActivityLaunchProtection = value
|
||||
"appDataIsolation" -> ConfigManager.altAppDataIsolation = value
|
||||
"voldAppDataIsolation" -> ConfigManager.altVoldAppDataIsolation = value
|
||||
"skipSystemAppDataIsolation" -> ConfigManager.skipSystemAppDataIsolation = value
|
||||
else -> throw IllegalArgumentException("Invalid key: $key")
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +150,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
setPreferencesFromResource(R.xml.settings_data_isolation, rootKey)
|
||||
|
||||
findPreference<SwitchPreferenceCompat>("appDataIsolation")?.let {
|
||||
it.summary = getString(R.string.settings_need_reboot) + "\n" +
|
||||
it.summary = getString(R.string.settings_need_reboot) + "\n\n" +
|
||||
getString(
|
||||
R.string.settings_default_value,
|
||||
CommonUtils.isAppDataIsolationEnabled.enabledString(resources)
|
||||
|
|
@ -156,7 +158,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
}
|
||||
|
||||
findPreference<SwitchPreferenceCompat>("voldAppDataIsolation")?.let {
|
||||
it.summary = getString(R.string.settings_need_reboot) + "\n" +
|
||||
it.summary = getString(R.string.settings_need_reboot) + "\n\n" +
|
||||
getString(
|
||||
R.string.settings_default_value,
|
||||
CommonUtils.isVoldAppDataIsolationEnabled.enabledString(resources)
|
||||
|
|
@ -263,15 +265,15 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
.setMessage(R.string.settings_is_clean_env_summary)
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
ServiceClient.stopService(true)
|
||||
makeToast(R.string.settings_stop_system_service)
|
||||
showToast(R.string.settings_stop_system_service)
|
||||
}
|
||||
.setNegativeButton(R.string.no) { _, _ ->
|
||||
ServiceClient.stopService(false)
|
||||
makeToast(R.string.settings_stop_system_service)
|
||||
showToast(R.string.settings_stop_system_service)
|
||||
}
|
||||
.setNeutralButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
} else makeToast(R.string.home_xposed_service_off)
|
||||
} else showToast(R.string.home_xposed_service_off)
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -281,8 +283,8 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), PreferenceFragmen
|
|||
.setMessage(R.string.settings_is_clean_env_summary)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val result = SuUtils.execPrivileged("rm -rf /data/misc/hide_my_applist*")
|
||||
if (result) makeToast(R.string.settings_force_clean_env_toast_successful)
|
||||
else makeToast(R.string.settings_permission_denied)
|
||||
if (result) showToast(R.string.settings_force_clean_env_toast_successful)
|
||||
else showToast(R.string.settings_permission_denied)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import android.widget.Toast
|
|||
import androidx.annotation.StringRes
|
||||
import icu.nullptr.hidemyapplist.hmaApp
|
||||
|
||||
fun makeToast(@StringRes resId: Int) {
|
||||
fun showToast(@StringRes resId: Int) {
|
||||
Toast.makeText(hmaApp, resId, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
fun makeToast(text: CharSequence) {
|
||||
fun showToast(text: CharSequence) {
|
||||
Toast.makeText(hmaApp, text, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.attrDrawable
|
|||
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.getColor
|
||||
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.homeItemBackgroundColor
|
||||
import icu.nullptr.hidemyapplist.ui.util.ThemeUtils.themeColor
|
||||
import icu.nullptr.hidemyapplist.ui.util.makeToast
|
||||
import icu.nullptr.hidemyapplist.ui.util.navigate
|
||||
import icu.nullptr.hidemyapplist.ui.util.setupToolbar
|
||||
import icu.nullptr.hidemyapplist.ui.util.showToast
|
||||
import org.frknkrc44.hma_oss.BuildConfig
|
||||
import org.frknkrc44.hma_oss.R
|
||||
import org.frknkrc44.hma_oss.databinding.FragmentHomeBinding
|
||||
|
|
@ -43,11 +43,11 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
|
|||
if (uri == null) return@backup
|
||||
ConfigManager.configFile.inputStream().use { input ->
|
||||
hmaApp.contentResolver.openOutputStream(uri).use { output ->
|
||||
if (output == null) makeToast(R.string.home_export_failed)
|
||||
if (output == null) showToast(R.string.home_export_failed)
|
||||
else input.copyTo(output)
|
||||
}
|
||||
}
|
||||
makeToast(R.string.home_exported)
|
||||
showToast(R.string.home_exported)
|
||||
}
|
||||
|
||||
private val restoreSAFLauncher =
|
||||
|
|
@ -58,7 +58,7 @@ class HomeFragment : Fragment(R.layout.fragment_home) {
|
|||
.openInputStream(uri)?.reader().use { it?.readText() }
|
||||
?: throw IOException(getString(R.string.home_import_file_damaged))
|
||||
ConfigManager.importConfig(backup)
|
||||
makeToast(R.string.home_import_successful)
|
||||
showToast(R.string.home_import_successful)
|
||||
}.onFailure {
|
||||
it.printStackTrace()
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@
|
|||
<SwitchPreferenceCompat
|
||||
android:icon="@drawable/ic_outline_layers_24"
|
||||
android:key="appDataIsolation"
|
||||
android:summary="@string/settings_need_reboot"
|
||||
android:title="@string/settings_app_data_isolation" />
|
||||
<SwitchPreferenceCompat
|
||||
android:icon="@drawable/ic_outline_layers_24"
|
||||
android:icon="@drawable/outline_sd_storage_24"
|
||||
android:key="voldAppDataIsolation"
|
||||
android:summary="@string/settings_need_reboot"
|
||||
android:title="@string/settings_vold_app_data_isolation" />
|
||||
<Preference
|
||||
android:key="info"
|
||||
|
|
@ -17,6 +15,16 @@
|
|||
android:summary="@string/settings_overwrite_summary" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/settings_vold_app_data_isolation"
|
||||
android:dependency="voldAppDataIsolation">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="skipSystemAppDataIsolation"
|
||||
android:summary="@string/settings_need_reboot"
|
||||
android:title="@string/app_exclude_system_apps" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/settings_module">
|
||||
<SwitchPreferenceCompat
|
||||
android:icon="@drawable/outline_storage_24"
|
||||
|
|
|
|||
|
|
@ -34,16 +34,29 @@ fun getUncommittedSuffix(): String {
|
|||
|
||||
val gitHasUncommittedSuffix = getUncommittedSuffix()
|
||||
val gitCommitCount = "git rev-list HEAD --count".execute().toInt()
|
||||
val gitCommitHash = "git rev-parse --verify --short HEAD".execute()
|
||||
|
||||
// 432 is the count of commits before license changed
|
||||
val gitCommitCountAfterOss = gitCommitCount - 432
|
||||
|
||||
val minSdkVer by extra(29)
|
||||
val targetSdkVer by extra(36)
|
||||
|
||||
val appVerCode = gitCommitCount + 0x6f7373
|
||||
val appVerCode = gitCommitCount + 0x6f7373 // commit count + 0xOSS
|
||||
val appVerName by extra("oss-${gitCommitCountAfterOss}${gitHasUncommittedSuffix}")
|
||||
|
||||
/*
|
||||
* configVerCode, serviceVerCode and minBackupVerCode is used by other build.gradle.kts files
|
||||
*
|
||||
* DO NOT REMOVE THESE LINES
|
||||
*/
|
||||
|
||||
@Suppress("unused")
|
||||
val configVerCode by extra(93)
|
||||
|
||||
@Suppress("unused")
|
||||
val serviceVerCode by extra(98)
|
||||
|
||||
@Suppress("unused")
|
||||
val minBackupVerCode by extra(65)
|
||||
|
||||
val androidSourceCompatibility = JavaVersion.VERSION_21
|
||||
|
|
@ -62,8 +75,6 @@ fun Project.configureBaseExtension() {
|
|||
targetSdk = targetSdkVer
|
||||
versionCode = appVerCode
|
||||
versionName = appVerName
|
||||
if (localProperties.getProperty("buildWithGitSuffix").toBoolean())
|
||||
versionNameSuffix = ".r${gitCommitCount}.${gitCommitHash}"
|
||||
|
||||
consumerProguardFiles("proguard-rules.pro")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ interface IHMAService {
|
|||
|
||||
void stopService(boolean cleanEnv) = 0;
|
||||
|
||||
void syncConfig(String json) = 1;
|
||||
void writeConfig(String json) = 1;
|
||||
|
||||
int getServiceVersion() = 2;
|
||||
|
||||
|
|
@ -17,4 +17,6 @@ interface IHMAService {
|
|||
void handlePackageEvent(String eventType, String packageName) = 6;
|
||||
|
||||
String[] getPackagesForPreset(String presetName) = 7;
|
||||
|
||||
String readConfig() = 8;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ data class JsonConfig(
|
|||
var disableActivityLaunchProtection: Boolean = false,
|
||||
var altAppDataIsolation: Boolean = false,
|
||||
var altVoldAppDataIsolation: Boolean = false,
|
||||
var skipSystemAppDataIsolation: Boolean = true,
|
||||
val templates: MutableMap<String, Template> = mutableMapOf(),
|
||||
val scope: MutableMap<String, AppConfig> = mutableMapOf()
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package icu.nullptr.hidemyapplist.common
|
|||
|
||||
import android.content.pm.ApplicationInfo
|
||||
import java.util.zip.ZipFile
|
||||
import kotlin.text.contains
|
||||
|
||||
object RiskyPackageUtils {
|
||||
private const val GMS_PROP = "\u0000c\u0000o\u0000m\u0000.\u0000g\u0000o\u0000o\u0000g\u0000l\u0000e\u0000.\u0000a\u0000n\u0000d\u0000r\u0000o\u0000i\u0000d\u0000.\u0000g\u0000m\u0000s\u0000."
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
|
||||
private val configLock = Any()
|
||||
private val loggerLock = Any()
|
||||
private val systemApps = mutableSetOf<String>()
|
||||
val systemApps = mutableSetOf<String>()
|
||||
private val frameworkHooks = mutableSetOf<IFrameworkHook>()
|
||||
val executor: ExecutorService = Executors.newSingleThreadExecutor()
|
||||
|
||||
|
|
@ -264,18 +264,23 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun syncConfig(json: String) {
|
||||
override fun writeConfig(json: String) {
|
||||
synchronized(configLock) {
|
||||
configFile.writeText(json)
|
||||
val newConfig = JsonConfig.parse(json)
|
||||
if (newConfig.configVersion != BuildConfig.CONFIG_VERSION) {
|
||||
logW(TAG, "Sync config: version mismatch, need reboot")
|
||||
return
|
||||
runCatching {
|
||||
val newConfig = JsonConfig.parse(json)
|
||||
if (newConfig.configVersion != BuildConfig.CONFIG_VERSION) {
|
||||
logW(TAG, "Sync config: version mismatch, need reboot")
|
||||
return
|
||||
}
|
||||
config = newConfig
|
||||
configFile.writeText(json)
|
||||
frameworkHooks.forEach(IFrameworkHook::onConfigChanged)
|
||||
}.onSuccess {
|
||||
logD(TAG, "Config synced")
|
||||
}.onFailure {
|
||||
return@synchronized
|
||||
}
|
||||
config = newConfig
|
||||
frameworkHooks.forEach(IFrameworkHook::onConfigChanged)
|
||||
}
|
||||
logD(TAG, "Config synced")
|
||||
}
|
||||
|
||||
override fun getServiceVersion() = BuildConfig.SERVICE_VERSION
|
||||
|
|
@ -305,4 +310,6 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
|
||||
override fun getPackagesForPreset(presetName: String) =
|
||||
AppPresets.instance.getPresetByName(presetName)?.packages?.toTypedArray()
|
||||
|
||||
override fun readConfig() = config.toString()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import com.github.kyuubiran.ezxhelper.utils.hookAfter
|
|||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import icu.nullptr.hidemyapplist.common.Utils
|
||||
import icu.nullptr.hidemyapplist.xposed.HMAService
|
||||
import icu.nullptr.hidemyapplist.xposed.logD
|
||||
import icu.nullptr.hidemyapplist.xposed.logE
|
||||
import icu.nullptr.hidemyapplist.xposed.logI
|
||||
|
||||
|
|
@ -79,6 +81,29 @@ class AppDataIsolationHook(private val service: HMAService): IFrameworkHook {
|
|||
hooks += it
|
||||
}
|
||||
|
||||
findMethodOrNull(
|
||||
"com.android.server.am.ProcessList"
|
||||
) {
|
||||
name == "needsStorageDataIsolation"
|
||||
}?.hookAfter { param ->
|
||||
if (service.config.altVoldAppDataIsolation && service.config.skipSystemAppDataIsolation) {
|
||||
val app = param.args.find { it.javaClass.simpleName == "ProcessRecord" }
|
||||
val uid = XposedHelpers.getIntField(app, "uid")
|
||||
val apps = Utils.binderLocalScope {
|
||||
service.pms.getPackagesForUid(uid)
|
||||
} ?: return@hookAfter
|
||||
|
||||
val isSystemApp = service.systemApps.any { apps.contains(it) }
|
||||
logD(
|
||||
TAG,
|
||||
"@needsStorageDataIsolation $uid - ${apps.contentToString()} isSystemApp: $isSystemApp"
|
||||
)
|
||||
if (isSystemApp) param.result = false
|
||||
}
|
||||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
|
||||
findMethodOrNull(
|
||||
"com.android.server.StorageManagerService"
|
||||
) {
|
||||
|
|
@ -117,6 +142,44 @@ class AppDataIsolationHook(private val service: HMAService): IFrameworkHook {
|
|||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
|
||||
findMethodOrNull(
|
||||
"com.android.server.StorageManagerService"
|
||||
) {
|
||||
name == "remountAppStorageDirs"
|
||||
}?.hookBefore { param ->
|
||||
if (service.config.altVoldAppDataIsolation && service.config.skipSystemAppDataIsolation) {
|
||||
val pidPkgMap = param.args[0] as java.util.Map<*, *>
|
||||
val userId = param.args[1] as Int
|
||||
|
||||
val keysToRemove = mutableSetOf<Any>()
|
||||
|
||||
for (entry in pidPkgMap.entrySet()) {
|
||||
val pid = entry.key
|
||||
val packageName = entry.value as String
|
||||
|
||||
val apps = Utils.binderLocalScope {
|
||||
val uid = Utils.getPackageUidCompat(service.pms, packageName, 0L, userId)
|
||||
service.pms.getPackagesForUid(uid)
|
||||
} ?: continue
|
||||
|
||||
for (app in apps) {
|
||||
if (app in service.systemApps) {
|
||||
logD(
|
||||
TAG,
|
||||
"@remountAppStorageDirs SYSTEM $pid - $packageName is marked to remove"
|
||||
)
|
||||
keysToRemove += pid
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keysToRemove.forEach { pidPkgMap.remove(it) }
|
||||
}
|
||||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
}
|
||||
|
||||
override fun unload() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue