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
|
return installed > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPolicyChanged() = aodBattery.refresh()
|
override fun onPolicyChanged() {
|
||||||
|
lockscreenBattery.refresh()
|
||||||
|
aodBattery.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
private companion object { const val TAG = "NotificationsMaster" }
|
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 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
|
private var failed = false
|
||||||
|
|
||||||
fun install(classLoader: ClassLoader): Boolean {
|
fun install(classLoader: ClassLoader): Boolean = runCatching {
|
||||||
val eventClass = classLoader.findClass("com.android.systemui.statusbar.IndicationEventType") ?: return false
|
val eventClass = requireNotNull(classLoader.findClass("com.android.systemui.statusbar.IndicationEventType"))
|
||||||
val batteryEvent = eventClass.staticField("BATTERY") ?: return false
|
batteryEvent = requireNotNull(eventClass.staticField("BATTERY"))
|
||||||
val restingEvent = eventClass.staticField("BATTERY_RESTING") ?: return false
|
restingEvent = requireNotNull(eventClass.staticField("BATTERY_RESTING"))
|
||||||
val controller = classLoader.findClass(
|
val controllerClass = requireNotNull(
|
||||||
"com.android.systemui.statusbar.KeyguardSecIndicationController",
|
classLoader.findClass("com.android.systemui.statusbar.KeyguardSecIndicationController"),
|
||||||
) ?: return false
|
)
|
||||||
val methods = controller.methodsNamed("addInitialIndication")
|
addTimeout = controllerClass.getDeclaredMethod(
|
||||||
methods.forEach { method ->
|
"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 ->
|
framework.intercept(method) { chain ->
|
||||||
val result = chain.proceed()
|
val result = chain.proceed()
|
||||||
runCatching {
|
controller = chain.thisObject
|
||||||
val target = chain.thisObject
|
update(chain.thisObject)
|
||||||
val context = target.field("mContext") as? Context ?: return@runCatching
|
result
|
||||||
val state = visibleLockscreenBattery(context, target) ?: return@runCatching
|
}
|
||||||
val text = state.formattedPercent()
|
classLoader.findClass("com.android.systemui.statusbar.KeyguardIndicationController\$4")
|
||||||
val color = target.field("mInitialTextColorState") as? ColorStateList
|
?.getDeclaredMethod("onDozingChanged", Boolean::class.javaPrimitiveType)
|
||||||
target.invokeNamed("addIndicationTimeout", batteryEvent, text, color, false)
|
?.also { it.isAccessible = true }
|
||||||
target.invokeNamed("addIndication", restingEvent, text)
|
?.let { dozingChanged ->
|
||||||
}.onFailure(::logFailureOnce)
|
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
|
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? {
|
private fun update(target: Any?) = runCatching {
|
||||||
if (!ProcessVisibilityPolicyCache.systemUiMisc.showLockscreenBatteryPercentWhenUnplugged) return null
|
if (target.field("mDozing") == true) return@runCatching
|
||||||
if (controller.field("mDozing") == true) return null
|
val context = target.field("mContext") as? Context ?: return@runCatching
|
||||||
return currentBatteryState(context)?.takeUnless { it.plugged || it.charged }
|
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) {
|
private fun logFailureOnce(error: Throwable) {
|
||||||
if (failed) return
|
if (failed) return
|
||||||
|
|||||||
Reference in New Issue
Block a user