Skip to content

Commit

Permalink
feat(shizuku): add support for Sui
Browse files Browse the repository at this point in the history
  • Loading branch information
aliernfrog authored Sep 14, 2024
1 parent 09faf62 commit 0416882
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.compose.material.icons.filled.RestartAlt
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
Expand All @@ -32,6 +33,7 @@ import com.aliernfrog.pftool.R
import com.aliernfrog.pftool.enum.ShizukuStatus
import com.aliernfrog.pftool.ui.component.ButtonIcon
import com.aliernfrog.pftool.ui.component.CardWithActions
import com.aliernfrog.pftool.ui.component.FadeVisibility
import com.aliernfrog.pftool.ui.viewmodel.ShizukuViewModel
import com.aliernfrog.pftool.util.staticutil.GeneralUtil
import org.koin.androidx.compose.koinViewModel
Expand Down Expand Up @@ -77,7 +79,7 @@ fun ShizukuPermissionsScreen(
.align(Alignment.CenterHorizontally)
.padding(16.dp),
buttons = {
TextButton(
if (shizukuViewModel.managerInstalled) TextButton(
onClick = {
shizukuViewModel.launchManager(context)
}
Expand Down Expand Up @@ -111,7 +113,7 @@ private fun ShizukuSetupGuide(
val context = LocalContext.current
val uriHandler = LocalUriHandler.current

if (shizukuViewModel.installed) Text(
if (shizukuViewModel.managerInstalled) Text(
text = stringResource(R.string.permissions_shizuku_introduction),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.padding(8.dp)
Expand All @@ -134,11 +136,11 @@ private fun ShizukuSetupGuide(
ShizukuStatus.UNKNOWN, ShizukuStatus.NOT_INSTALLED -> {
Button(
onClick = {
uriHandler.openUri("https://play.google.com/store/apps/details?id=moe.shizuku.privileged.api")
shizukuViewModel.launchManager(context)
}
) {
ButtonIcon(rememberVectorPainter(Icons.AutoMirrored.Filled.OpenInNew))
Text(stringResource(R.string.permissions_shizuku_install_install))
Text(stringResource(R.string.permissions_shizuku_installShizuku))
}
}
ShizukuStatus.WAITING_FOR_BINDER -> {
Expand Down Expand Up @@ -175,5 +177,40 @@ private fun ShizukuSetupGuide(
}
}

FadeVisibility(
shizukuViewModel.deviceRooted && shizukuViewModel.status != ShizukuStatus.UNAUTHORIZED
) {
CardWithActions(
title = stringResource(R.string.permissions_shizuku_rooted),
buttons = {
OutlinedButton(
onClick = {
uriHandler.openUri(ShizukuViewModel.SUI_GITHUB)
}
) {
ButtonIcon(rememberVectorPainter(Icons.AutoMirrored.Filled.OpenInNew))
Text(stringResource(R.string.permissions_shizuku_sui))
}
Button(
onClick = {
shizukuViewModel.launchManager(context)
}
) {
ButtonIcon(rememberVectorPainter(Icons.AutoMirrored.Filled.OpenInNew))
Text(stringResource(
if (shizukuViewModel.managerInstalled) R.string.permissions_shizuku_openShizuku
else R.string.permissions_shizuku_installShizuku
))
}
},
modifier = Modifier.fillMaxWidth().padding(8.dp)
) {
Text(
text = stringResource(R.string.permissions_shizuku_rooted_description),
style = MaterialTheme.typography.bodyMedium
)
}
}

Spacer(Modifier.navigationBarsPadding())
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package com.aliernfrog.pftool.ui.viewmodel

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager
import android.net.Uri
import android.os.IBinder
import android.util.Log
import androidx.compose.material.icons.Icons
Expand All @@ -26,7 +28,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import rikka.shizuku.Shizuku

import java.io.File

class ShizukuViewModel(
val prefs: PreferenceManager,
Expand All @@ -35,11 +37,16 @@ class ShizukuViewModel(
) : ViewModel() {
companion object {
const val SHIZUKU_PACKAGE = "moe.shizuku.privileged.api"
const val SHIZUKU_PLAY_STORE = "https://play.google.com/store/apps/details?id=moe.shizuku.privileged.api"
const val SUI_GITHUB = "https://github.com/RikkaApps/Sui"
}

var status by mutableStateOf(ShizukuStatus.UNKNOWN)
val installed: Boolean
val managerInstalled: Boolean
get() = status != ShizukuStatus.NOT_INSTALLED && status != ShizukuStatus.UNKNOWN
val deviceRooted = System.getenv("PATH")?.split(":")?.any { path ->
File(path, "su").canExecute()
} ?: false

var fileService: IFileService? = null
var fileServiceRunning by mutableStateOf(false)
Expand All @@ -60,7 +67,7 @@ class ShizukuViewModel(
private val userServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, binder: IBinder) {
val shizukuNeverLoad = prefs.shizukuNeverLoad.value
Log.d(TAG, "user service connected, shizukuNeverLoad ${shizukuNeverLoad}")
Log.d(TAG, "user service connected, shizukuNeverLoad: $shizukuNeverLoad")
if (shizukuNeverLoad) return
fileService = IFileService.Stub.asInterface(binder)
fileServiceRunning = true
Expand Down Expand Up @@ -90,13 +97,17 @@ class ShizukuViewModel(
Shizuku.addBinderReceivedListener(binderReceivedListener)
Shizuku.addBinderDeadListener(binderDeadListener)
Shizuku.addRequestPermissionResultListener(permissionResultListener)
checkAvailability(context)
}

fun launchManager(context: Context) {
try {
context.startActivity(
if (managerInstalled) context.startActivity(
context.packageManager.getLaunchIntentForPackage(SHIZUKU_PACKAGE)
)
) else {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(SHIZUKU_PLAY_STORE))
context.startActivity(intent)
}
} catch (e: Exception) {
Log.e(TAG, "ShizukuViewModel/launchManager: failed to start activity ", e)
topToastState.showErrorToast()
Expand All @@ -105,14 +116,13 @@ class ShizukuViewModel(

fun checkAvailability(context: Context): ShizukuStatus {
status = try {
if (!isInstalled(context)) ShizukuStatus.NOT_INSTALLED
else if (!Shizuku.pingBinder()) ShizukuStatus.WAITING_FOR_BINDER
else {
if (Shizuku.pingBinder()) {
if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) ShizukuStatus.AVAILABLE
else ShizukuStatus.UNAUTHORIZED
}
} else if (!isManagerInstalled(context)) ShizukuStatus.NOT_INSTALLED
else ShizukuStatus.WAITING_FOR_BINDER
} catch (e: Exception) {
Log.e(TAG, "updateStatus: ", e)
Log.e(TAG, "ShizukuViewModel/checkAvailability: failed to determine status", e)
ShizukuStatus.UNKNOWN
}
if (status == ShizukuStatus.AVAILABLE && !fileServiceRunning) {
Expand All @@ -125,13 +135,10 @@ class ShizukuViewModel(
return status
}

private fun isInstalled(context: Context): Boolean {
return try {
context.packageManager.getPackageInfo(SHIZUKU_PACKAGE, 0) != null
} catch (e: Exception) {
Log.e(TAG, "isInstalled: ", e)
false
}
private fun isManagerInstalled(context: Context) = try {
context.packageManager.getPackageInfo(SHIZUKU_PACKAGE, 0) != null
} catch (_: Exception) {
false
}

override fun onCleared() {
Expand Down
9 changes: 6 additions & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@
<string name="permissions_exportedMaps_recommended">PF Tool used this folder in older versions, choose this folder if you want to access maps you have exported before</string>
<string name="permissions_shizuku_introduction">Shizuku is an app which lets other apps use shell permissions by making use of wireless debugging.\nShizuku mode can be disabled from Settings > Storage > Storage access type</string>
<string name="permissions_shizuku_openShizuku">Open Shizuku</string>
<string name="permissions_shizuku_installShizuku">Install Shizuku</string>
<string name="permissions_shizuku_install_title">Install Shizuku to get started</string>
<string name="permissions_shizuku_install_install">Install</string>
<string name="permissions_shizuku_notRunning">Shizuku is not running</string>
<string name="permissions_shizuku_notRunning_description">Start Shizuku service to proceed</string>
<string name="permissions_shizuku_permission">Permission needed</string>
<string name="permissions_shizuku_permission_description">PF Tool does not have permissions to use Shizuku</string>
<string name="permissions_shizuku_permission_grant">Grant permission</string>
<string name="permissions_shizuku_rooted">Start Shizuku automatically</string>
<string name="permissions_shizuku_rooted_description">On rooted devices, you can set Shizuku to start automatically when your device boots up, you can find this option in Shizuku\nAlternatively, you can use Shizuku\'s Magisk module \"Sui\" which works similarly</string>
<string name="permissions_shizuku_sui">Sui</string>
<string name="permissions_shizuku_waitingService">Waiting for file service..</string>
<string name="permissions_shizuku_waitingService_timedOut">Taking long? Try restarting PF Tool</string>
<string name="permissions_shizuku_waitingService_timedOut_restart">Restart</string>
Expand Down Expand Up @@ -142,8 +145,8 @@
<string name="settings_storage_storageAccessType">Storage access type</string>
<string name="settings_storage_storageAccessType_saf">Scoped storage</string>
<string name="settings_storage_storageAccessType_saf_description">Only access the directories PF Tool needs</string>
<string name="settings_storage_storageAccessType_shizuku">Shizuku</string>
<string name="settings_storage_storageAccessType_shizuku_description">Use Shizuku to access storage</string>
<string name="settings_storage_storageAccessType_shizuku">Shizuku/Sui</string>
<string name="settings_storage_storageAccessType_shizuku_description">Use Shizuku or Sui to access storage</string>
<string name="settings_storage_storageAccessType_allFiles">All files access (legacy)</string>
<string name="settings_storage_storageAccessType_allFiles_description">Access all files, this may be easier to setup</string>
<string name="settings_storage_folders">Folders</string>
Expand Down

0 comments on commit 0416882

Please sign in to comment.