Shizuku: Dex2Oat usually needs root to run
This commit is contained in:
parent
fced5612fb
commit
798d98c089
|
|
@ -42,6 +42,15 @@ object ShizukuApi {
|
||||||
var isBinderAvailable = false
|
var isBinderAvailable = false
|
||||||
var isPermissionGranted by mutableStateOf(false)
|
var isPermissionGranted by mutableStateOf(false)
|
||||||
|
|
||||||
|
fun getBackendUidOrNull(): Int? {
|
||||||
|
if (!isBinderAvailable || !isPermissionGranted) return null
|
||||||
|
return runCatching { Shizuku.getUid() }
|
||||||
|
.getOrNull()
|
||||||
|
?.takeIf { it >= 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isRootBackend(): Boolean = getBackendUidOrNull() == 0
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
Shizuku.addBinderReceivedListenerSticky {
|
Shizuku.addBinderReceivedListenerSticky {
|
||||||
isBinderAvailable = true
|
isBinderAvailable = true
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,16 @@ fun AppManageBody(
|
||||||
is ProcessingState.Idle -> Unit
|
is ProcessingState.Idle -> Unit
|
||||||
is ProcessingState.Processing -> LoadingDialog()
|
is ProcessingState.Processing -> LoadingDialog()
|
||||||
is ProcessingState.Done -> {
|
is ProcessingState.Done -> {
|
||||||
val it = viewModel.optimizeState as ProcessingState.Done
|
val it = viewModel.optimizeState as ProcessingState.Done<AppManageViewModel.OptimizeResult>
|
||||||
val optimizeSucceed = stringResource(R.string.manage_optimize_successfully)
|
val optimizeSucceed = stringResource(R.string.manage_optimize_successfully)
|
||||||
val optimizeFailed = stringResource(R.string.manage_optimize_failed)
|
val optimizeFailed = stringResource(R.string.manage_optimize_failed)
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
snackbarHost.showSnackbar(if (it.result) optimizeSucceed else optimizeFailed)
|
val message = if (it.result.success) {
|
||||||
|
optimizeSucceed
|
||||||
|
} else {
|
||||||
|
it.result.messageRes?.let { resId -> lspApp.getString(resId) } ?: optimizeFailed
|
||||||
|
}
|
||||||
|
snackbarHost.showSnackbar(message)
|
||||||
viewModel.dispatch(AppManageViewModel.ViewAction.ClearOptimizeResult)
|
viewModel.dispatch(AppManageViewModel.ViewAction.ClearOptimizeResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.lsposed.npatch.Patcher
|
import org.lsposed.npatch.Patcher
|
||||||
|
import org.lsposed.npatch.R
|
||||||
import org.lsposed.npatch.lspApp
|
import org.lsposed.npatch.lspApp
|
||||||
import org.lsposed.npatch.share.Constants
|
import org.lsposed.npatch.share.Constants
|
||||||
import org.lsposed.npatch.share.PatchConfig
|
import org.lsposed.npatch.share.PatchConfig
|
||||||
|
|
@ -45,6 +46,11 @@ class AppManageViewModel : ViewModel() {
|
||||||
object Refresh : ViewAction()
|
object Refresh : ViewAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class OptimizeResult(
|
||||||
|
val success: Boolean,
|
||||||
|
val messageRes: Int? = null
|
||||||
|
)
|
||||||
|
|
||||||
// 手動管理狀態,避免實時響應系統廣播導致列表跳動
|
// 手動管理狀態,避免實時響應系統廣播導致列表跳動
|
||||||
var appList: List<Pair<AppInfo, PatchConfig>> by mutableStateOf(emptyList())
|
var appList: List<Pair<AppInfo, PatchConfig>> by mutableStateOf(emptyList())
|
||||||
private set
|
private set
|
||||||
|
|
@ -55,7 +61,7 @@ class AppManageViewModel : ViewModel() {
|
||||||
var updateLoaderState: ProcessingState<Result<Unit>> by mutableStateOf(ProcessingState.Idle)
|
var updateLoaderState: ProcessingState<Result<Unit>> by mutableStateOf(ProcessingState.Idle)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var optimizeState: ProcessingState<Boolean> by mutableStateOf(ProcessingState.Idle)
|
var optimizeState: ProcessingState<OptimizeResult> by mutableStateOf(ProcessingState.Idle)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private val logger = object : Logger() {
|
private val logger = object : Logger() {
|
||||||
|
|
@ -195,7 +201,12 @@ class AppManageViewModel : ViewModel() {
|
||||||
Log.i(TAG, "Perform optimize for ${appInfo.app.packageName}")
|
Log.i(TAG, "Perform optimize for ${appInfo.app.packageName}")
|
||||||
optimizeState = ProcessingState.Processing
|
optimizeState = ProcessingState.Processing
|
||||||
val result = withContext(Dispatchers.IO) {
|
val result = withContext(Dispatchers.IO) {
|
||||||
ShizukuApi.performDexOptMode(appInfo.app.packageName)
|
if (!ShizukuApi.isRootBackend()) {
|
||||||
|
Log.w(TAG, "Optimize refused: Shizuku backend is not root, uid=${ShizukuApi.getBackendUidOrNull()}")
|
||||||
|
OptimizeResult(success = false, messageRes = R.string.manage_optimize_permission_denied)
|
||||||
|
} else {
|
||||||
|
OptimizeResult(success = ShizukuApi.performDexOptMode(appInfo.app.packageName))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
optimizeState = ProcessingState.Done(result)
|
optimizeState = ProcessingState.Done(result)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
<string name="manage_optimize">优化</string>
|
<string name="manage_optimize">优化</string>
|
||||||
<string name="manage_optimize_successfully">优化成功</string>
|
<string name="manage_optimize_successfully">优化成功</string>
|
||||||
<string name="manage_optimize_failed">优化失败</string>
|
<string name="manage_optimize_failed">优化失败</string>
|
||||||
|
<string name="manage_optimize_permission_denied">权限不足:优化功能要求 Shizuku 运行在 Root 特权下</string>
|
||||||
<string name="manage_uninstall_successfully">卸载成功</string>
|
<string name="manage_uninstall_successfully">卸载成功</string>
|
||||||
<string name="manage_no_modules">尚无模块</string>
|
<string name="manage_no_modules">尚无模块</string>
|
||||||
<string name="manage_module_settings">模块设置</string>
|
<string name="manage_module_settings">模块设置</string>
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
<string name="manage_optimize">Optimize</string>
|
<string name="manage_optimize">Optimize</string>
|
||||||
<string name="manage_optimize_successfully">Optimize successfully</string>
|
<string name="manage_optimize_successfully">Optimize successfully</string>
|
||||||
<string name="manage_optimize_failed">Optimize failed</string>
|
<string name="manage_optimize_failed">Optimize failed</string>
|
||||||
|
<string name="manage_optimize_permission_denied">Insufficient privilege: optimize requires Shizuku running as root</string>
|
||||||
<string name="manage_uninstall_successfully">Uninstall successfully</string>
|
<string name="manage_uninstall_successfully">Uninstall successfully</string>
|
||||||
<string name="manage_no_modules">No modules yet</string>
|
<string name="manage_no_modules">No modules yet</string>
|
||||||
<string name="manage_module_settings">Module settings</string>
|
<string name="manage_module_settings">Module settings</string>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue