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.test.suitebuilder.annotation.SmallTest;
46 import android.testing.AndroidTestingRunner;
47 import android.testing.TestableLooper;
48 import android.view.View;
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.DialogLaunchAnimator;
55 import com.android.systemui.broadcast.BroadcastSender;
56 import com.android.systemui.plugins.ActivityStarter;
57 import com.android.systemui.settings.UserTracker;
58 import com.android.systemui.statusbar.policy.BatteryController;
59 import com.android.systemui.util.NotificationChannels;
60 import com.android.systemui.util.settings.FakeSettings;
61 import com.android.systemui.util.settings.GlobalSettings;
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(AndroidTestingRunner.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 final GlobalSettings mGlobalSettings = new FakeSettings();
81     private PowerNotificationWarnings mPowerNotificationWarnings;
82 
83     @Mock
84     private BatteryController mBatteryController;
85     @Mock
86     private DialogLaunchAnimator mDialogLaunchAnimator;
87     @Mock
88     private UiEventLogger mUiEventLogger;
89     @Mock
90     private UserTracker mUserTracker;
91     @Mock
92     private View mView;
93 
94     private BroadcastReceiver mReceiver;
95 
96     @Before
setUp()97     public void setUp() throws Exception {
98         MockitoAnnotations.initMocks(this);
99 
100         Context wrapper = new ContextWrapper(mContext) {
101             @Override
102             public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
103                     IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
104                 mReceiver = receiver;
105                 return null;
106             }
107         };
108 
109         // Test Instance.
110         mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
111         ActivityStarter starter = mDependency.injectMockDependency(ActivityStarter.class);
112         BroadcastSender broadcastSender = mDependency.injectMockDependency(BroadcastSender.class);
113         when(mUserTracker.getUserId()).thenReturn(ActivityManager.getCurrentUser());
114         when(mUserTracker.getUserHandle()).thenReturn(
115                 UserHandle.of(ActivityManager.getCurrentUser()));
116         mPowerNotificationWarnings = new PowerNotificationWarnings(wrapper, starter,
117                 broadcastSender, () -> mBatteryController, mDialogLaunchAnimator, mUiEventLogger,
118                 mGlobalSettings, mUserTracker);
119         BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
120                 BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
121         mPowerNotificationWarnings.updateSnapshot(snapshot);
122     }
123 
124     @Test
testIsInvalidChargerWarningShowing_DefaultsToFalse()125     public void testIsInvalidChargerWarningShowing_DefaultsToFalse() {
126         assertFalse(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
127     }
128 
129     @Test
testIsInvalidChargerWarningShowing_TrueAfterShow()130     public void testIsInvalidChargerWarningShowing_TrueAfterShow() {
131         mPowerNotificationWarnings.showInvalidChargerWarning();
132         assertTrue(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
133     }
134 
135     @Test
testIsInvalidChargerWarningShowing_FalseAfterDismiss()136     public void testIsInvalidChargerWarningShowing_FalseAfterDismiss() {
137         mPowerNotificationWarnings.showInvalidChargerWarning();
138         mPowerNotificationWarnings.dismissInvalidChargerWarning();
139         assertFalse(mPowerNotificationWarnings.isInvalidChargerWarningShowing());
140     }
141 
142     @Test
testShowInvalidChargerNotification_NotifyAsUser()143     public void testShowInvalidChargerNotification_NotifyAsUser() {
144         mPowerNotificationWarnings.showInvalidChargerWarning();
145         verify(mMockNotificationManager, times(1))
146                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_BAD_CHARGER), any(), any());
147         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
148                 eq(SystemMessage.NOTE_POWER_LOW), any());
149     }
150 
151     @Test
testDismissInvalidChargerNotification_CancelAsUser()152     public void testDismissInvalidChargerNotification_CancelAsUser() {
153         mPowerNotificationWarnings.showInvalidChargerWarning();
154         mPowerNotificationWarnings.dismissInvalidChargerWarning();
155         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
156                 eq(SystemMessage.NOTE_BAD_CHARGER), any());
157     }
158 
159     @Test
testShowLowBatteryNotification_NotifyAsUser()160     public void testShowLowBatteryNotification_NotifyAsUser() {
161         mPowerNotificationWarnings.showLowBatteryWarning(false);
162         verify(mMockNotificationManager, times(1))
163                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW), any(), any());
164         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
165                 eq(SystemMessage.NOTE_BAD_CHARGER), any());
166     }
167 
168     @Test
testDismissLowBatteryNotification_CancelAsUser()169     public void testDismissLowBatteryNotification_CancelAsUser() {
170         mPowerNotificationWarnings.showLowBatteryWarning(false);
171         mPowerNotificationWarnings.dismissLowBatteryWarning();
172         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
173                 eq(SystemMessage.NOTE_POWER_LOW), any());
174     }
175 
176     @Test
testShowLowBatteryNotification_BatteryChannel()177     public void testShowLowBatteryNotification_BatteryChannel() {
178         mPowerNotificationWarnings.showLowBatteryWarning(true);
179         ArgumentCaptor<Notification> captor = ArgumentCaptor.forClass(Notification.class);
180         verify(mMockNotificationManager)
181                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_POWER_LOW),
182                         captor.capture(), any());
183         assertTrue(captor.getValue().getChannelId() == NotificationChannels.BATTERY);
184     }
185 
186     @Test
testShowHighTemperatureWarning_NotifyAsUser()187     public void testShowHighTemperatureWarning_NotifyAsUser() {
188         mPowerNotificationWarnings.showHighTemperatureWarning();
189         verify(mMockNotificationManager, times(1))
190                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_HIGH_TEMP), any(), any());
191     }
192 
193     @Test
testDismissHighTemperatureWarning_CancelAsUser()194     public void testDismissHighTemperatureWarning_CancelAsUser() {
195         mPowerNotificationWarnings.showHighTemperatureWarning();
196         mPowerNotificationWarnings.dismissHighTemperatureWarning();
197         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
198                 eq(SystemMessage.NOTE_HIGH_TEMP), any());
199     }
200 
201     @Test
testShowThermalShutdownWarning_NotifyAsUser()202     public void testShowThermalShutdownWarning_NotifyAsUser() {
203         mPowerNotificationWarnings.showThermalShutdownWarning();
204         verify(mMockNotificationManager, times(1))
205                 .notifyAsUser(anyString(), eq(SystemMessage.NOTE_THERMAL_SHUTDOWN), any(), any());
206     }
207 
208     @Test
testDismissThermalShutdownWarning_CancelAsUser()209     public void testDismissThermalShutdownWarning_CancelAsUser() {
210         mPowerNotificationWarnings.showThermalShutdownWarning();
211         mPowerNotificationWarnings.dismissThermalShutdownWarning();
212         verify(mMockNotificationManager, times(1)).cancelAsUser(anyString(),
213                 eq(SystemMessage.NOTE_THERMAL_SHUTDOWN), any());
214     }
215 
216     @Test
testShowUsbHighTemperatureAlarm()217     public void testShowUsbHighTemperatureAlarm() {
218         mPowerNotificationWarnings.showUsbHighTemperatureAlarm();
219         waitForIdleSync(mContext.getMainThreadHandler());
220         assertThat(mPowerNotificationWarnings.mUsbHighTempDialog).isNotNull();
221 
222         mPowerNotificationWarnings.mUsbHighTempDialog.dismiss();
223     }
224 
225     @Test
testDialogStartedFromLauncher_viewVisible()226     public void testDialogStartedFromLauncher_viewVisible() {
227         when(mBatteryController.getLastPowerSaverStartView())
228                 .thenReturn(new WeakReference<>(mView));
229         when(mView.isAggregatedVisible()).thenReturn(true);
230 
231         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
232         intent.putExtras(new Bundle());
233 
234         mReceiver.onReceive(mContext, intent);
235 
236         verify(mDialogLaunchAnimator).showFromView(any(), eq(mView), any());
237 
238         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
239     }
240 
241     @Test
testDialogStartedNotFromLauncher_viewNotVisible()242     public void testDialogStartedNotFromLauncher_viewNotVisible() {
243         when(mBatteryController.getLastPowerSaverStartView())
244                 .thenReturn(new WeakReference<>(mView));
245         when(mView.isAggregatedVisible()).thenReturn(false);
246 
247         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
248         intent.putExtras(new Bundle());
249 
250         mReceiver.onReceive(mContext, intent);
251 
252         verify(mDialogLaunchAnimator, never()).showFromView(any(), any());
253 
254         assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue();
255         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
256     }
257 
258     @Test
testDialogShownNotFromLauncher()259     public void testDialogShownNotFromLauncher() {
260         when(mBatteryController.getLastPowerSaverStartView()).thenReturn(null);
261 
262         Intent intent = new Intent(BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION);
263         intent.putExtras(new Bundle());
264 
265         mReceiver.onReceive(mContext, intent);
266 
267         verify(mDialogLaunchAnimator, never()).showFromView(any(), any());
268 
269         assertThat(mPowerNotificationWarnings.getSaverConfirmationDialog().isShowing()).isTrue();
270         mPowerNotificationWarnings.getSaverConfirmationDialog().dismiss();
271     }
272 }
273