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