Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,9 @@ object ManagerService : ILSPManagerService.Stub() {
fun openManager(withData: Uri?) {
val intent = getManagerIntent() ?: return
val launchIntent = Intent(intent).apply { data = withData }
runCatching {
activityManager?.startActivityAsUserWithFeature(
SystemContext.appThread,
"android",
null,
launchIntent,
launchIntent.type,
null,
null,
0,
0,
null,
null,
0)
}
.onFailure { Log.e(TAG, "Failed to open manager", it) }
// Negative results are `ActivityManager.START_*` errors, the positive ones are all successes.
val result = activityManager?.startActivityAsUserCompat(launchIntent, 0) ?: -1
if (result < 0) Log.e(TAG, "Failed to open manager: $result")
}

/** Fixes permissions for the WebView cache. */
Expand Down Expand Up @@ -376,19 +363,7 @@ object ManagerService : ILSPManagerService.Stub() {
wm?.lockNow(null)
}
}
return activityManager?.startActivityAsUserWithFeature(
SystemContext.appThread,
"android",
null,
intent,
intent.type,
null,
null,
0,
0,
null,
null,
userId) ?: -1
return activityManager?.startActivityAsUserCompat(intent, userId) ?: -1
}

override fun queryIntentActivitiesAsUser(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ object SystemServerService : ILSPSystemServerService.Stub(), IBinder.DeathRecipi
// Register as the service name early to setup an IPC for `system_server`.
Log.d(TAG, "Registering bridge service for `system_server` with name `$serviceName`.")

// `IServiceManager.registerForNotifications` is only available since Android R.
// On older platforms we simply let the real service replace our proxy in servicemanager.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val callback =
object : IServiceCallback.Stub() {
Expand All @@ -39,13 +41,17 @@ object SystemServerService : ILSPSystemServerService.Stub(), IBinder.DeathRecipi

override fun asBinder(): IBinder = this
}
runCatching {
getSystemServiceManager().registerForNotifications(serviceName, callback)
ServiceManager.addService(serviceName, this)
proxyServiceName = serviceName
}
runCatching { getSystemServiceManager().registerForNotifications(serviceName, callback) }
.onFailure { Log.e(TAG, "Failed to register IServiceCallback", it) }
}

// The Zygisk module polls this name during `system_server` specialization,
// so it must be claimed on every supported platform.
runCatching {
ServiceManager.addService(serviceName, this)
proxyServiceName = serviceName
}
.onFailure { Log.e(TAG, "Failed to register proxy service `$serviceName`", it) }
}

override fun requestApplicationService(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,34 @@ fun IActivityManager.broadcastIntentCompat(intent: Intent) {
.onFailure { Log.e(TAG, "broadcastIntent failed", it) }
}

// `startActivityAsUserWithFeature` only arrived in Android R: on older platforms the same call
// exists without the calling feature id, and using the newer one throws `NoSuchMethodError`.
fun IActivityManager.startActivityAsUserCompat(intent: Intent, userId: Int): Int {
val appThread = SystemContext.appThread
return runCatching {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
startActivityAsUserWithFeature(
appThread,
"android",
null,
intent,
intent.type,
null,
null,
0,
0,
null,
null,
userId)
} else {
startActivityAsUser(
appThread, "android", intent, intent.type, null, null, 0, 0, null, null, userId)
}
}
.onFailure { Log.e(TAG, "startActivityAsUser failed", it) }
.getOrDefault(-1)
}

fun IUserManager.getUserName(userId: Int): String {
return runCatching { getUserInfo(userId)?.name }.getOrNull() ?: userId.toString()
}
Loading