UI improvement & Add optimize function
This commit is contained in:
parent
290989b0e6
commit
4493c45025
|
|
@ -6,6 +6,7 @@
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||||
tools:ignore="QueryAllPackagesPermission" />
|
tools:ignore="QueryAllPackagesPermission" />
|
||||||
|
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".LSPApplication"
|
android:name=".LSPApplication"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package org.lsposed.lspatch.ui.page
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
|
@ -13,7 +14,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.ArrowForwardIos
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
|
@ -46,6 +46,7 @@ import org.lsposed.lspatch.ui.util.setState
|
||||||
import org.lsposed.lspatch.ui.viewmodel.ManageViewModel
|
import org.lsposed.lspatch.ui.viewmodel.ManageViewModel
|
||||||
import org.lsposed.lspatch.util.LSPPackageManager
|
import org.lsposed.lspatch.util.LSPPackageManager
|
||||||
import org.lsposed.lspatch.util.LSPPackageManager.AppInfo
|
import org.lsposed.lspatch.util.LSPPackageManager.AppInfo
|
||||||
|
import org.lsposed.lspatch.util.ShizukuApi
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
private const val TAG = "ManagePage"
|
private const val TAG = "ManagePage"
|
||||||
|
|
@ -205,6 +206,7 @@ private fun Fab() {
|
||||||
@Composable
|
@Composable
|
||||||
private fun Body() {
|
private fun Body() {
|
||||||
val viewModel = viewModel<ManageViewModel>()
|
val viewModel = viewModel<ManageViewModel>()
|
||||||
|
val snackbarHost = LocalSnackbarHost.current
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
|
@ -250,23 +252,8 @@ private fun Body() {
|
||||||
icon = LSPPackageManager.getIcon(it.first),
|
icon = LSPPackageManager.getIcon(it.first),
|
||||||
label = it.first.label,
|
label = it.first.label,
|
||||||
packageName = it.first.app.packageName,
|
packageName = it.first.app.packageName,
|
||||||
onClick = {
|
onClick = { expanded = true },
|
||||||
scope.launch {
|
onLongClick = { expanded = true },
|
||||||
scopeApp = it.first.app.packageName
|
|
||||||
val activated = ConfigManager.getModulesForApp(scopeApp).map { it.pkgName }.toSet()
|
|
||||||
navController.currentBackStackEntry!!.setState(
|
|
||||||
"selected",
|
|
||||||
SnapshotStateList<AppInfo>().apply {
|
|
||||||
LSPPackageManager.appList.filterTo(this) { activated.contains(it.app.packageName) }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
navController.navigate(PageList.SelectApps.name + "?multiSelect=true")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongClick = {
|
|
||||||
// expanded = true
|
|
||||||
},
|
|
||||||
rightIcon = { if (it.second.useManager) Icon(Icons.Filled.ArrowForwardIos, null) },
|
|
||||||
additionalContent = {
|
additionalContent = {
|
||||||
val text = buildAnnotatedString {
|
val text = buildAnnotatedString {
|
||||||
val (text, color) =
|
val (text, color) =
|
||||||
|
|
@ -284,9 +271,66 @@ private fun Body() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
||||||
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
|
if (it.second.useManager) {
|
||||||
/* TODO */
|
DropdownMenuItem(
|
||||||
|
text = { Text(stringResource(R.string.manage_module_scope)) },
|
||||||
|
onClick = {
|
||||||
|
expanded = false
|
||||||
|
scope.launch {
|
||||||
|
scopeApp = it.first.app.packageName
|
||||||
|
val activated = ConfigManager.getModulesForApp(scopeApp).map { it.pkgName }.toSet()
|
||||||
|
navController.currentBackStackEntry!!.setState(
|
||||||
|
"selected",
|
||||||
|
SnapshotStateList<AppInfo>().apply {
|
||||||
|
LSPPackageManager.appList.filterTo(this) { activated.contains(it.app.packageName) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
navController.navigate(PageList.SelectApps.name + "?multiSelect=true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val shizukuUnavailable = stringResource(R.string.shizuku_unavailable)
|
||||||
|
val optimizeSucceed = stringResource(R.string.manage_optimize_successfully)
|
||||||
|
val optimizeFailed = stringResource(R.string.manage_optimize_failed)
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(stringResource(R.string.manage_optimize)) },
|
||||||
|
onClick = {
|
||||||
|
expanded = false
|
||||||
|
if (!ShizukuApi.isPermissionGranted) {
|
||||||
|
scope.launch {
|
||||||
|
snackbarHost.showSnackbar(shizukuUnavailable)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scope.launch {
|
||||||
|
val result = ShizukuApi.performDexOptMode(it.first.app.packageName)
|
||||||
|
snackbarHost.showSnackbar(if (result) optimizeSucceed else optimizeFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val uninstallSuccessfully = stringResource(R.string.manage_uninstall_successfully)
|
||||||
|
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
|
if (it.resultCode == Activity.RESULT_OK) {
|
||||||
|
scope.launch {
|
||||||
|
LSPPackageManager.fetchAppList()
|
||||||
|
snackbarHost.showSnackbar(uninstallSuccessfully)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DropdownMenuItem(
|
||||||
|
text = { Text(stringResource(R.string.uninstall)) },
|
||||||
|
onClick = {
|
||||||
|
expanded = false
|
||||||
|
val intent = Intent(Intent.ACTION_DELETE).apply {
|
||||||
|
data = Uri.parse("package:${it.first.app.packageName}")
|
||||||
|
putExtra(Intent.EXTRA_RETURN_RESULT, true)
|
||||||
|
}
|
||||||
|
launcher.launch(intent)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,7 +359,7 @@ private fun DoPatchBody(modifier: Modifier) {
|
||||||
installing = true
|
installing = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
content = { Text(stringResource(R.string.patch_install)) }
|
content = { Text(stringResource(R.string.install)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -439,7 +439,7 @@ private fun InstallDialog(patchApp: AppInfo, onFinish: (Int, String?) -> Unit) {
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(R.string.patch_uninstall),
|
text = stringResource(R.string.uninstall),
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
@ -454,7 +454,7 @@ private fun InstallDialog(patchApp: AppInfo, onFinish: (Int, String?) -> Unit) {
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(if (installing == 1) R.string.patch_installing else R.string.patch_uninstalling),
|
text = stringResource(if (installing == 1) R.string.installing else R.string.uninstalling),
|
||||||
fontFamily = FontFamily.Serif,
|
fontFamily = FontFamily.Serif,
|
||||||
textAlign = TextAlign.Center
|
textAlign = TextAlign.Center
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -57,28 +57,28 @@ private fun TopBar() {
|
||||||
private fun KeyStore() {
|
private fun KeyStore() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var dropDownExpanded by remember { mutableStateOf(false) }
|
var dropdownExpanded by remember { mutableStateOf(false) }
|
||||||
var showDialog by remember { mutableStateOf(false) }
|
var showDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
SettingsItem(
|
SettingsItem(
|
||||||
onClick = { dropDownExpanded = !dropDownExpanded },
|
onClick = { dropdownExpanded = !dropdownExpanded },
|
||||||
icon = Icons.Outlined.Ballot,
|
icon = Icons.Outlined.Ballot,
|
||||||
title = stringResource(R.string.settings_keystore),
|
title = stringResource(R.string.settings_keystore),
|
||||||
desc = stringResource(if (MyKeyStore.useDefault) R.string.settings_keystore_default else R.string.settings_keystore_custom)
|
desc = stringResource(if (MyKeyStore.useDefault) R.string.settings_keystore_default else R.string.settings_keystore_custom)
|
||||||
)
|
)
|
||||||
DropdownMenu(expanded = dropDownExpanded, onDismissRequest = { dropDownExpanded = false }) {
|
DropdownMenu(expanded = dropdownExpanded, onDismissRequest = { dropdownExpanded = false }) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.settings_keystore_default)) },
|
text = { Text(stringResource(R.string.settings_keystore_default)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
scope.launch { MyKeyStore.reset() }
|
scope.launch { MyKeyStore.reset() }
|
||||||
dropDownExpanded = false
|
dropdownExpanded = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.settings_keystore_custom)) },
|
text = { Text(stringResource(R.string.settings_keystore_custom)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
dropDownExpanded = false
|
dropdownExpanded = false
|
||||||
showDialog = true
|
showDialog = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -107,7 +107,7 @@ private fun KeyStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = { dropDownExpanded = false; showDialog = false },
|
onDismissRequest = { dropdownExpanded = false; showDialog = false },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
content = { Text(stringResource(android.R.string.ok)) },
|
content = { Text(stringResource(android.R.string.ok)) },
|
||||||
|
|
@ -145,14 +145,14 @@ private fun KeyStore() {
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.launch { MyKeyStore.setCustom(password, alias, aliasPassword) }
|
scope.launch { MyKeyStore.setCustom(password, alias, aliasPassword) }
|
||||||
dropDownExpanded = false
|
dropdownExpanded = false
|
||||||
showDialog = false
|
showDialog = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
content = { Text(stringResource(android.R.string.cancel)) },
|
content = { Text(stringResource(android.R.string.cancel)) },
|
||||||
onClick = { dropDownExpanded = false; showDialog = false }
|
onClick = { dropdownExpanded = false; showDialog = false }
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
title = {
|
title = {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import android.content.pm.*
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.os.IInterface
|
import android.os.IInterface
|
||||||
|
import android.os.SystemProperties
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
|
@ -71,4 +72,12 @@ object ShizukuApi {
|
||||||
fun uninstallPackage(packageName: String, intentSender: IntentSender) {
|
fun uninstallPackage(packageName: String, intentSender: IntentSender) {
|
||||||
packageInstaller.uninstall(packageName, intentSender)
|
packageInstaller.uninstall(packageName, intentSender)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun performDexOptMode(packageName: String): Boolean {
|
||||||
|
return iPackageManager.performDexOptMode(
|
||||||
|
packageName,
|
||||||
|
SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false),
|
||||||
|
"verify", true, true, null
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
<resources>
|
<resources>
|
||||||
<string name="add">Add</string>
|
<string name="add">Add</string>
|
||||||
|
<string name="install">Install</string>
|
||||||
|
<string name="installing">Installing</string>
|
||||||
|
<string name="uninstall">Uninstall</string>
|
||||||
|
<string name="uninstalling">Uninstalling</string>
|
||||||
<string name="shizuku_available">Shizuku service available</string>
|
<string name="shizuku_available">Shizuku service available</string>
|
||||||
<string name="shizuku_unavailable">Shizuku service not connected</string>
|
<string name="shizuku_unavailable">Shizuku service not connected</string>
|
||||||
|
|
||||||
<string name="page_repo">Repo</string>
|
<string name="page_repo">Repo</string>
|
||||||
<string name="page_logs">Logs</string>
|
<string name="page_logs">Logs</string>
|
||||||
|
|
||||||
|
|
@ -23,6 +26,11 @@
|
||||||
<string name="page_manage">Manage</string>
|
<string name="page_manage">Manage</string>
|
||||||
<string name="manage_loading">Loading</string>
|
<string name="manage_loading">Loading</string>
|
||||||
<string name="manage_no_apps">No patched apps yet</string>
|
<string name="manage_no_apps">No patched apps yet</string>
|
||||||
|
<string name="manage_module_scope">Module scope</string>
|
||||||
|
<string name="manage_optimize">Optimize</string>
|
||||||
|
<string name="manage_optimize_successfully">Optimize successfully</string>
|
||||||
|
<string name="manage_optimize_failed">Optimize failed</string>
|
||||||
|
<string name="manage_uninstall_successfully">Uninstall successfully</string>
|
||||||
|
|
||||||
<!-- New Patch Page -->
|
<!-- New Patch Page -->
|
||||||
<string name="page_new_patch">New Patch</string>
|
<string name="page_new_patch">New Patch</string>
|
||||||
|
|
@ -47,11 +55,7 @@
|
||||||
<string name="patch_override_version_code_desc">Override the patched app\'s version code to 1\nThis allows downgrade installation in the future, and generally this will not affect the version code actually perceived by the application</string>
|
<string name="patch_override_version_code_desc">Override the patched app\'s version code to 1\nThis allows downgrade installation in the future, and generally this will not affect the version code actually perceived by the application</string>
|
||||||
<string name="patch_start">Start Patch</string>
|
<string name="patch_start">Start Patch</string>
|
||||||
<string name="patch_return">Return</string>
|
<string name="patch_return">Return</string>
|
||||||
<string name="patch_install">Install</string>
|
|
||||||
<string name="patch_installing">Installing</string>
|
|
||||||
<string name="patch_uninstall">Uninstall</string>
|
|
||||||
<string name="patch_uninstall_text">Due to different signatures, you need to uninstall the original app before installing the patched one.\nMake sure you have backed up personal data.</string>
|
<string name="patch_uninstall_text">Due to different signatures, you need to uninstall the original app before installing the patched one.\nMake sure you have backed up personal data.</string>
|
||||||
<string name="patch_uninstalling">Uninstalling</string>
|
|
||||||
<string name="patch_install_successfully">Install successfully</string>
|
<string name="patch_install_successfully">Install successfully</string>
|
||||||
<string name="patch_install_failed">Install failed</string>
|
<string name="patch_install_failed">Install failed</string>
|
||||||
<string name="patch_copy_error">Copy error</string>
|
<string name="patch_copy_error">Copy error</string>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue