fix: refresh OneUI lockscreen battery indication
This commit is contained in:
@@ -40,7 +40,10 @@ internal class OneUiMiscBackend(private val framework: XposedInterface) : Visibi
|
||||
return installed > 0
|
||||
}
|
||||
|
||||
override fun onPolicyChanged() = aodBattery.refresh()
|
||||
override fun onPolicyChanged() {
|
||||
lockscreenBattery.refresh()
|
||||
aodBattery.refresh()
|
||||
}
|
||||
|
||||
private companion object { const val TAG = "NotificationsMaster" }
|
||||
}
|
||||
@@ -128,39 +131,81 @@ private class AodCallVisibilityController(private val framework: XposedInterface
|
||||
}
|
||||
|
||||
private class LockscreenBatteryController(private val framework: XposedInterface) {
|
||||
private var controller: Any? = null
|
||||
private var batteryEvent: Any? = null
|
||||
private var restingEvent: Any? = null
|
||||
private lateinit var addTimeout: Method
|
||||
private lateinit var addResting: Method
|
||||
private lateinit var remove: Method
|
||||
private var failed = false
|
||||
|
||||
fun install(classLoader: ClassLoader): Boolean {
|
||||
val eventClass = classLoader.findClass("com.android.systemui.statusbar.IndicationEventType") ?: return false
|
||||
val batteryEvent = eventClass.staticField("BATTERY") ?: return false
|
||||
val restingEvent = eventClass.staticField("BATTERY_RESTING") ?: return false
|
||||
val controller = classLoader.findClass(
|
||||
"com.android.systemui.statusbar.KeyguardSecIndicationController",
|
||||
) ?: return false
|
||||
val methods = controller.methodsNamed("addInitialIndication")
|
||||
methods.forEach { method ->
|
||||
fun install(classLoader: ClassLoader): Boolean = runCatching {
|
||||
val eventClass = requireNotNull(classLoader.findClass("com.android.systemui.statusbar.IndicationEventType"))
|
||||
batteryEvent = requireNotNull(eventClass.staticField("BATTERY"))
|
||||
restingEvent = requireNotNull(eventClass.staticField("BATTERY_RESTING"))
|
||||
val controllerClass = requireNotNull(
|
||||
classLoader.findClass("com.android.systemui.statusbar.KeyguardSecIndicationController"),
|
||||
)
|
||||
addTimeout = controllerClass.getDeclaredMethod(
|
||||
"addIndicationTimeout",
|
||||
eventClass,
|
||||
CharSequence::class.java,
|
||||
ColorStateList::class.java,
|
||||
Boolean::class.javaPrimitiveType,
|
||||
).also { it.isAccessible = true }
|
||||
addResting = controllerClass.getDeclaredMethod(
|
||||
"addIndication",
|
||||
eventClass,
|
||||
CharSequence::class.java,
|
||||
).also { it.isAccessible = true }
|
||||
remove = controllerClass.getDeclaredMethod("removeIndication", eventClass).also { it.isAccessible = true }
|
||||
val method = controllerClass.getDeclaredMethod("addInitialIndication").also { it.isAccessible = true }
|
||||
framework.intercept(method) { chain ->
|
||||
val result = chain.proceed()
|
||||
runCatching {
|
||||
val target = chain.thisObject
|
||||
val context = target.field("mContext") as? Context ?: return@runCatching
|
||||
val state = visibleLockscreenBattery(context, target) ?: return@runCatching
|
||||
val text = state.formattedPercent()
|
||||
val color = target.field("mInitialTextColorState") as? ColorStateList
|
||||
target.invokeNamed("addIndicationTimeout", batteryEvent, text, color, false)
|
||||
target.invokeNamed("addIndication", restingEvent, text)
|
||||
}.onFailure(::logFailureOnce)
|
||||
controller = chain.thisObject
|
||||
update(chain.thisObject)
|
||||
result
|
||||
}
|
||||
classLoader.findClass("com.android.systemui.statusbar.KeyguardIndicationController\$4")
|
||||
?.getDeclaredMethod("onDozingChanged", Boolean::class.javaPrimitiveType)
|
||||
?.also { it.isAccessible = true }
|
||||
?.let { dozingChanged ->
|
||||
framework.intercept(dozingChanged) { chain ->
|
||||
val result = chain.proceed()
|
||||
val target = chain.thisObject.field("this\$0")
|
||||
if (chain.args.firstOrNull() == false && controllerClass.isInstance(target)) {
|
||||
controller = target
|
||||
update(target)
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
return methods.isNotEmpty()
|
||||
}.onFailure { error ->
|
||||
Log.w(TAG, "OneUI lockscreen battery boundary is unavailable", error)
|
||||
}.isSuccess
|
||||
|
||||
fun refresh() {
|
||||
val target = controller ?: return
|
||||
(target.field("mIndicationArea") as? View)?.post { update(target) } ?: update(target)
|
||||
}
|
||||
|
||||
private fun visibleLockscreenBattery(context: Context, controller: Any): BatteryState? {
|
||||
if (!ProcessVisibilityPolicyCache.systemUiMisc.showLockscreenBatteryPercentWhenUnplugged) return null
|
||||
if (controller.field("mDozing") == true) return null
|
||||
return currentBatteryState(context)?.takeUnless { it.plugged || it.charged }
|
||||
private fun update(target: Any?) = runCatching {
|
||||
if (target.field("mDozing") == true) return@runCatching
|
||||
val context = target.field("mContext") as? Context ?: return@runCatching
|
||||
val state = currentBatteryState(context) ?: return@runCatching
|
||||
if (state.plugged || state.charged) return@runCatching
|
||||
val battery = batteryEvent ?: return@runCatching
|
||||
val resting = restingEvent ?: return@runCatching
|
||||
if (!ProcessVisibilityPolicyCache.systemUiMisc.showLockscreenBatteryPercentWhenUnplugged) {
|
||||
remove.invoke(target, battery)
|
||||
remove.invoke(target, resting)
|
||||
return@runCatching
|
||||
}
|
||||
val text = state.formattedPercent()
|
||||
val color = target.field("mInitialTextColorState") as? ColorStateList
|
||||
addTimeout.invoke(target, battery, text, color, false)
|
||||
addResting.invoke(target, resting, text)
|
||||
}.onFailure(::logFailureOnce)
|
||||
|
||||
private fun logFailureOnce(error: Throwable) {
|
||||
if (failed) return
|
||||
|
||||
Reference in New Issue
Block a user