UI improvement & Add optimize function

This commit is contained in:
Nullptr 2022-05-31 21:55:59 +08:00
parent 290989b0e6
commit 4493c45025
No known key found for this signature in database
GPG Key ID: 0B9D02052FF536BD
6 changed files with 95 additions and 37 deletions

View File

@ -6,6 +6,7 @@
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<application
android:name=".LSPApplication"

View File

@ -2,6 +2,7 @@ package org.lsposed.lspatch.ui.page
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
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.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.ArrowForwardIos
import androidx.compose.material3.*
import androidx.compose.runtime.*
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.util.LSPPackageManager
import org.lsposed.lspatch.util.LSPPackageManager.AppInfo
import org.lsposed.lspatch.util.ShizukuApi
import java.io.IOException
private const val TAG = "ManagePage"
@ -205,6 +206,7 @@ private fun Fab() {
@Composable
private fun Body() {
val viewModel = viewModel<ManageViewModel>()
val snackbarHost = LocalSnackbarHost.current
val navController = LocalNavController.current
val scope = rememberCoroutineScope()
@ -250,23 +252,8 @@ private fun Body() {
icon = LSPPackageManager.getIcon(it.first),
label = it.first.label,
packageName = it.first.app.packageName,
onClick = {
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")
}
},
onLongClick = {
// expanded = true
},
rightIcon = { if (it.second.useManager) Icon(Icons.Filled.ArrowForwardIos, null) },
onClick = { expanded = true },
onLongClick = { expanded = true },
additionalContent = {
val text = buildAnnotatedString {
val (text, color) =
@ -284,9 +271,66 @@ private fun Body() {
)
}
)
}
DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
/* TODO */
if (it.second.useManager) {
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)
}
)
}
}
}
}

View File

@ -359,7 +359,7 @@ private fun DoPatchBody(modifier: Modifier) {
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 = {
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.patch_uninstall),
text = stringResource(R.string.uninstall),
textAlign = TextAlign.Center
)
},
@ -454,7 +454,7 @@ private fun InstallDialog(patchApp: AppInfo, onFinish: (Int, String?) -> Unit) {
title = {
Text(
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,
textAlign = TextAlign.Center
)

View File

@ -57,28 +57,28 @@ private fun TopBar() {
private fun KeyStore() {
val context = LocalContext.current
val scope = rememberCoroutineScope()
var dropDownExpanded by remember { mutableStateOf(false) }
var dropdownExpanded by remember { mutableStateOf(false) }
var showDialog by remember { mutableStateOf(false) }
Box {
SettingsItem(
onClick = { dropDownExpanded = !dropDownExpanded },
onClick = { dropdownExpanded = !dropdownExpanded },
icon = Icons.Outlined.Ballot,
title = stringResource(R.string.settings_keystore),
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(
text = { Text(stringResource(R.string.settings_keystore_default)) },
onClick = {
scope.launch { MyKeyStore.reset() }
dropDownExpanded = false
dropdownExpanded = false
}
)
DropdownMenuItem(
text = { Text(stringResource(R.string.settings_keystore_custom)) },
onClick = {
dropDownExpanded = false
dropdownExpanded = false
showDialog = true
}
)
@ -107,7 +107,7 @@ private fun KeyStore() {
}
AlertDialog(
onDismissRequest = { dropDownExpanded = false; showDialog = false },
onDismissRequest = { dropdownExpanded = false; showDialog = false },
confirmButton = {
TextButton(
content = { Text(stringResource(android.R.string.ok)) },
@ -145,14 +145,14 @@ private fun KeyStore() {
}
scope.launch { MyKeyStore.setCustom(password, alias, aliasPassword) }
dropDownExpanded = false
dropdownExpanded = false
showDialog = false
})
},
dismissButton = {
TextButton(
content = { Text(stringResource(android.R.string.cancel)) },
onClick = { dropDownExpanded = false; showDialog = false }
onClick = { dropdownExpanded = false; showDialog = false }
)
},
title = {

View File

@ -5,6 +5,7 @@ import android.content.pm.*
import android.os.Build
import android.os.IBinder
import android.os.IInterface
import android.os.SystemProperties
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@ -71,4 +72,12 @@ object ShizukuApi {
fun uninstallPackage(packageName: String, intentSender: IntentSender) {
packageInstaller.uninstall(packageName, intentSender)
}
fun performDexOptMode(packageName: String): Boolean {
return iPackageManager.performDexOptMode(
packageName,
SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false),
"verify", true, true, null
)
}
}

View File

@ -1,8 +1,11 @@
<resources>
<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_unavailable">Shizuku service not connected</string>
<string name="page_repo">Repo</string>
<string name="page_logs">Logs</string>
@ -23,6 +26,11 @@
<string name="page_manage">Manage</string>
<string name="manage_loading">Loading</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 -->
<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_start">Start Patch</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_uninstalling">Uninstalling</string>
<string name="patch_install_successfully">Install successfully</string>
<string name="patch_install_failed">Install failed</string>
<string name="patch_copy_error">Copy error</string>