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.
This commit is contained in:
@@ -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
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user