Loading packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +25 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.power; import static android.app.PendingIntent.FLAG_IMMUTABLE; import android.app.Dialog; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -60,20 +61,25 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import com.android.systemui.volume.Events; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.text.NumberFormat; import java.util.Locale; import java.util.Objects; import javax.inject.Inject; import dagger.Lazy; /** */ @SysUISingleton Loading Loading @@ -164,11 +170,15 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private ActivityStarter mActivityStarter; private final BroadcastSender mBroadcastSender; private final Lazy<BatteryController> mBatteryControllerLazy; private final DialogLaunchAnimator mDialogLaunchAnimator; /** */ @Inject public PowerNotificationWarnings(Context context, ActivityStarter activityStarter, BroadcastSender broadcastSender) { BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy, DialogLaunchAnimator dialogLaunchAnimator) { mContext = context; mNoMan = mContext.getSystemService(NotificationManager.class); mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE); Loading @@ -176,6 +186,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { mReceiver.init(); mActivityStarter = activityStarter; mBroadcastSender = broadcastSender; mBatteryControllerLazy = batteryControllerLazy; mDialogLaunchAnimator = dialogLaunchAnimator; mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog); } Loading Loading @@ -685,8 +697,19 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { } d.setShowForAllUsers(true); d.setOnDismissListener((dialog) -> mSaverConfirmation = null); WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView(); if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) { mDialogLaunchAnimator.showFromView(d, ref.get()); } else { d.show(); } mSaverConfirmation = d; mBatteryControllerLazy.get().clearLastPowerSaverStartView(); } @VisibleForTesting Dialog getSaverConfirmationDialog() { return mSaverConfirmation; } private boolean isEnglishLocale() { Loading packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +6 −1 Original line number Diff line number Diff line Loading @@ -116,6 +116,11 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements public void handleSetListening(boolean listening) { super.handleSetListening(listening); mSetting.setListening(listening); if (!listening) { // If we stopped listening, it means that the tile is not visible. In that case, we // don't need to save the view anymore mBatteryController.clearLastPowerSaverStartView(); } } @Override Loading @@ -128,7 +133,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements if (getState().state == Tile.STATE_UNAVAILABLE) { return; } mBatteryController.setPowerSaveMode(!mPowerSave); mBatteryController.setPowerSaveMode(!mPowerSave, view); } @Override Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +28 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import android.annotation.Nullable; import android.view.View; import com.android.systemui.Dumpable; import com.android.systemui.demomode.DemoMode; Loading @@ -24,6 +25,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; public interface BatteryController extends DemoMode, Dumpable, CallbackController<BatteryStateChangeCallback> { Loading @@ -35,7 +37,32 @@ public interface BatteryController extends DemoMode, Dumpable, /** * Sets if the current device is in power save mode. */ void setPowerSaveMode(boolean powerSave); default void setPowerSaveMode(boolean powerSave) { setPowerSaveMode(powerSave, null); } /** * Sets if the current device is in power save mode. * * Can pass the view that triggered the request. */ void setPowerSaveMode(boolean powerSave, @Nullable View view); /** * Gets a reference to the last view used when called {@link #setPowerSaveMode}. */ @Nullable default WeakReference<View> getLastPowerSaverStartView() { return null; } /** * Clears the last view used when called {@link #setPowerSaveMode}. * * Immediately after calling this, a call to {@link #getLastPowerSaverStartView()} should return * {@code null}. */ default void clearLastPowerSaverStartView() {} /** * Returns {@code true} if the device is currently plugged in. Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +20 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerSaveState; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -45,8 +46,10 @@ import com.android.systemui.power.EnhancedEstimates; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** * Default implementation of a {@link BatteryController}. This controller monitors for battery Loading Loading @@ -85,6 +88,11 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private Estimate mEstimate; private boolean mFetchingEstimate = false; // Use AtomicReference because we may request it from a different thread // Use WeakReference because we are keeping a reference to a View that's not as long lived // as this controller. private AtomicReference<WeakReference<View>> mPowerSaverStartView = new AtomicReference<>(); @VisibleForTesting public BatteryControllerImpl( Context context, Loading Loading @@ -141,10 +149,21 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } @Override public void setPowerSaveMode(boolean powerSave) { public void setPowerSaveMode(boolean powerSave, View view) { if (powerSave) mPowerSaverStartView.set(new WeakReference<>(view)); BatterySaverUtils.setPowerSaveMode(mContext, powerSave, /*needFirstTimeWarning*/ true); } @Override public WeakReference<View> getLastPowerSaverStartView() { return mPowerSaverStartView.get(); } @Override public void clearLastPowerSaverStartView() { mPowerSaverStartView.set(null); } @Override public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) { synchronized (mChangeCallbacks) { Loading packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java +92 −5 Original line number Diff line number Diff line Loading @@ -25,29 +25,48 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import androidx.test.runner.AndroidJUnit4; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.lang.ref.WeakReference; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class PowerNotificationWarningsTest extends SysuiTestCase { public static final String FORMATTED_45M = "0h 45m"; Loading @@ -55,14 +74,34 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { private final NotificationManager mMockNotificationManager = mock(NotificationManager.class); private PowerNotificationWarnings mPowerNotificationWarnings; @Mock private BatteryController mBatteryController; @Mock private DialogLaunchAnimator mDialogLaunchAnimator; @Mock private View mView; private BroadcastReceiver mReceiver; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Context wrapper = new ContextWrapper(mContext) { @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { mReceiver = receiver; return null; } }; // Test Instance. mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager); ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class); BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class); mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter, broadcastSender); mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter, broadcastSender, () -> mBatteryController, mDialogLaunchAnimator); BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1, BatteryManager.BATTERY_HEALTH_GOOD, 5, 15); mPowerNotificationWarnings.updateSnapshot(snapshot); Loading Loading @@ -168,4 +207,52 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { mPowerNotificationWarnings.mUsbHighTempDialog.dismiss(); } @Test public void testDialogStartedFromLauncher_viewVisible() { when(mBatteryController.getLastPowerSaverStartView()) .thenReturn(new WeakReference<>(mView)); when(mView.isAggregatedVisible()).thenReturn(true); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator).showFromView(any(), eq(mView)); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } @Test public void testDialogStartedNotFromLauncher_viewNotVisible() { when(mBatteryController.getLastPowerSaverStartView()) .thenReturn(new WeakReference<>(mView)); when(mView.isAggregatedVisible()).thenReturn(false); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } @Test public void testDialogShownNotFromLauncher() { when(mBatteryController.getLastPowerSaverStartView()).thenReturn(null); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } } Loading
packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +25 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.power; import static android.app.PendingIntent.FLAG_IMMUTABLE; import android.app.Dialog; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationManager; Loading Loading @@ -60,20 +61,25 @@ import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.settingslib.utils.PowerUtil; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.phone.SystemUIDialog; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import com.android.systemui.volume.Events; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.text.NumberFormat; import java.util.Locale; import java.util.Objects; import javax.inject.Inject; import dagger.Lazy; /** */ @SysUISingleton Loading Loading @@ -164,11 +170,15 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { private ActivityStarter mActivityStarter; private final BroadcastSender mBroadcastSender; private final Lazy<BatteryController> mBatteryControllerLazy; private final DialogLaunchAnimator mDialogLaunchAnimator; /** */ @Inject public PowerNotificationWarnings(Context context, ActivityStarter activityStarter, BroadcastSender broadcastSender) { BroadcastSender broadcastSender, Lazy<BatteryController> batteryControllerLazy, DialogLaunchAnimator dialogLaunchAnimator) { mContext = context; mNoMan = mContext.getSystemService(NotificationManager.class); mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE); Loading @@ -176,6 +186,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { mReceiver.init(); mActivityStarter = activityStarter; mBroadcastSender = broadcastSender; mBatteryControllerLazy = batteryControllerLazy; mDialogLaunchAnimator = dialogLaunchAnimator; mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog); } Loading Loading @@ -685,8 +697,19 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { } d.setShowForAllUsers(true); d.setOnDismissListener((dialog) -> mSaverConfirmation = null); WeakReference<View> ref = mBatteryControllerLazy.get().getLastPowerSaverStartView(); if (ref != null && ref.get() != null && ref.get().isAggregatedVisible()) { mDialogLaunchAnimator.showFromView(d, ref.get()); } else { d.show(); } mSaverConfirmation = d; mBatteryControllerLazy.get().clearLastPowerSaverStartView(); } @VisibleForTesting Dialog getSaverConfirmationDialog() { return mSaverConfirmation; } private boolean isEnglishLocale() { Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java +6 −1 Original line number Diff line number Diff line Loading @@ -116,6 +116,11 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements public void handleSetListening(boolean listening) { super.handleSetListening(listening); mSetting.setListening(listening); if (!listening) { // If we stopped listening, it means that the tile is not visible. In that case, we // don't need to save the view anymore mBatteryController.clearLastPowerSaverStartView(); } } @Override Loading @@ -128,7 +133,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements if (getState().state == Tile.STATE_UNAVAILABLE) { return; } mBatteryController.setPowerSaveMode(!mPowerSave); mBatteryController.setPowerSaveMode(!mPowerSave, view); } @Override Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +28 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import android.annotation.Nullable; import android.view.View; import com.android.systemui.Dumpable; import com.android.systemui.demomode.DemoMode; Loading @@ -24,6 +25,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; public interface BatteryController extends DemoMode, Dumpable, CallbackController<BatteryStateChangeCallback> { Loading @@ -35,7 +37,32 @@ public interface BatteryController extends DemoMode, Dumpable, /** * Sets if the current device is in power save mode. */ void setPowerSaveMode(boolean powerSave); default void setPowerSaveMode(boolean powerSave) { setPowerSaveMode(powerSave, null); } /** * Sets if the current device is in power save mode. * * Can pass the view that triggered the request. */ void setPowerSaveMode(boolean powerSave, @Nullable View view); /** * Gets a reference to the last view used when called {@link #setPowerSaveMode}. */ @Nullable default WeakReference<View> getLastPowerSaverStartView() { return null; } /** * Clears the last view used when called {@link #setPowerSaveMode}. * * Immediately after calling this, a call to {@link #getLastPowerSaverStartView()} should return * {@code null}. */ default void clearLastPowerSaverStartView() {} /** * Returns {@code true} if the device is currently plugged in. Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java +20 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.PowerSaveState; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -45,8 +46,10 @@ import com.android.systemui.power.EnhancedEstimates; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** * Default implementation of a {@link BatteryController}. This controller monitors for battery Loading Loading @@ -85,6 +88,11 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC private Estimate mEstimate; private boolean mFetchingEstimate = false; // Use AtomicReference because we may request it from a different thread // Use WeakReference because we are keeping a reference to a View that's not as long lived // as this controller. private AtomicReference<WeakReference<View>> mPowerSaverStartView = new AtomicReference<>(); @VisibleForTesting public BatteryControllerImpl( Context context, Loading Loading @@ -141,10 +149,21 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC } @Override public void setPowerSaveMode(boolean powerSave) { public void setPowerSaveMode(boolean powerSave, View view) { if (powerSave) mPowerSaverStartView.set(new WeakReference<>(view)); BatterySaverUtils.setPowerSaveMode(mContext, powerSave, /*needFirstTimeWarning*/ true); } @Override public WeakReference<View> getLastPowerSaverStartView() { return mPowerSaverStartView.get(); } @Override public void clearLastPowerSaverStartView() { mPowerSaverStartView.set(null); } @Override public void addCallback(@NonNull BatteryController.BatteryStateChangeCallback cb) { synchronized (mChangeCallbacks) { Loading
packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java +92 −5 Original line number Diff line number Diff line Loading @@ -25,29 +25,48 @@ import static org.mockito.Matchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Notification; import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.test.suitebuilder.annotation.SmallTest; import androidx.test.runner.AndroidJUnit4; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.settingslib.fuelgauge.BatterySaverUtils; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.util.NotificationChannels; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.lang.ref.WeakReference; @SmallTest @RunWith(AndroidJUnit4.class) @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class PowerNotificationWarningsTest extends SysuiTestCase { public static final String FORMATTED_45M = "0h 45m"; Loading @@ -55,14 +74,34 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { private final NotificationManager mMockNotificationManager = mock(NotificationManager.class); private PowerNotificationWarnings mPowerNotificationWarnings; @Mock private BatteryController mBatteryController; @Mock private DialogLaunchAnimator mDialogLaunchAnimator; @Mock private View mView; private BroadcastReceiver mReceiver; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Context wrapper = new ContextWrapper(mContext) { @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) { mReceiver = receiver; return null; } }; // Test Instance. mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager); ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class); BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class); mPowerNotificationWarnings = new PowerNotificationWarnings(mContext, starter, broadcastSender); mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter, broadcastSender, () -> mBatteryController, mDialogLaunchAnimator); BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1, BatteryManager.BATTERY_HEALTH_GOOD, 5, 15); mPowerNotificationWarnings.updateSnapshot(snapshot); Loading Loading @@ -168,4 +207,52 @@ public class PowerNotificationWarningsTest extends SysuiTestCase { mPowerNotificationWarnings.mUsbHighTempDialog.dismiss(); } @Test public void testDialogStartedFromLauncher_viewVisible() { when(mBatteryController.getLastPowerSaverStartView()) .thenReturn(new WeakReference<>(mView)); when(mView.isAggregatedVisible()).thenReturn(true); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator).showFromView(any(), eq(mView)); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } @Test public void testDialogStartedNotFromLauncher_viewNotVisible() { when(mBatteryController.getLastPowerSaverStartView()) .thenReturn(new WeakReference<>(mView)); when(mView.isAggregatedVisible()).thenReturn(false); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } @Test public void testDialogShownNotFromLauncher() { when(mBatteryController.getLastPowerSaverStartView()).thenReturn(null); Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION); intent.putExtras(new Bundle()); mReceiver.onReceive(mContext, intent); verify(mDialogLaunchAnimator, never()).showFromView(any(), any()); assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue(); mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss(); } }