Add fallback for system getInstalledPackages
This commit is contained in:
@@ -61,7 +61,13 @@ class AppChangeReceiver : BroadcastReceiver() {
|
|||||||
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
||||||
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
||||||
}
|
}
|
||||||
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags)
|
val retryFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES
|
||||||
|
}
|
||||||
|
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags, retryFlags)
|
||||||
val chinaApps = mutableSetOf<String>()
|
val chinaApps = mutableSetOf<String>()
|
||||||
for (packageInfo in installedPackages) {
|
for (packageInfo in installedPackages) {
|
||||||
if (PerAppProxyScanner.scanChinaPackage(packageInfo)) {
|
if (PerAppProxyScanner.scanChinaPackage(packageInfo)) {
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||||||
import androidx.compose.material.icons.filled.Clear
|
import androidx.compose.material.icons.filled.Clear
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.ContentPaste
|
import androidx.compose.material.icons.filled.ContentPaste
|
||||||
import androidx.compose.material.icons.filled.ExpandLess
|
|
||||||
import androidx.compose.material.icons.filled.ExpandMore
|
|
||||||
import androidx.compose.material.icons.filled.FilterList
|
import androidx.compose.material.icons.filled.FilterList
|
||||||
import androidx.compose.material.icons.filled.ManageSearch
|
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material.icons.filled.Search
|
import androidx.compose.material.icons.filled.Search
|
||||||
import androidx.compose.material.icons.filled.SelectAll
|
import androidx.compose.material.icons.filled.SelectAll
|
||||||
@@ -63,7 +60,6 @@ import io.nekohasekai.sfa.compose.shared.AppSelectionCard
|
|||||||
import io.nekohasekai.sfa.compose.shared.PackageCache
|
import io.nekohasekai.sfa.compose.shared.PackageCache
|
||||||
import io.nekohasekai.sfa.compose.shared.SortMode
|
import io.nekohasekai.sfa.compose.shared.SortMode
|
||||||
import io.nekohasekai.sfa.compose.shared.buildDisplayPackages
|
import io.nekohasekai.sfa.compose.shared.buildDisplayPackages
|
||||||
import io.nekohasekai.sfa.compose.screen.profileoverride.PerAppProxyScanner
|
|
||||||
import io.nekohasekai.sfa.utils.PrivilegeSettingsClient
|
import io.nekohasekai.sfa.utils.PrivilegeSettingsClient
|
||||||
import io.nekohasekai.sfa.vendor.PackageQueryManager
|
import io.nekohasekai.sfa.vendor.PackageQueryManager
|
||||||
import io.nekohasekai.sfa.vendor.PrivilegedAccessRequiredException
|
import io.nekohasekai.sfa.vendor.PrivilegedAccessRequiredException
|
||||||
@@ -263,49 +259,19 @@ fun PrivilegeSettingsManageScreen(onBack: () -> Unit) {
|
|||||||
postSaveSelectedApplications(newSelected)
|
postSaveSelectedApplications(newSelected)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startScanChinaApps() {
|
|
||||||
val scanPackages = currentPackages.toList()
|
|
||||||
if (scanPackages.isEmpty() || isLoading) return
|
|
||||||
isLoading = true
|
|
||||||
coroutineScope.launch {
|
|
||||||
val foundUids =
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
scanPackages.mapNotNull { packageCache ->
|
|
||||||
if (PerAppProxyScanner.scanChinaPackage(packageCache.info)) {
|
|
||||||
if (getRiskCategory(packageCache) != RiskCategory.NONE) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
packageCache.uid
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}.toSet()
|
|
||||||
}
|
|
||||||
if (foundUids.isNotEmpty()) {
|
|
||||||
postSaveSelectedApplications(selectedUids + foundUids)
|
|
||||||
}
|
|
||||||
isLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
isLoading = true
|
isLoading = true
|
||||||
val packageManagerFlags =
|
val packageManagerFlags =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
PackageManager.GET_PERMISSIONS or PackageManager.MATCH_UNINSTALLED_PACKAGES or
|
PackageManager.GET_PERMISSIONS or PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
|
||||||
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
|
||||||
} else {
|
} else {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
PackageManager.GET_PERMISSIONS or PackageManager.GET_UNINSTALLED_PACKAGES or
|
PackageManager.GET_PERMISSIONS or PackageManager.GET_UNINSTALLED_PACKAGES
|
||||||
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
|
||||||
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
|
||||||
}
|
}
|
||||||
val loadResult =
|
val loadResult =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags)
|
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags, packageManagerFlags)
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
val packageCaches =
|
val packageCaches =
|
||||||
installedPackages.mapNotNull { packageInfo ->
|
installedPackages.mapNotNull { packageInfo ->
|
||||||
@@ -424,9 +390,6 @@ fun PrivilegeSettingsManageScreen(onBack: () -> Unit) {
|
|||||||
hideDisabledApps = !hideDisabledApps
|
hideDisabledApps = !hideDisabledApps
|
||||||
applyFilter()
|
applyFilter()
|
||||||
},
|
},
|
||||||
onScanChinaApps = {
|
|
||||||
startScanChinaApps()
|
|
||||||
},
|
|
||||||
onSelectAll = {
|
onSelectAll = {
|
||||||
val newSelected = currentPackages.map { it.uid }.toSet()
|
val newSelected = currentPackages.map { it.uid }.toSet()
|
||||||
postSaveSelectedApplications(newSelected)
|
postSaveSelectedApplications(newSelected)
|
||||||
@@ -594,7 +557,6 @@ private fun PrivilegeSettingsMenus(
|
|||||||
onHideSystemAppsToggle: () -> Unit,
|
onHideSystemAppsToggle: () -> Unit,
|
||||||
onHideOfflineAppsToggle: () -> Unit,
|
onHideOfflineAppsToggle: () -> Unit,
|
||||||
onHideDisabledAppsToggle: () -> Unit,
|
onHideDisabledAppsToggle: () -> Unit,
|
||||||
onScanChinaApps: () -> Unit,
|
|
||||||
onSelectAll: () -> Unit,
|
onSelectAll: () -> Unit,
|
||||||
onDeselectAll: () -> Unit,
|
onDeselectAll: () -> Unit,
|
||||||
onImport: () -> Unit,
|
onImport: () -> Unit,
|
||||||
@@ -603,7 +565,6 @@ private fun PrivilegeSettingsMenus(
|
|||||||
var showMainMenu by remember { mutableStateOf(false) }
|
var showMainMenu by remember { mutableStateOf(false) }
|
||||||
var showSortMenu by remember { mutableStateOf(false) }
|
var showSortMenu by remember { mutableStateOf(false) }
|
||||||
var showFilterMenu by remember { mutableStateOf(false) }
|
var showFilterMenu by remember { mutableStateOf(false) }
|
||||||
var showScanMenu by remember { mutableStateOf(false) }
|
|
||||||
var showSelectMenu by remember { mutableStateOf(false) }
|
var showSelectMenu by remember { mutableStateOf(false) }
|
||||||
var showBackupMenu by remember { mutableStateOf(false) }
|
var showBackupMenu by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
@@ -617,7 +578,6 @@ private fun PrivilegeSettingsMenus(
|
|||||||
showMainMenu = false
|
showMainMenu = false
|
||||||
showSortMenu = false
|
showSortMenu = false
|
||||||
showFilterMenu = false
|
showFilterMenu = false
|
||||||
showScanMenu = false
|
|
||||||
showSelectMenu = false
|
showSelectMenu = false
|
||||||
showBackupMenu = false
|
showBackupMenu = false
|
||||||
},
|
},
|
||||||
@@ -733,48 +693,6 @@ private fun PrivilegeSettingsMenus(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(stringResource(R.string.per_app_proxy_scan)) },
|
|
||||||
onClick = { showScanMenu = !showScanMenu },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.ManageSearch,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
trailingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector =
|
|
||||||
if (showScanMenu) {
|
|
||||||
Icons.Default.ExpandLess
|
|
||||||
} else {
|
|
||||||
Icons.Default.ExpandMore
|
|
||||||
},
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if (showScanMenu) {
|
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(stringResource(R.string.per_app_proxy_scan_china_apps)) },
|
|
||||||
onClick = {
|
|
||||||
onScanChinaApps()
|
|
||||||
showMainMenu = false
|
|
||||||
showScanMenu = false
|
|
||||||
},
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.ManageSearch,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.padding(start = 24.dp),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.per_app_proxy_filter)) },
|
text = { Text(stringResource(R.string.per_app_proxy_filter)) },
|
||||||
onClick = { showFilterMenu = !showFilterMenu },
|
onClick = { showFilterMenu = !showFilterMenu },
|
||||||
|
|||||||
@@ -242,6 +242,13 @@ fun PerAppProxyScreen(onBack: () -> Unit) {
|
|||||||
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
||||||
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
||||||
}
|
}
|
||||||
|
val retryFlags =
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES
|
||||||
|
}
|
||||||
val loadResult =
|
val loadResult =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
@@ -251,7 +258,7 @@ fun PerAppProxyScreen(onBack: () -> Unit) {
|
|||||||
} else {
|
} else {
|
||||||
Settings.PER_APP_PROXY_EXCLUDE
|
Settings.PER_APP_PROXY_EXCLUDE
|
||||||
}
|
}
|
||||||
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags)
|
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags, retryFlags)
|
||||||
val packageManager = context.packageManager
|
val packageManager = context.packageManager
|
||||||
val packageCaches =
|
val packageCaches =
|
||||||
installedPackages.mapNotNull { packageInfo ->
|
installedPackages.mapNotNull { packageInfo ->
|
||||||
|
|||||||
@@ -704,8 +704,14 @@ private suspend fun scanAllChinaApps(): Set<String> = withContext(Dispatchers.De
|
|||||||
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
PackageManager.GET_ACTIVITIES or PackageManager.GET_SERVICES or
|
||||||
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
PackageManager.GET_RECEIVERS or PackageManager.GET_PROVIDERS
|
||||||
}
|
}
|
||||||
|
val retryFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
PackageManager.GET_UNINSTALLED_PACKAGES
|
||||||
|
}
|
||||||
|
|
||||||
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags)
|
val installedPackages = PackageQueryManager.getInstalledPackages(packageManagerFlags, retryFlags)
|
||||||
|
|
||||||
val chinaApps = mutableSetOf<String>()
|
val chinaApps = mutableSetOf<String>()
|
||||||
installedPackages.map { packageInfo ->
|
installedPackages.map { packageInfo ->
|
||||||
|
|||||||
@@ -52,22 +52,33 @@ object PackageQueryManager {
|
|||||||
_queryMode.value = mode
|
_queryMode.value = mode
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getInstalledPackages(flags: Int): List<PackageInfo> {
|
suspend fun getInstalledPackages(flags: Int, retryFlags: Int): List<PackageInfo> {
|
||||||
return when (val s = strategy) {
|
return when (val s = strategy) {
|
||||||
is PackageQueryStrategy.ForcedRoot -> RootClient.getInstalledPackages(flags)
|
is PackageQueryStrategy.ForcedRoot -> RootClient.getInstalledPackages(flags)
|
||||||
is PackageQueryStrategy.UserSelected -> RootClient.getInstalledPackages(flags)
|
is PackageQueryStrategy.UserSelected -> RootClient.getInstalledPackages(flags)
|
||||||
is PackageQueryStrategy.Direct -> getPackagesViaPackageManager(flags)
|
is PackageQueryStrategy.Direct -> getPackagesViaPackageManager(flags, retryFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPackagesViaPackageManager(flags: Int): List<PackageInfo> {
|
private fun getPackagesViaPackageManager(flags: Int, retryFlags: Int): List<PackageInfo> {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
return try {
|
||||||
Application.packageManager.getInstalledPackages(
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
PackageManager.PackageInfoFlags.of(flags.toLong())
|
Application.packageManager.getInstalledPackages(
|
||||||
)
|
PackageManager.PackageInfoFlags.of(flags.toLong())
|
||||||
} else {
|
)
|
||||||
@Suppress("DEPRECATION")
|
} else {
|
||||||
Application.packageManager.getInstalledPackages(flags)
|
@Suppress("DEPRECATION")
|
||||||
|
Application.packageManager.getInstalledPackages(flags)
|
||||||
|
}
|
||||||
|
} catch (_: RuntimeException) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
Application.packageManager.getInstalledPackages(
|
||||||
|
PackageManager.PackageInfoFlags.of(retryFlags.toLong())
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
Application.packageManager.getInstalledPackages(retryFlags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,25 +60,36 @@ object PackageQueryManager {
|
|||||||
_queryMode.value = mode
|
_queryMode.value = mode
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getInstalledPackages(flags: Int): List<PackageInfo> {
|
suspend fun getInstalledPackages(flags: Int, retryFlags: Int): List<PackageInfo> {
|
||||||
return when (val s = strategy) {
|
return when (val s = strategy) {
|
||||||
is PackageQueryStrategy.ForcedRoot -> RootClient.getInstalledPackages(flags)
|
is PackageQueryStrategy.ForcedRoot -> RootClient.getInstalledPackages(flags)
|
||||||
is PackageQueryStrategy.UserSelected -> when (s.mode) {
|
is PackageQueryStrategy.UserSelected -> when (s.mode) {
|
||||||
Settings.PACKAGE_QUERY_MODE_ROOT -> RootClient.getInstalledPackages(flags)
|
Settings.PACKAGE_QUERY_MODE_ROOT -> RootClient.getInstalledPackages(flags)
|
||||||
else -> ShizukuPackageManager.getInstalledPackages(flags)
|
else -> ShizukuPackageManager.getInstalledPackages(flags)
|
||||||
}
|
}
|
||||||
is PackageQueryStrategy.Direct -> getPackagesViaPackageManager(flags)
|
is PackageQueryStrategy.Direct -> getPackagesViaPackageManager(flags, retryFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPackagesViaPackageManager(flags: Int): List<PackageInfo> {
|
private fun getPackagesViaPackageManager(flags: Int, retryFlags: Int): List<PackageInfo> {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
return try {
|
||||||
Application.packageManager.getInstalledPackages(
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
PackageManager.PackageInfoFlags.of(flags.toLong())
|
Application.packageManager.getInstalledPackages(
|
||||||
)
|
PackageManager.PackageInfoFlags.of(flags.toLong())
|
||||||
} else {
|
)
|
||||||
@Suppress("DEPRECATION")
|
} else {
|
||||||
Application.packageManager.getInstalledPackages(flags)
|
@Suppress("DEPRECATION")
|
||||||
|
Application.packageManager.getInstalledPackages(flags)
|
||||||
|
}
|
||||||
|
} catch (_: RuntimeException) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
Application.packageManager.getInstalledPackages(
|
||||||
|
PackageManager.PackageInfoFlags.of(retryFlags.toLong())
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
Application.packageManager.getInstalledPackages(retryFlags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user