From 9a5952a1b5ebfad9ca3f6b939e42d4f5be456c5a Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Fri, 30 Sep 2022 22:51:36 +0000 Subject: [PATCH] BatteryController: Only listen to UEvents from power_supply changes Previously, BatteryController would listen to all UEvents generated for the input device's path. However, it should only listen to changes from the power_supply subsystem, which correspond to battery updates. Bug: 243005009 Test: atest FrameworkServicesTests Change-Id: I34e7dfce6eff40ca5c4e39a1de8893e67c1513e1 --- .../server/input/BatteryController.java | 34 +++++++++++-------- .../server/input/BatteryControllerTests.kt | 9 ++--- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java index 44c031da81dd3..324eefc809e82 100644 --- a/services/core/java/com/android/server/input/BatteryController.java +++ b/services/core/java/com/android/server/input/BatteryController.java @@ -38,7 +38,7 @@ import android.view.InputDevice; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.input.BatteryController.UEventManager.UEventListener; +import com.android.server.input.BatteryController.UEventManager.UEventBatteryListener; import java.io.PrintWriter; import java.util.Arrays; @@ -438,7 +438,7 @@ final class BatteryController { private State mState; @Nullable - private UEventListener mUEventListener; + private UEventBatteryListener mUEventBatteryListener; DeviceMonitor(int deviceId) { mState = new State(deviceId); @@ -473,13 +473,14 @@ final class BatteryController { return; } final int deviceId = mState.deviceId; - mUEventListener = new UEventListener() { + mUEventBatteryListener = new UEventBatteryListener() { @Override - public void onUEvent(long eventTime) { + public void onBatteryUEvent(long eventTime) { handleUEventNotification(deviceId, eventTime); } }; - mUEventManager.addListener(mUEventListener, "DEVPATH=" + formatDevPath(batteryPath)); + mUEventManager.addListener( + mUEventBatteryListener, "DEVPATH=" + formatDevPath(batteryPath)); } private String formatDevPath(String path) { @@ -489,9 +490,9 @@ final class BatteryController { // This must be called when the device is no longer being monitored. public void stopMonitoring() { - if (mUEventListener != null) { - mUEventManager.removeListener(mUEventListener); - mUEventListener = null; + if (mUEventBatteryListener != null) { + mUEventManager.removeListener(mUEventBatteryListener); + mUEventBatteryListener = null; } } @@ -503,7 +504,7 @@ final class BatteryController { @Override public String toString() { return "state=" + mState - + ", uEventListener=" + (mUEventListener != null ? "added" : "none"); + + ", uEventListener=" + (mUEventBatteryListener != null ? "added" : "none"); } } @@ -512,7 +513,7 @@ final class BatteryController { interface UEventManager { @VisibleForTesting - abstract class UEventListener { + abstract class UEventBatteryListener { private final UEventObserver mObserver = new UEventObserver() { @Override public void onUEvent(UEvent event) { @@ -522,18 +523,23 @@ final class BatteryController { "UEventListener: Received UEvent: " + event + " eventTime: " + eventTime); } - UEventListener.this.onUEvent(eventTime); + if (!"CHANGE".equalsIgnoreCase(event.get("ACTION")) + || !"POWER_SUPPLY".equalsIgnoreCase(event.get("SUBSYSTEM"))) { + // Disregard any UEvents that do not correspond to battery changes. + return; + } + UEventBatteryListener.this.onBatteryUEvent(eventTime); } }; - public abstract void onUEvent(long eventTime); + public abstract void onBatteryUEvent(long eventTime); } - default void addListener(UEventListener listener, String match) { + default void addListener(UEventBatteryListener listener, String match) { listener.mObserver.startObserving(match); } - default void removeListener(UEventListener listener) { + default void removeListener(UEventBatteryListener listener) { listener.mObserver.stopObserving(); } } diff --git a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt index 5a3148e2b6969..65076a372b0b9 100644 --- a/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt +++ b/services/tests/servicestests/src/com/android/server/input/BatteryControllerTests.kt @@ -33,6 +33,7 @@ import android.platform.test.annotations.Presubmit import android.view.InputDevice import androidx.test.InstrumentationRegistry import com.android.server.input.BatteryController.UEventManager +import com.android.server.input.BatteryController.UEventManager.UEventBatteryListener import org.hamcrest.Description import org.hamcrest.Matcher import org.hamcrest.MatcherAssert.assertThat @@ -264,7 +265,7 @@ class BatteryControllerTests { `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING) `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78) val listener = createMockListener() - val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java) + val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java) batteryController.registerBatteryListener(DEVICE_ID, listener, PID) // The device paths for UEvent notifications do not include the "/sys" prefix, so verify // that the added listener is configured to match the path without that prefix. @@ -274,14 +275,14 @@ class BatteryControllerTests { // If the battery state has changed when an UEvent is sent, the listeners are notified. `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(80) - uEventListener.value!!.onUEvent(TIMESTAMP) + uEventListener.value!!.onBatteryUEvent(TIMESTAMP) listener.verifyNotified(DEVICE_ID, status = STATUS_CHARGING, capacity = 0.80f, eventTime = TIMESTAMP) // If the battery state has not changed when an UEvent is sent, the listeners are not // notified. clearInvocations(listener) - uEventListener.value!!.onUEvent(TIMESTAMP + 1) + uEventListener.value!!.onBatteryUEvent(TIMESTAMP + 1) verifyNoMoreInteractions(listener) batteryController.unregisterBatteryListener(DEVICE_ID, listener, PID) @@ -296,7 +297,7 @@ class BatteryControllerTests { `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING) `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78) val listener = createMockListener() - val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java) + val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java) batteryController.registerBatteryListener(DEVICE_ID, listener, PID) verify(uEventManager).addListener(uEventListener.capture(), eq("DEVPATH=/test/device1")) listener.verifyNotified(DEVICE_ID, status = STATUS_CHARGING, capacity = 0.78f)