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