From 23774e64a94c5cab08daa3ba2cec7a98db850cbd Mon Sep 17 00:00:00 2001 From: JingMatrix Date: Fri, 29 Aug 2025 18:26:33 +0200 Subject: [PATCH] app: config: Use linkToDeath for PackageManager resilience (#29) The previous implementation used `pingBinder()` to check the liveness of the PackageManager service on every call to `getPm()`. This polling approach introduces an unnecessary IPC round-trip overhead for every access. This commit refactors the logic to use the canonical, event-driven pattern for handling remote service death by implementing `linkToDeath`. A `DeathRecipient` is now registered with the binder upon the first connection. If the service process (`system_server`) dies for any reason, the `binderDied()` callback is automatically invoked by the system. This callback proactively clears the cached service instance, ensuring that the next call to `getPm()` will transparently re-establish a valid connection. --- .../TrickyStoreOSS/core/config/Config.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/github/beakthoven/TrickyStoreOSS/core/config/Config.kt b/app/src/main/java/io/github/beakthoven/TrickyStoreOSS/core/config/Config.kt index 925f6a9..c6b3735 100644 --- a/app/src/main/java/io/github/beakthoven/TrickyStoreOSS/core/config/Config.kt +++ b/app/src/main/java/io/github/beakthoven/TrickyStoreOSS/core/config/Config.kt @@ -7,6 +7,7 @@ package io.github.beakthoven.TrickyStoreOSS.core.config import android.content.pm.IPackageManager import android.os.FileObserver +import android.os.IBinder import android.os.IInterface import android.os.ServiceManager import io.github.beakthoven.TrickyStoreOSS.CertificateHacker @@ -127,10 +128,18 @@ object Config { } private var iPm: IPackageManager? = null + private val packageManagerDeathRecipient = object : IBinder.DeathRecipient { + override fun binderDied() { + (iPm as? IInterface)?.asBinder()?.unlinkToDeath(this, 0) + iPm = null + } + } fun getPm(): IPackageManager? { - if (iPm == null || (iPm as? IInterface)?.asBinder()?.pingBinder() != true) { - iPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")) + if (iPm == null) { + val binder = ServiceManager.getService("package") + binder.linkToDeath(packageManagerDeathRecipient, 0) + iPm = IPackageManager.Stub.asInterface(binder) } return iPm } @@ -208,4 +217,4 @@ data class CustomPatchLevel( val vendor: String? = null, val boot: String? = null, val all: String? = null -) \ No newline at end of file +)