1 /* 2 * Copyright (C) 2018 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.server.wifi; 18 19 import static com.android.server.wifi.WakeupNotificationFactory.ACTION_DISMISS_NOTIFICATION; 20 import static com.android.server.wifi.WakeupNotificationFactory.ACTION_OPEN_WIFI_PREFERENCES; 21 import static com.android.server.wifi.WakeupNotificationFactory.ACTION_TURN_OFF_WIFI_WAKE; 22 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertTrue; 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.eq; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.NotificationManager; 33 import android.content.BroadcastReceiver; 34 import android.content.Context; 35 import android.content.Intent; 36 import android.content.IntentFilter; 37 import android.os.Handler; 38 import android.os.test.TestLooper; 39 import android.provider.Settings; 40 41 import androidx.test.filters.SmallTest; 42 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.mockito.ArgumentCaptor; 46 import org.mockito.InOrder; 47 import org.mockito.Mock; 48 import org.mockito.Mockito; 49 import org.mockito.MockitoAnnotations; 50 51 /** Unit tests for {@link com.android.server.wifi.WakeupOnboarding} */ 52 @SmallTest 53 public class WakeupOnboardingTest { 54 55 @Mock private Context mContext; 56 @Mock private WifiConfigManager mWifiConfigManager; 57 @Mock private FrameworkFacade mFrameworkFacade; 58 @Mock private WakeupNotificationFactory mWakeupNotificationFactory; 59 @Mock private NotificationManager mNotificationManager; 60 61 private TestLooper mLooper; 62 private WakeupOnboarding mWakeupOnboarding; 63 64 // convenience method for resetting onboarded status setOnboardedStatus(boolean isOnboarded)65 private void setOnboardedStatus(boolean isOnboarded) { 66 mWakeupOnboarding.getIsOnboadedDataSource().setData(isOnboarded); 67 } 68 setNotificationsShown(int numNotifications)69 private void setNotificationsShown(int numNotifications) { 70 mWakeupOnboarding.getNotificationsDataSource().setData(numNotifications); 71 } 72 73 @Before setUp()74 public void setUp() { 75 MockitoAnnotations.initMocks(this); 76 77 when(mContext.getSystemService(Context.NOTIFICATION_SERVICE)) 78 .thenReturn(mNotificationManager); 79 80 mLooper = new TestLooper(); 81 mWakeupOnboarding = new WakeupOnboarding(mContext, mWifiConfigManager, mLooper.getLooper(), 82 mFrameworkFacade, mWakeupNotificationFactory); 83 } 84 85 /** 86 * Verify that the notification shows if the user isn't onboarded. 87 */ 88 @Test showsNotificationIfNotOnboarded()89 public void showsNotificationIfNotOnboarded() { 90 setOnboardedStatus(false); 91 mWakeupOnboarding.maybeShowNotification(); 92 93 verify(mNotificationManager).notify(eq(WakeupNotificationFactory.ONBOARD_ID), any()); 94 } 95 96 /** 97 * Verify that the notification does not show if the user is onboarded. 98 */ 99 @Test doesNotShowNotificationIfAlreadyOnboarded()100 public void doesNotShowNotificationIfAlreadyOnboarded() { 101 setOnboardedStatus(true); 102 mWakeupOnboarding.maybeShowNotification(); 103 104 verify(mNotificationManager, never()) 105 .notify(eq(WakeupNotificationFactory.ONBOARD_ID), any()); 106 } 107 108 /** 109 * Verify that the notification does not relaunch if it's already showing. 110 */ 111 @Test doesNotShowNotificationIfAlreadyShowing()112 public void doesNotShowNotificationIfAlreadyShowing() { 113 setOnboardedStatus(false); 114 mWakeupOnboarding.maybeShowNotification(); 115 mWakeupOnboarding.maybeShowNotification(); 116 117 InOrder inOrder = Mockito.inOrder(mNotificationManager); 118 inOrder.verify(mNotificationManager) 119 .notify(eq(WakeupNotificationFactory.ONBOARD_ID), any()); 120 inOrder.verifyNoMoreInteractions(); 121 } 122 123 /** 124 * Verify that the user is onboarded when the notification is dismissed. 125 */ 126 @Test dismissNotificationAction_setsOnboarded()127 public void dismissNotificationAction_setsOnboarded() { 128 setOnboardedStatus(false); 129 assertFalse(mWakeupOnboarding.isOnboarded()); 130 131 mWakeupOnboarding.maybeShowNotification(); 132 ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); 133 verify(mContext).registerReceiver(captor.capture(), any(IntentFilter.class), any(), 134 any(Handler.class)); 135 BroadcastReceiver broadcastReceiver = captor.getValue(); 136 137 broadcastReceiver.onReceive(mContext, new Intent(ACTION_DISMISS_NOTIFICATION)); 138 139 verify(mNotificationManager).cancel(WakeupNotificationFactory.ONBOARD_ID); 140 assertTrue(mWakeupOnboarding.isOnboarded()); 141 } 142 143 /** 144 * Verify that the user is onboarded and Wifi Wake is turned off when the user selects the 145 * ACTION_TURN_OFF_WIFI_WAKE action. 146 */ 147 @Test turnOffWifiWakeAction_setsOnboardedAndTurnsOffWifiWake()148 public void turnOffWifiWakeAction_setsOnboardedAndTurnsOffWifiWake() { 149 setOnboardedStatus(false); 150 assertFalse(mWakeupOnboarding.isOnboarded()); 151 152 mWakeupOnboarding.maybeShowNotification(); 153 ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); 154 verify(mContext).registerReceiver(captor.capture(), any(IntentFilter.class), any(), 155 any(Handler.class)); 156 BroadcastReceiver broadcastReceiver = captor.getValue(); 157 158 broadcastReceiver.onReceive(mContext, new Intent(ACTION_TURN_OFF_WIFI_WAKE)); 159 160 verify(mFrameworkFacade).setIntegerSetting(mContext, 161 Settings.Global.WIFI_WAKEUP_ENABLED, 0); 162 163 verify(mNotificationManager).cancel(WakeupNotificationFactory.ONBOARD_ID); 164 assertTrue(mWakeupOnboarding.isOnboarded()); 165 } 166 167 /** 168 * Verify that the user is onboarded and sent to WifiSettings when the user selects the 169 * ACTION_OPEN_WIFI_SETTINGS action. 170 */ 171 @Test openWifiSettingsAction_setsOnboardedAndOpensWifiSettings()172 public void openWifiSettingsAction_setsOnboardedAndOpensWifiSettings() { 173 setOnboardedStatus(false); 174 assertFalse(mWakeupOnboarding.isOnboarded()); 175 176 mWakeupOnboarding.maybeShowNotification(); 177 ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class); 178 verify(mContext).registerReceiver(captor.capture(), any(IntentFilter.class), any(), 179 any(Handler.class)); 180 BroadcastReceiver broadcastReceiver = captor.getValue(); 181 182 broadcastReceiver.onReceive(mContext, new Intent(ACTION_OPEN_WIFI_PREFERENCES)); 183 184 verify(mContext).startActivity(any()); 185 186 verify(mNotificationManager).cancel(WakeupNotificationFactory.ONBOARD_ID); 187 assertTrue(mWakeupOnboarding.isOnboarded()); 188 } 189 190 /** 191 * Verify that onStop() doesn't onboard the user. 192 */ 193 @Test onStopDismissesNotificationWithoutOnboarding()194 public void onStopDismissesNotificationWithoutOnboarding() { 195 setOnboardedStatus(false); 196 assertFalse(mWakeupOnboarding.isOnboarded()); 197 198 mWakeupOnboarding.maybeShowNotification(); 199 mWakeupOnboarding.onStop(); 200 201 verify(mNotificationManager).cancel(WakeupNotificationFactory.ONBOARD_ID); 202 assertFalse(mWakeupOnboarding.isOnboarded()); 203 } 204 205 /** 206 * Verify that incrementing the notification count saves to store. 207 */ 208 @Test setOnboardedSavesToStore()209 public void setOnboardedSavesToStore() { 210 setOnboardedStatus(false); 211 mWakeupOnboarding.setOnboarded(); 212 verify(mWifiConfigManager).saveToStore(false /* forceWrite */); 213 assertTrue(mWakeupOnboarding.isOnboarded()); 214 } 215 216 /** 217 * Verify that incrementing the notification count saves to store. 218 */ 219 @Test incrementingNotificationCountSavesToStore()220 public void incrementingNotificationCountSavesToStore() { 221 setOnboardedStatus(false); 222 setNotificationsShown(0); 223 mWakeupOnboarding.maybeShowNotification(); 224 verify(mWifiConfigManager).saveToStore(false /* forceWrite */); 225 } 226 227 /** 228 * Verify that the notification does not show multiple times within 24 hours. 229 */ 230 @Test doesNotShowMultipleNotificationsWithin24Hours()231 public void doesNotShowMultipleNotificationsWithin24Hours() { 232 setOnboardedStatus(false); 233 setNotificationsShown(0); 234 235 mWakeupOnboarding.maybeShowNotification(0 /* timestamp */); 236 mWakeupOnboarding.onStop(); 237 mWakeupOnboarding.maybeShowNotification(0 /* timestamp */); 238 239 InOrder inOrder = Mockito.inOrder(mNotificationManager); 240 inOrder.verify(mNotificationManager) 241 .notify(eq(WakeupNotificationFactory.ONBOARD_ID), any()); 242 inOrder.verify(mNotificationManager).cancel(WakeupNotificationFactory.ONBOARD_ID); 243 inOrder.verifyNoMoreInteractions(); 244 } 245 246 /** 247 * Verify that notification reappears after 24 hours if not onboarded. 248 */ 249 @Test showsNotificationsOutsideOf24Hours()250 public void showsNotificationsOutsideOf24Hours() { 251 setOnboardedStatus(false); 252 setNotificationsShown(0); 253 254 mWakeupOnboarding.maybeShowNotification(0 /* timestamp */); 255 assertFalse(mWakeupOnboarding.isOnboarded()); 256 257 mWakeupOnboarding.onStop(); 258 mWakeupOnboarding.maybeShowNotification(WakeupOnboarding.REQUIRED_NOTIFICATION_DELAY + 1); 259 260 verify(mNotificationManager, times(2)) 261 .notify(eq(WakeupNotificationFactory.ONBOARD_ID), any()); 262 } 263 264 /** 265 * Verify that the user is onboarded after 266 * {@link WakeupOnboarding#NOTIFICATIONS_UNTIL_ONBOARDED} notifications are shown. 267 */ 268 @Test onboardsUserAfterThreeNotifications()269 public void onboardsUserAfterThreeNotifications() { 270 setOnboardedStatus(false); 271 setNotificationsShown(WakeupOnboarding.NOTIFICATIONS_UNTIL_ONBOARDED - 1); 272 273 mWakeupOnboarding.maybeShowNotification(0 /* timestamp */); 274 assertTrue(mWakeupOnboarding.isOnboarded()); 275 } 276 } 277