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 <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"

View File

@ -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 }) {
/* 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 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
) )

View File

@ -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 = {

View File

@ -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
)
}
} }

View File

@ -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>