Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a5952a1 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

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
parent f840dd48
Loading
Loading
Loading
Loading
+20 −14
Original line number Original line Diff line number Diff line
@@ -38,7 +38,7 @@ import android.view.InputDevice;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
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.io.PrintWriter;
import java.util.Arrays;
import java.util.Arrays;
@@ -438,7 +438,7 @@ final class BatteryController {
        private State mState;
        private State mState;


        @Nullable
        @Nullable
        private UEventListener mUEventListener;
        private UEventBatteryListener mUEventBatteryListener;


        DeviceMonitor(int deviceId) {
        DeviceMonitor(int deviceId) {
            mState = new State(deviceId);
            mState = new State(deviceId);
@@ -473,13 +473,14 @@ final class BatteryController {
                return;
                return;
            }
            }
            final int deviceId = mState.deviceId;
            final int deviceId = mState.deviceId;
            mUEventListener = new UEventListener() {
            mUEventBatteryListener = new UEventBatteryListener() {
                @Override
                @Override
                public void onUEvent(long eventTime) {
                public void onBatteryUEvent(long eventTime) {
                    handleUEventNotification(deviceId, eventTime);
                    handleUEventNotification(deviceId, eventTime);
                }
                }
            };
            };
            mUEventManager.addListener(mUEventListener, "DEVPATH=" + formatDevPath(batteryPath));
            mUEventManager.addListener(
                    mUEventBatteryListener, "DEVPATH=" + formatDevPath(batteryPath));
        }
        }


        private String formatDevPath(String path) {
        private String formatDevPath(String path) {
@@ -489,9 +490,9 @@ final class BatteryController {


        // This must be called when the device is no longer being monitored.
        // This must be called when the device is no longer being monitored.
        public void stopMonitoring() {
        public void stopMonitoring() {
            if (mUEventListener != null) {
            if (mUEventBatteryListener != null) {
                mUEventManager.removeListener(mUEventListener);
                mUEventManager.removeListener(mUEventBatteryListener);
                mUEventListener = null;
                mUEventBatteryListener = null;
            }
            }
        }
        }


@@ -503,7 +504,7 @@ final class BatteryController {
        @Override
        @Override
        public String toString() {
        public String toString() {
            return "state=" + mState
            return "state=" + mState
                    + ", uEventListener=" + (mUEventListener != null ? "added" : "none");
                    + ", uEventListener=" + (mUEventBatteryListener != null ? "added" : "none");
        }
        }
    }
    }


@@ -512,7 +513,7 @@ final class BatteryController {
    interface UEventManager {
    interface UEventManager {


        @VisibleForTesting
        @VisibleForTesting
        abstract class UEventListener {
        abstract class UEventBatteryListener {
            private final UEventObserver mObserver = new UEventObserver() {
            private final UEventObserver mObserver = new UEventObserver() {
                @Override
                @Override
                public void onUEvent(UEvent event) {
                public void onUEvent(UEvent event) {
@@ -522,18 +523,23 @@ final class BatteryController {
                                "UEventListener: Received UEvent: "
                                "UEventListener: Received UEvent: "
                                        + event + " eventTime: " + eventTime);
                                        + 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);
            listener.mObserver.startObserving(match);
        }
        }


        default void removeListener(UEventListener listener) {
        default void removeListener(UEventBatteryListener listener) {
            listener.mObserver.stopObserving();
            listener.mObserver.stopObserving();
        }
        }
    }
    }
+5 −4
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ import android.platform.test.annotations.Presubmit
import android.view.InputDevice
import android.view.InputDevice
import androidx.test.InstrumentationRegistry
import androidx.test.InstrumentationRegistry
import com.android.server.input.BatteryController.UEventManager
import com.android.server.input.BatteryController.UEventManager
import com.android.server.input.BatteryController.UEventManager.UEventBatteryListener
import org.hamcrest.Description
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matcher
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.MatcherAssert.assertThat
@@ -264,7 +265,7 @@ class BatteryControllerTests {
        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
        val listener = createMockListener()
        val listener = createMockListener()
        val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java)
        val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java)
        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
        // The device paths for UEvent notifications do not include the "/sys" prefix, so verify
        // 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.
        // 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.
        // If the battery state has changed when an UEvent is sent, the listeners are notified.
        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(80)
        `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,
        listener.verifyNotified(DEVICE_ID, status = STATUS_CHARGING, capacity = 0.80f,
            eventTime = TIMESTAMP)
            eventTime = TIMESTAMP)


        // If the battery state has not changed when an UEvent is sent, the listeners are not
        // If the battery state has not changed when an UEvent is sent, the listeners are not
        // notified.
        // notified.
        clearInvocations(listener)
        clearInvocations(listener)
        uEventListener.value!!.onUEvent(TIMESTAMP + 1)
        uEventListener.value!!.onBatteryUEvent(TIMESTAMP + 1)
        verifyNoMoreInteractions(listener)
        verifyNoMoreInteractions(listener)


        batteryController.unregisterBatteryListener(DEVICE_ID, listener, PID)
        batteryController.unregisterBatteryListener(DEVICE_ID, listener, PID)
@@ -296,7 +297,7 @@ class BatteryControllerTests {
        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
        `when`(native.getBatteryStatus(DEVICE_ID)).thenReturn(STATUS_CHARGING)
        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
        `when`(native.getBatteryCapacity(DEVICE_ID)).thenReturn(78)
        val listener = createMockListener()
        val listener = createMockListener()
        val uEventListener = ArgumentCaptor.forClass(UEventManager.UEventListener::class.java)
        val uEventListener = ArgumentCaptor.forClass(UEventBatteryListener::class.java)
        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
        batteryController.registerBatteryListener(DEVICE_ID, listener, PID)
        verify(uEventManager).addListener(uEventListener.capture(), eq("DEVPATH=/test/device1"))
        verify(uEventManager).addListener(uEventListener.capture(), eq("DEVPATH=/test/device1"))
        listener.verifyNotified(DEVICE_ID, status = STATUS_CHARGING, capacity = 0.78f)
        listener.verifyNotified(DEVICE_ID, status = STATUS_CHARGING, capacity = 0.78f)