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

Commit 18408aa0 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Check power saver when plugged in state changes

Changes in plugged in state could also change power save, but they are
notified by two separate broadcasts. In order to obtain the information
early, check the power save state if the plugged in state changes and
update it before notifying callbacks.

Before this, the tile (and statusbar icon) will briefly go through
no-power save state when going between power save and plugged in (and
back), while we waited for the second broadcast.

With this solution, there's still a small instant of INACTIVE observed
(in logs), but we go from >50ms to <1ms.

We only check power save if the plugged in state changes, to prevent
frequent calls to system_server.

Test: atest BatteryControllerTest
Test: manual, observe tile logs
Fixes: 331755756
Flag: EXEMPT BUGFIX
Change-Id: I37c4d9890f02a072b345bcb165e09fcdce8ad313
parent 06350626
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -250,6 +250,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
            mLevel = (int) (100f
                    * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
                    / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
            int previousPluggedChargingSource = mPluggedChargingSource;
            mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
            mPluggedIn = mPluggedChargingSource != 0;
            final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
@@ -276,7 +277,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
                mIsBatteryDefender = isBatteryDefender;
                fireIsBatteryDefenderChanged();
            }

            if (mPluggedChargingSource != previousPluggedChargingSource) {
                updatePowerSave();
            }
            fireBatteryLevelChanged();
        } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
            updatePowerSave();
+63 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess
import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -308,6 +310,52 @@ public class BatteryControllerTest extends SysuiTestCase {
        mBatteryController.fireBatteryLevelChanged();
    }

    @Test
    public void plugAndUnplugWhenInBatterySaver_stateUpdatedWithoutBatterySaverBroadcast() {
        PowerSaveState state = new PowerSaveState.Builder()
                .setBatterySaverEnabled(false)
                .build();
        when(mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD)).thenReturn(state);

        // Set up on power save and not charging
        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
        mBatteryController.onReceive(
                getContext(), new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
        mBatteryController.onReceive(getContext(), createChargingIntent(false));

        TestCallback callback = new TestCallback();
        mBatteryController.addCallback(callback);

        assertThat(callback.pluggedIn).isFalse();
        assertThat(callback.powerSaverOn).isTrue();

        // Plug in (battery saver turns off)
        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
        mBatteryController.onReceive(getContext(), createChargingIntent(true));

        assertThat(callback.pluggedIn).isTrue();
        assertThat(callback.powerSaverOn).isFalse();

        // Unplug (battery saver turns back on)
        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
        mBatteryController.onReceive(getContext(), createChargingIntent(false));

        assertThat(callback.pluggedIn).isFalse();
        assertThat(callback.powerSaverOn).isTrue();
    }

    private Intent createChargingIntent(boolean charging) {
        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        if (charging) {
            return intent
                .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING)
                .putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_AC);
        } else {
            return intent
                .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_DISCHARGING);
        }
    }

    private void setupIncompatibleCharging() {
        final List<UsbPort> usbPorts = new ArrayList<>();
        usbPorts.add(mUsbPort);
@@ -318,4 +366,19 @@ public class BatteryControllerTest extends SysuiTestCase {
        when(mUsbPortStatus.getComplianceWarnings())
                .thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY});
    }

    private static class TestCallback
        implements BatteryController.BatteryStateChangeCallback {
        boolean pluggedIn = false;
        boolean powerSaverOn = false;
        @Override
        public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
            this.pluggedIn = pluggedIn;
        }

        @Override
        public void onPowerSaveChanged(boolean isPowerSave) {
            this.powerSaverOn = isPowerSave;
        }
    }
}