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