diff options
5 files changed, 209 insertions, 2 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index c61002ec9822..c2e4b82acf57 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -793,4 +793,14 @@ flag { metadata { purpose: PURPOSE_BUGFIX } -}
\ No newline at end of file +} + +flag { + name: "register_battery_controller_receivers_in_corestartable" + namespace: "systemui" + description: "Decide whether to register the receivers in battery controller impl in the BatteryControllerStartable corestartable." + bug: "307517093" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 21ee5bd92328..23fc8ace0223 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -55,6 +55,7 @@ import com.android.systemui.statusbar.gesture.GesturePointerEventListener import com.android.systemui.statusbar.notification.InstantAppNotifier import com.android.systemui.statusbar.phone.ScrimController import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener +import com.android.systemui.statusbar.policy.BatteryControllerStartable import com.android.systemui.stylus.StylusUsiPowerStartable import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.theme.ThemeOverlayController @@ -343,4 +344,10 @@ abstract class SystemUICoreStartableModule { @IntoMap @ClassKey(HomeControlsDreamStartable::class) abstract fun bindHomeControlsDreamStartable(impl: HomeControlsDreamStartable): CoreStartable + + /** Binds {@link BatteryControllerStartable} as a {@link CoreStartable}. */ + @Binds + @IntoMap + @ClassKey(BatteryControllerStartable::class) + abstract fun bindsBatteryControllerStartable(impl: BatteryControllerStartable): CoreStartable } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java index 45078e32108d..46ca6e908cc1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java @@ -22,6 +22,7 @@ import static android.os.BatteryManager.EXTRA_CHARGING_STATUS; import static android.os.BatteryManager.EXTRA_PRESENT; import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS; +import static com.android.systemui.Flags.registerBatteryControllerReceiversInCorestartable; import static com.android.systemui.util.DumpUtilsKt.asIndenting; import android.annotation.WorkerThread; @@ -151,7 +152,9 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC @Override public void init() { mLogger.logBatteryControllerInit(this, mHasReceivedBattery); - registerReceiver(); + if (!registerBatteryControllerReceiversInCorestartable()) { + registerReceiver(); + } if (!mHasReceivedBattery) { // Get initial state. Relying on Sticky behavior until API for getting info. Intent intent = mContext.registerReceiver( diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerStartable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerStartable.java new file mode 100644 index 000000000000..7f601c837feb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerStartable.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy; + +import static com.android.systemui.Flags.registerBatteryControllerReceiversInCorestartable; + +import android.content.BroadcastReceiver; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbManager; +import android.os.PowerManager; + +import com.android.systemui.CoreStartable; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Background; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +/** A {@link CoreStartable} responsible for registering the receivers for + * {@link BatteryControllerImpl}. + */ +@SysUISingleton +public class BatteryControllerStartable implements CoreStartable { + + private final BatteryController mBatteryController; + private final Executor mBackgroundExecutor; + + private static final String ACTION_LEVEL_TEST = "com.android.systemui.BATTERY_LEVEL_TEST"; + + protected final BroadcastDispatcher mBroadcastDispatcher; + @Inject + public BatteryControllerStartable( + BatteryController batteryController, + BroadcastDispatcher broadcastDispatcher, + @Background Executor backgroundExecutor) { + mBatteryController = batteryController; + mBroadcastDispatcher = broadcastDispatcher; + mBackgroundExecutor = backgroundExecutor; + } + + private void registerReceiver() { + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_BATTERY_CHANGED); + filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); + filter.addAction(ACTION_LEVEL_TEST); + filter.addAction(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED); + mBroadcastDispatcher.registerReceiver((BroadcastReceiver) mBatteryController, filter); + } + + @Override + public void start() { + if (registerBatteryControllerReceiversInCorestartable() + && mBatteryController instanceof BatteryControllerImpl) { + mBackgroundExecutor.execute(() -> registerReceiver()); + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerStartableTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerStartableTest.java new file mode 100644 index 000000000000..f1dbee2ff8df --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerStartableTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.policy; + +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import android.os.Handler; +import android.os.Looper; +import android.os.PowerManager; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import com.android.settingslib.fuelgauge.BatterySaverUtils; +import com.android.systemui.Flags; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.demomode.DemoModeController; +import com.android.systemui.dump.DumpManager; +import com.android.systemui.power.EnhancedEstimates; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +public class BatteryControllerStartableTest extends SysuiTestCase { + + private BatteryController mBatteryController; + private BatteryControllerStartable mBatteryControllerStartable; + private MockitoSession mMockitoSession; + private FakeExecutor mExecutor; + @Mock + private BroadcastDispatcher mBroadcastDispatcher; + + @Before + public void setUp() throws IllegalStateException { + MockitoAnnotations.initMocks(this); + mMockitoSession = mockitoSession() + .initMocks(this) + .mockStatic(BatterySaverUtils.class) + .startMocking(); + + mExecutor = new FakeExecutor(new FakeSystemClock()); + + mBatteryController = new BatteryControllerImpl(getContext(), + mock(EnhancedEstimates.class), + mock(PowerManager.class), + mock(BroadcastDispatcher.class), + mock(DemoModeController.class), + mock(DumpManager.class), + mock(BatteryControllerLogger.class), + new Handler(Looper.getMainLooper()), + new Handler(Looper.getMainLooper())); + mBatteryController.init(); + + mBatteryControllerStartable = new BatteryControllerStartable(mBatteryController, + mBroadcastDispatcher, mExecutor); + } + + @After + public void tearDown() { + mMockitoSession.finishMocking(); + } + + @Test + @EnableFlags(Flags.FLAG_REGISTER_BATTERY_CONTROLLER_RECEIVERS_IN_CORESTARTABLE) + public void start_flagEnabled_registersListeners() { + mBatteryControllerStartable.start(); + mExecutor.runAllReady(); + + verify(mBroadcastDispatcher).registerReceiver(any(), any()); + } + + @Test + @DisableFlags(Flags.FLAG_REGISTER_BATTERY_CONTROLLER_RECEIVERS_IN_CORESTARTABLE) + public void start_flagDisabled_doesNotRegistersListeners() { + mBatteryControllerStartable.start(); + mExecutor.runAllReady(); + + verifyZeroInteractions(mBroadcastDispatcher); + } +} |