1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.power;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static junit.framework.Assert.assertFalse;
22 import static junit.framework.Assert.assertTrue;
23 
24 import static org.mockito.Matchers.eq;
25 import static org.mockito.Mockito.any;
26 import static org.mockito.Mockito.anyString;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.times;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.app.ActivityManager;
34 import android.app.Notification;
35 import android.app.NotificationManager;
36 import android.content.BroadcastReceiver;
37 import android.content.Context;
38 import android.content.ContextWrapper;
39 import android.content.Intent;
40 import android.content.IntentFilter;
41 import android.os.BatteryManager;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.UserHandle;
45 import android.testing.TestableLooper;
46 
47 import androidx.test.ext.junit.runners.AndroidJUnit4;
48 import androidx.test.filters.SmallTest;
49 
50 import com.android.internal.logging.UiEventLogger;
51 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
52 import com.android.settingslib.fuelgauge.BatterySaverUtils;
53 import com.android.systemui.SysuiTestCase;
54 import com.android.systemui.animation.DialogTransitionAnimator;
55 import com.android.systemui.animation.Expandable;
56 import com.android.systemui.broadcast.BroadcastSender;
57 import com.android.systemui.plugins.ActivityStarter;
58 import com.android.systemui.settings.UserTracker;
59 import com.android.systemui.statusbar.phone.SystemUIDialog;
60 import com.android.systemui.statusbar.policy.BatteryController;
61 import com.android.systemui.util.NotificationChannels;
62 
63 import org.junit.Before;
64 import org.junit.Test;
65 import org.junit.runner.RunWith;
66 import org.mockito.ArgumentCaptor;
67 import org.mockito.Mock;
68 import org.mockito.MockitoAnnotations;
69 
70 import java.lang.ref.WeakReference;
71 
72 @SmallTest
73 @RunWith(AndroidJUnit4.class)
74 @TestableLooper.RunWithLooper
75 public class PowerNotificationWarningsTest extends SysuiTestCase {
76 
77     public static final String FORMATTED_45M = "0h 45m";
78     public static final String FORMATTED_HOUR = "1h 0m";
79     private final NotificationManager mMockNotificationManager = mock(NotificationManager.class);
80     private PowerNotificationWarnings mPowerNotificationWarnings;
81 
82     @Mock
83     private BatteryController mBatteryController;
84     @Mock
85     private DialogTransitionAnimator mDialogTransitionAnimator;
86     @Mock
87     private UiEventLogger mUiEventLogger;
88     @Mock
89     private UserTracker mUserTracker;
90     @Mock
91     private Expandable mExpandable;
92     @Mock
93     private DialogTransitionAnimator.Controller mController;
94     @Mock
95     private SystemUIDialog.Factory mSystemUIDialogFactory;
96     @Mock
97     private SystemUIDialog mSystemUIDialog;
98 
99     private BroadcastReceiver mReceiver;
100 
101     @Before
setUp()102     public void setUp() throws Exception {
103         MockitoAnnotations.initMocks(this);
104 
105         Context wrapper = new ContextWrapper(mContext) {
106             @Override
107             public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
108                     IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
109                 mReceiver = receiver;
110                 return null;
111             }
112         };
113 
114         // Test Instance.
115         mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
116         ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
117         BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
118         when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
119         when(mUserTracker.getUserHandle()).thenReturn(
120                 UserHandle.of(ActivityManager.getCurrentUser()));
121         when(mSystemUIDialogFactory.create()).thenReturn(mSystemUIDialog);
122         mPowerNotificationWarnings = new PowerNotificationWarnings(
123                 wrapper,
124                 starter,
125                 broadcastSender,
126                 () -> mBatteryController,
127                 mDialogTransitionAnimator,
128                 mUiEventLogger,
129                 mUserTracker,
130                 mSystemUIDialogFactory);
131         BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
132                 BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
133         mPowerNotificationWarnings.updateSnapshot(snapshot);
134     }
135 
136     @Test
testIsInvalidChargerWarningShowing_DefaultsToFalse()137     public void testIsInvalidChargerWarningShowing_DefaultsToFalse() {
138         assertFalse(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
139     }
140 
141     @Test
testIsInvalidChargerWarningShowing_TrueAfterShow()142     public void testIsInvalidChargerWarningShowing_TrueAfterShow() {
143         mPowerNotificationWarnings.showInvalidChargerWarning();
144         assertTrue(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
145     }
146 
147     @Test
testIsInvalidChargerWarningShowing_FalseAfterDismiss()148     public void testIsInvalidChargerWarningShowing_FalseAfterDismiss() {
149         mPowerNotificationWarnings.showInvalidChargerWarning();
150         mPowerNotificationWarnings.dismissInvalidChargerWarning();
151         assertFalse(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
152     }
153 
154     @Test
testShowInvalidChargerNotification_NotifyAsUser()155     public void testShowInvalidChargerNotification_NotifyAsUser() {
156         mPowerNotificationWarnings.showInvalidChargerWarning();
157         verify(mMockNotificationManager, times(1))
158                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_BAD_CHARGER), any(), any());
159         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
160                 eq(SystemMessage.NOTE_POWER_LOW), any());
161     }
162 
163     @Test
testDismissInvalidChargerNotification_CancelAsUser()164     public void testDismissInvalidChargerNotification_CancelAsUser() {
165         mPowerNotificationWarnings.showInvalidChargerWarning();
166         mPowerNotificationWarnings.dismissInvalidChargerWarning();
167         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
168                 eq(SystemMessage.NOTE_BAD_CHARGER), any());
169     }
170 
171     @Test
testShowLowBatteryNotification_NotifyAsUser()172     public void testShowLowBatteryNotification_NotifyAsUser() {
173         mPowerNotificationWarnings.showLowBatteryWarning(false);
174         verify(mMockNotificationManager, times(1))
175                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), any(), any());
176         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
177                 eq(SystemMessage.NOTE_BAD_CHARGER), any());
178     }
179 
180     @Test
testDismissLowBatteryNotification_CancelAsUser()181     public void testDismissLowBatteryNotification_CancelAsUser() {
182         mPowerNotificationWarnings.showLowBatteryWarning(false);
183         mPowerNotificationWarnings.dismissLowBatteryWarning();
184         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
185                 eq(SystemMessage.NOTE_POWER_LOW), any());
186     }
187 
188     @Test
testShowLowBatteryNotification_BatteryChannel()189     public void testShowLowBatteryNotification_BatteryChannel() {
190         mPowerNotificationWarnings.showLowBatteryWarning(true);
191         ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class);
192         verify(mMockNotificationManager)
193                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW),
194                         captor.capture(), any());
195         assertTrue(captor.getValue().getChannelId() == NotificationChannels.BATTERY);
196     }
197 
198     @Test
testShowHighTemperatureWarning_NotifyAsUser()199     public void testShowHighTemperatureWarning_NotifyAsUser() {
200         mPowerNotificationWarnings.showHighTemperatureWarning();
201         verify(mMockNotificationManager, times(1))
202                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_HIGH_TEMP), any(), any());
203     }
204 
205     @Test
testDismissHighTemperatureWarning_CancelAsUser()206     public void testDismissHighTemperatureWarning_CancelAsUser() {
207         mPowerNotificationWarnings.showHighTemperatureWarning();
208         mPowerNotificationWarnings.dismissHighTemperatureWarning();
209         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
210                 eq(SystemMessage.NOTE_HIGH_TEMP), any());
211     }
212 
213     @Test
testShowThermalShutdownWarning_NotifyAsUser()214     public void testShowThermalShutdownWarning_NotifyAsUser() {
215         mPowerNotificationWarnings.showThermalShutdownWarning();
216         verify(mMockNotificationManager, times(1))
217                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_THERMAL_SHUTDOWN), any(), any());
218     }
219 
220     @Test
testDismissThermalShutdownWarning_CancelAsUser()221     public void testDismissThermalShutdownWarning_CancelAsUser() {
222         mPowerNotificationWarnings.showThermalShutdownWarning();
223         mPowerNotificationWarnings.dismissThermalShutdownWarning();
224         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
225                 eq(SystemMessage.NOTE_THERMAL_SHUTDOWN), any());
226     }
227 
228     @Test
testShowUsbHighTemperatureAlarm()229     public void testShowUsbHighTemperatureAlarm() {
230         mPowerNotificationWarnings.showUsbHighTemperatureAlarm();
231         waitForIdleSync(mContext.getMainThreadHandler());
232         assertThat(mPowerNotificationWarnings.mUsbHighTempDialog).isNotNull();
233 
234         mPowerNotificationWarnings.mUsbHighTempDialog.dismiss();
235     }
236 
237     @Test
testDialogStartedFromLauncher_viewVisible()238     public void testDialogStartedFromLauncher_viewVisible() {
239         when(mBatteryController.getLastPowerSaverStartExpandable())
240                 .thenReturn(new WeakReference<>(mExpandable));
241         when(mExpandable.dialogTransitionController(any())).thenReturn(mController);
242 
243         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
244         intent.putExtras(new Bundle());
245 
246         mReceiver.onReceive(mContext, intent);
247 
248         verify(mDialogTransitionAnimator).show(any(), eq(mController));
249 
250         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
251     }
252 
253     @Test
testDialogStartedNotFromLauncher_viewNotVisible()254     public void testDialogStartedNotFromLauncher_viewNotVisible() {
255         when(mBatteryController.getLastPowerSaverStartExpandable())
256                 .thenReturn(new WeakReference<>(mExpandable));
257 
258         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
259         intent.putExtras(new Bundle());
260 
261         mReceiver.onReceive(mContext, intent);
262 
263         verify(mDialogTransitionAnimator, never()).show(any(), any());
264 
265         verify(mPowerNotificationWarnings.getSaverConfirmationDialog()).show();
266         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
267     }
268 
269     @Test
testDialogShownNotFromLauncher()270     public void testDialogShownNotFromLauncher() {
271         when(mBatteryController.getLastPowerSaverStartExpandable()).thenReturn(null);
272 
273         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
274         intent.putExtras(new Bundle());
275 
276         mReceiver.onReceive(mContext, intent);
277 
278         verify(mDialogTransitionAnimator, never()).showFromView(any(), any());
279 
280         verify(mPowerNotificationWarnings.getSaverConfirmationDialog()).show();
281         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
282     }
283 }
284