Skip to content

Commit

Permalink
manager: get application with pms and remove libsu's root services
Browse files Browse the repository at this point in the history
libsu uses Android's native IPC mechanism, binder, for communication between root service and the main application process.
However, some OEMs' dirty hack of framework code made it unstable. Like #283, it made libart crash. No app loaded.

Signed-off-by: GarfieldHan <[email protected]>
  • Loading branch information
pomelohan committed Mar 14, 2024
1 parent 87fae11 commit e2daeb9
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 130 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

<application
android:name=".APApplication"
Expand Down
9 changes: 0 additions & 9 deletions app/src/main/aidl/me/bmax/apatch/IAPRootService.aidl

This file was deleted.

72 changes: 0 additions & 72 deletions app/src/main/java/me/bmax/apatch/services/RootServices.java

This file was deleted.

4 changes: 3 additions & 1 deletion app/src/main/java/me/bmax/apatch/ui/screen/SuperUser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import dev.utils.app.AppUtils.getPackageManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
Expand All @@ -37,6 +38,7 @@ import me.bmax.apatch.ui.component.SearchAppBar
import me.bmax.apatch.ui.viewmodel.SuperUserViewModel
import me.bmax.apatch.util.PkgConfig

private val pm = getPackageManager()

@OptIn(ExperimentalMaterialApi::class)
@Destination
Expand Down Expand Up @@ -143,7 +145,7 @@ private fun AppItem(
leadingContent = {
AsyncImage(
model = ImageRequest.Builder(LocalContext.current)
.data(app.packageInfo)
.data(app.applicationInfo.loadIcon(pm))
.crossfade(true)
.build(),
contentDescription = app.label,
Expand Down
62 changes: 14 additions & 48 deletions app/src/main/java/me/bmax/apatch/ui/viewmodel/SuperUserViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.IBinder
import android.os.Parcelable
import android.util.Log
Expand All @@ -14,13 +15,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import com.topjohnwu.superuser.Shell
import dev.utils.app.AppUtils.getPackageManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.parcelize.Parcelize
import me.bmax.apatch.IAPRootService
import me.bmax.apatch.Natives
import me.bmax.apatch.apApp
import me.bmax.apatch.services.RootServices
import me.bmax.apatch.util.APatchCli
import me.bmax.apatch.util.HanziToPinyin
import me.bmax.apatch.util.PkgConfig
Expand All @@ -41,13 +41,13 @@ class SuperUserViewModel : ViewModel() {
@Parcelize
data class AppInfo(
val label: String,
val packageInfo: PackageInfo,
val applicationInfo: ApplicationInfo,
val config: PkgConfig.Config
) : Parcelable {
val packageName: String
get() = packageInfo.packageName
get() = applicationInfo.packageName
val uid: Int
get() = packageInfo.applicationInfo.uid
get() = applicationInfo.uid
}

var search by mutableStateOf("")
Expand Down Expand Up @@ -75,50 +75,17 @@ class SuperUserViewModel : ViewModel() {
HanziToPinyin.getInstance().toPinyinString(it.label).contains(search.lowercase())
}.filter {
it.uid == 2000 // Always show shell
|| showSystemApps || it.packageInfo.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) == 0
|| showSystemApps || it.applicationInfo.flags.and(ApplicationInfo.FLAG_SYSTEM) == 0
}
}

private suspend inline fun connectRootService(
crossinline onDisconnect: () -> Unit = {}
): Pair<IBinder, ServiceConnection> = suspendCoroutine {
val connection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
onDisconnect()
}
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
it.resume(binder as IBinder to this)
}
}
val intent = Intent(apApp, RootServices::class.java)
val task = RootServices.bindOrTask(
intent,
Shell.EXECUTOR,
connection,
)
val shell = APatchCli.SHELL
task?.let { it1 -> shell.execTask(it1) }
}

private fun stopRootService() {
val intent = Intent(apApp, RootServices::class.java)
RootServices.stop(intent)
}

suspend fun fetchAppList() {
isRefreshing = true

val result = connectRootService {
Log.w(TAG, "RootService disconnected")
}

withContext(Dispatchers.IO) {
val binder = result.first
val allPackages = IAPRootService.Stub.asInterface(binder).getPackages(0)
val pm = getPackageManager()
val allPackages = pm.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES)

withContext(Dispatchers.Main) {
stopRootService()
}
val uids = Natives.suUids().toList()
Log.d(TAG, "all allows: $uids")

Expand All @@ -130,13 +97,12 @@ class SuperUserViewModel : ViewModel() {

Log.d(TAG, "all configs: $configs")

apps = allPackages.list.map {
val appInfo = it.applicationInfo
val uid = appInfo.uid
apps = allPackages.map {
val uid = it.uid
val actProfile = if (uids.contains(uid)) Natives.suProfile(uid) else null
val config = configs.getOrDefault(
appInfo.packageName,
PkgConfig.Config(appInfo.packageName, 1, 0, Natives.Profile(uid))
it.packageName,
PkgConfig.Config(it.packageName, 1, 0, Natives.Profile(uid))
)
config.allow = 0

Expand All @@ -146,8 +112,8 @@ class SuperUserViewModel : ViewModel() {
config.profile = actProfile
}
AppInfo(
label = appInfo.loadLabel(apApp.packageManager).toString(),
packageInfo = it,
label = it.loadLabel(apApp.packageManager).toString(),
applicationInfo = it,
config = config
)
}.filter { it.packageName != apApp.packageName }
Expand Down

0 comments on commit e2daeb9

Please sign in to comment.