Home | History | Annotate | Download | only in wifi
      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.server.wifi;
     18 
     19 import static android.net.wifi.WifiManager.HOTSPOT_FAILED;
     20 import static android.net.wifi.WifiManager.HOTSPOT_STARTED;
     21 import static android.net.wifi.WifiManager.HOTSPOT_STOPPED;
     22 import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
     23 import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
     24 import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
     25 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
     26 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
     27 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
     28 import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
     29 import static android.net.wifi.WifiManager.SAP_START_FAILURE_GENERAL;
     30 import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL;
     31 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
     32 import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
     33 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
     34 import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
     35 import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
     36 import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
     37 import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
     38 import static android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY;
     39 import static android.provider.Settings.Secure.LOCATION_MODE_OFF;
     40 
     41 import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
     42 import static com.android.server.wifi.WifiController.CMD_SET_AP;
     43 import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
     44 
     45 import static org.junit.Assert.assertEquals;
     46 import static org.junit.Assert.assertFalse;
     47 import static org.junit.Assert.assertNotNull;
     48 import static org.junit.Assert.assertNull;
     49 import static org.junit.Assert.assertTrue;
     50 import static org.junit.Assert.fail;
     51 import static org.mockito.Matchers.any;
     52 import static org.mockito.Matchers.anyString;
     53 import static org.mockito.Matchers.eq;
     54 import static org.mockito.Mockito.*;
     55 import static org.mockito.Mockito.atLeastOnce;
     56 
     57 import android.app.ActivityManager;
     58 import android.app.AppOpsManager;
     59 import android.content.BroadcastReceiver;
     60 import android.content.ContentResolver;
     61 import android.content.Context;
     62 import android.content.Intent;
     63 import android.content.IntentFilter;
     64 import android.content.pm.ApplicationInfo;
     65 import android.content.pm.PackageManager;
     66 import android.content.res.Resources;
     67 import android.net.Uri;
     68 import android.net.wifi.ISoftApCallback;
     69 import android.net.wifi.ScanResult;
     70 import android.net.wifi.WifiConfiguration;
     71 import android.net.wifi.WifiConfiguration.KeyMgmt;
     72 import android.net.wifi.WifiEnterpriseConfig;
     73 import android.net.wifi.WifiInfo;
     74 import android.net.wifi.WifiManager;
     75 import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
     76 import android.net.wifi.WifiManager.SoftApCallback;
     77 import android.net.wifi.WifiSsid;
     78 import android.net.wifi.hotspot2.IProvisioningCallback;
     79 import android.net.wifi.hotspot2.OsuProvider;
     80 import android.net.wifi.hotspot2.PasspointConfiguration;
     81 import android.os.Binder;
     82 import android.os.Handler;
     83 import android.os.HandlerThread;
     84 import android.os.IBinder;
     85 import android.os.IPowerManager;
     86 import android.os.Looper;
     87 import android.os.Message;
     88 import android.os.Messenger;
     89 import android.os.PowerManager;
     90 import android.os.Process;
     91 import android.os.RemoteException;
     92 import android.os.UserManager;
     93 import android.os.test.TestLooper;
     94 import android.support.test.filters.SmallTest;
     95 
     96 import com.android.internal.os.PowerProfile;
     97 import com.android.internal.telephony.TelephonyIntents;
     98 import com.android.internal.util.AsyncChannel;
     99 import com.android.server.wifi.WifiServiceImpl.LocalOnlyRequestorCallback;
    100 import com.android.server.wifi.hotspot2.PasspointProvisioningTestUtil;
    101 import com.android.server.wifi.util.WifiAsyncChannel;
    102 import com.android.server.wifi.util.WifiPermissionsUtil;
    103 import com.android.server.wifi.util.WifiPermissionsWrapper;
    104 
    105 import org.junit.Before;
    106 import org.junit.Ignore;
    107 import org.junit.Test;
    108 import org.mockito.ArgumentCaptor;
    109 import org.mockito.ArgumentMatcher;
    110 import org.mockito.Mock;
    111 import org.mockito.MockitoAnnotations;
    112 import org.mockito.Spy;
    113 
    114 import java.io.FileDescriptor;
    115 import java.io.PrintWriter;
    116 import java.io.StringWriter;
    117 import java.util.ArrayList;
    118 import java.util.Arrays;
    119 import java.util.List;
    120 
    121 /**
    122  * Unit tests for {@link WifiServiceImpl}.
    123  *
    124  * Note: this is intended to build up over time and will not immediately cover the entire file.
    125  */
    126 @SmallTest
    127 public class WifiServiceImplTest {
    128 
    129     private static final String TAG = "WifiServiceImplTest";
    130     private static final String SCAN_PACKAGE_NAME = "scanPackage";
    131     private static final int DEFAULT_VERBOSE_LOGGING = 0;
    132     private static final String ANDROID_SYSTEM_PACKAGE = "android";
    133     private static final String TEST_PACKAGE_NAME = "TestPackage";
    134     private static final String SYSUI_PACKAGE_NAME = "com.android.systemui";
    135     private static final int TEST_PID = 6789;
    136     private static final int TEST_PID2 = 9876;
    137     private static final int TEST_UID = 1200000;
    138     private static final int OTHER_TEST_UID = 1300000;
    139     private static final int TEST_USER_HANDLE = 13;
    140     private static final String WIFI_IFACE_NAME = "wlan0";
    141     private static final String TEST_COUNTRY_CODE = "US";
    142 
    143     private WifiServiceImpl mWifiServiceImpl;
    144     private TestLooper mLooper;
    145     private PowerManager mPowerManager;
    146     private Handler mHandler;
    147     private Handler mHandlerSpyForWsmRunWithScissors;
    148     private Messenger mAppMessenger;
    149     private int mPid;
    150     private int mPid2 = Process.myPid();
    151     private OsuProvider mOsuProvider;
    152     private SoftApCallback mStateMachineSoftApCallback;
    153 
    154     final ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor =
    155             ArgumentCaptor.forClass(BroadcastReceiver.class);
    156     final ArgumentCaptor<IntentFilter> mIntentFilterCaptor =
    157             ArgumentCaptor.forClass(IntentFilter.class);
    158 
    159     final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class);
    160     final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor =
    161             ArgumentCaptor.forClass(SoftApModeConfiguration.class);
    162 
    163     @Mock Context mContext;
    164     @Mock WifiInjector mWifiInjector;
    165     @Mock WifiCountryCode mWifiCountryCode;
    166     @Mock Clock mClock;
    167     @Mock WifiController mWifiController;
    168     @Mock WifiTrafficPoller mWifiTrafficPoller;
    169     @Mock WifiStateMachine mWifiStateMachine;
    170     @Mock WifiStateMachinePrime mWifiStateMachinePrime;
    171     @Mock HandlerThread mHandlerThread;
    172     @Mock AsyncChannel mAsyncChannel;
    173     @Mock Resources mResources;
    174     @Mock ApplicationInfo mApplicationInfo;
    175     @Mock FrameworkFacade mFrameworkFacade;
    176     @Mock WifiLockManager mLockManager;
    177     @Mock WifiMulticastLockManager mWifiMulticastLockManager;
    178     @Mock WifiLastResortWatchdog mWifiLastResortWatchdog;
    179     @Mock WifiBackupRestore mWifiBackupRestore;
    180     @Mock WifiMetrics mWifiMetrics;
    181     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
    182     @Mock WifiPermissionsWrapper mWifiPermissionsWrapper;
    183     @Mock WifiSettingsStore mSettingsStore;
    184     @Mock ContentResolver mContentResolver;
    185     @Mock PackageManager mPackageManager;
    186     @Mock UserManager mUserManager;
    187     @Mock WifiApConfigStore mWifiApConfigStore;
    188     @Mock WifiConfiguration mApConfig;
    189     @Mock ActivityManager mActivityManager;
    190     @Mock AppOpsManager mAppOpsManager;
    191     @Mock IBinder mAppBinder;
    192     @Mock LocalOnlyHotspotRequestInfo mRequestInfo;
    193     @Mock LocalOnlyHotspotRequestInfo mRequestInfo2;
    194     @Mock IProvisioningCallback mProvisioningCallback;
    195     @Mock ISoftApCallback mClientSoftApCallback;
    196     @Mock ISoftApCallback mAnotherSoftApCallback;
    197     @Mock PowerProfile mPowerProfile;
    198     @Mock WifiTrafficPoller mWifiTrafficPolller;
    199     @Mock ScanRequestProxy mScanRequestProxy;
    200 
    201     @Spy FakeWifiLog mLog;
    202 
    203     private class WifiAsyncChannelTester {
    204         private static final String TAG = "WifiAsyncChannelTester";
    205         public static final int CHANNEL_STATE_FAILURE = -1;
    206         public static final int CHANNEL_STATE_DISCONNECTED = 0;
    207         public static final int CHANNEL_STATE_HALF_CONNECTED = 1;
    208         public static final int CHANNEL_STATE_FULLY_CONNECTED = 2;
    209 
    210         private int mState = CHANNEL_STATE_DISCONNECTED;
    211         private WifiAsyncChannel mChannel;
    212         private WifiLog mAsyncTestLog;
    213 
    214         WifiAsyncChannelTester(WifiInjector wifiInjector) {
    215             mAsyncTestLog = wifiInjector.makeLog(TAG);
    216         }
    217 
    218         public int getChannelState() {
    219             return mState;
    220         }
    221 
    222         public void connect(final Looper looper, final Messenger messenger,
    223                 final Handler incomingMessageHandler) {
    224             assertEquals("AsyncChannel must be in disconnected state",
    225                     CHANNEL_STATE_DISCONNECTED, mState);
    226             mChannel = new WifiAsyncChannel(TAG);
    227             mChannel.setWifiLog(mLog);
    228             Handler handler = new Handler(mLooper.getLooper()) {
    229                 @Override
    230                 public void handleMessage(Message msg) {
    231                     switch (msg.what) {
    232                         case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
    233                             if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
    234                                 mChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
    235                                 mState = CHANNEL_STATE_HALF_CONNECTED;
    236                             } else {
    237                                 mState = CHANNEL_STATE_FAILURE;
    238                             }
    239                             break;
    240                         case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
    241                             mState = CHANNEL_STATE_FULLY_CONNECTED;
    242                             break;
    243                         case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
    244                             mState = CHANNEL_STATE_DISCONNECTED;
    245                             break;
    246                         default:
    247                             incomingMessageHandler.handleMessage(msg);
    248                             break;
    249                     }
    250                 }
    251             };
    252             mChannel.connect(null, handler, messenger);
    253         }
    254 
    255         private Message sendMessageSynchronously(Message request) {
    256             return mChannel.sendMessageSynchronously(request);
    257         }
    258 
    259         private void sendMessage(Message request) {
    260             mChannel.sendMessage(request);
    261         }
    262     }
    263 
    264     @Before public void setUp() {
    265         MockitoAnnotations.initMocks(this);
    266         mLooper = new TestLooper();
    267         mHandler = spy(new Handler(mLooper.getLooper()));
    268         mAppMessenger = new Messenger(mHandler);
    269 
    270         when(mRequestInfo.getPid()).thenReturn(mPid);
    271         when(mRequestInfo2.getPid()).thenReturn(mPid2);
    272         when(mWifiInjector.getUserManager()).thenReturn(mUserManager);
    273         when(mWifiInjector.getWifiCountryCode()).thenReturn(mWifiCountryCode);
    274         when(mWifiInjector.getWifiController()).thenReturn(mWifiController);
    275         when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics);
    276         when(mWifiInjector.getWifiStateMachine()).thenReturn(mWifiStateMachine);
    277         when(mWifiStateMachine.syncInitialize(any())).thenReturn(true);
    278         when(mWifiInjector.getWifiStateMachinePrime()).thenReturn(mWifiStateMachinePrime);
    279         when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread);
    280         when(mWifiInjector.getPowerProfile()).thenReturn(mPowerProfile);
    281         when(mHandlerThread.getLooper()).thenReturn(mLooper.getLooper());
    282         when(mContext.getResources()).thenReturn(mResources);
    283         when(mContext.getContentResolver()).thenReturn(mContentResolver);
    284         when(mContext.getPackageManager()).thenReturn(mPackageManager);
    285         when(mWifiInjector.getWifiApConfigStore()).thenReturn(mWifiApConfigStore);
    286         doNothing().when(mFrameworkFacade).registerContentObserver(eq(mContext), any(),
    287                 anyBoolean(), any());
    288         when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
    289         when(mContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
    290         IPowerManager powerManagerService = mock(IPowerManager.class);
    291         mPowerManager = new PowerManager(mContext, powerManagerService, new Handler());
    292         when(mContext.getSystemServiceName(PowerManager.class)).thenReturn(Context.POWER_SERVICE);
    293         when(mContext.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
    294         WifiAsyncChannel wifiAsyncChannel = new WifiAsyncChannel("WifiServiceImplTest");
    295         wifiAsyncChannel.setWifiLog(mLog);
    296         when(mFrameworkFacade.makeWifiAsyncChannel(anyString())).thenReturn(wifiAsyncChannel);
    297         when(mWifiInjector.getFrameworkFacade()).thenReturn(mFrameworkFacade);
    298         when(mWifiInjector.getWifiLockManager()).thenReturn(mLockManager);
    299         when(mWifiInjector.getWifiMulticastLockManager()).thenReturn(mWifiMulticastLockManager);
    300         when(mWifiInjector.getWifiLastResortWatchdog()).thenReturn(mWifiLastResortWatchdog);
    301         when(mWifiInjector.getWifiBackupRestore()).thenReturn(mWifiBackupRestore);
    302         when(mWifiInjector.makeLog(anyString())).thenReturn(mLog);
    303         when(mWifiInjector.getWifiTrafficPoller()).thenReturn(mWifiTrafficPoller);
    304         when(mWifiInjector.getWifiPermissionsUtil()).thenReturn(mWifiPermissionsUtil);
    305         when(mWifiInjector.getWifiPermissionsWrapper()).thenReturn(mWifiPermissionsWrapper);
    306         when(mWifiInjector.getWifiSettingsStore()).thenReturn(mSettingsStore);
    307         when(mWifiInjector.getClock()).thenReturn(mClock);
    308         when(mWifiInjector.getScanRequestProxy()).thenReturn(mScanRequestProxy);
    309         when(mWifiStateMachine.syncStartSubscriptionProvisioning(anyInt(),
    310                 any(OsuProvider.class), any(IProvisioningCallback.class), any())).thenReturn(true);
    311         when(mPackageManager.hasSystemFeature(
    312                 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
    313         // Create an OSU provider that can be provisioned via an open OSU AP
    314         mOsuProvider = PasspointProvisioningTestUtil.generateOsuProvider(true);
    315         when(mContext.getOpPackageName()).thenReturn(TEST_PACKAGE_NAME);
    316         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
    317                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
    318         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(true);
    319 
    320         ArgumentCaptor<SoftApCallback> softApCallbackCaptor =
    321                 ArgumentCaptor.forClass(SoftApCallback.class);
    322         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    323         verify(mWifiStateMachinePrime).registerSoftApCallback(softApCallbackCaptor.capture());
    324         mStateMachineSoftApCallback = softApCallbackCaptor.getValue();
    325         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
    326     }
    327 
    328     private WifiAsyncChannelTester verifyAsyncChannelHalfConnected() throws RemoteException {
    329         WifiAsyncChannelTester channelTester = new WifiAsyncChannelTester(mWifiInjector);
    330         Handler handler = mock(Handler.class);
    331         TestLooper looper = new TestLooper();
    332         channelTester.connect(looper.getLooper(),
    333                 mWifiServiceImpl.getWifiServiceMessenger(TEST_PACKAGE_NAME), handler);
    334         mLooper.dispatchAll();
    335         assertEquals("AsyncChannel must be half connected",
    336                 WifiAsyncChannelTester.CHANNEL_STATE_HALF_CONNECTED,
    337                 channelTester.getChannelState());
    338         return channelTester;
    339     }
    340 
    341     /**
    342      * Verifies that any operations on WifiServiceImpl without setting up the WifiStateMachine
    343      * channel would fail.
    344      */
    345     @Test
    346     public void testRemoveNetworkUnknown() {
    347         assertFalse(mWifiServiceImpl.removeNetwork(-1, TEST_PACKAGE_NAME));
    348         verify(mWifiStateMachine, never()).syncRemoveNetwork(any(), anyInt());
    349     }
    350 
    351     /**
    352      * Tests whether we're able to set up an async channel connection with WifiServiceImpl.
    353      * This is the path used by some WifiManager public API calls.
    354      */
    355     @Test
    356     public void testAsyncChannelHalfConnected() throws RemoteException {
    357         verifyAsyncChannelHalfConnected();
    358     }
    359 
    360     /**
    361      * Ensure WifiMetrics.dump() is the only dump called when 'dumpsys wifi WifiMetricsProto' is
    362      * called. This is required to support simple metrics collection via dumpsys
    363      */
    364     @Test
    365     public void testWifiMetricsDump() {
    366         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()),
    367                 new String[]{mWifiMetrics.PROTO_DUMP_ARG});
    368         verify(mWifiMetrics)
    369                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
    370         verify(mWifiStateMachine, never())
    371                 .dump(any(FileDescriptor.class), any(PrintWriter.class), any(String[].class));
    372     }
    373 
    374     /**
    375      * Ensure WifiServiceImpl.dump() doesn't throw an NPE when executed with null args
    376      */
    377     @Test
    378     public void testDumpNullArgs() {
    379         mWifiServiceImpl.dump(new FileDescriptor(), new PrintWriter(new StringWriter()), null);
    380     }
    381 
    382     /**
    383      * Verify that wifi can be enabled by a caller with WIFI_STATE_CHANGE permission when wifi is
    384      * off (no hotspot, no airplane mode).
    385      *
    386      * Note: hotspot is disabled by default
    387      */
    388     @Test
    389     public void testSetWifiEnabledSuccess() throws Exception {
    390         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    391         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    392         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    393         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    394     }
    395 
    396     /**
    397      * Verify that the CMD_TOGGLE_WIFI message won't be sent if wifi is already on.
    398      */
    399     @Test
    400     public void testSetWifiEnabledNoToggle() throws Exception {
    401         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(false);
    402         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    403         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    404     }
    405 
    406     /**
    407      * Verify a SecurityException is thrown if a caller does not have the correct permission to
    408      * toggle wifi.
    409      */
    410     @Test
    411     public void testSetWifiEnableWithoutPermission() throws Exception {
    412         doThrow(new SecurityException()).when(mContext)
    413                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
    414                                                 eq("WifiService"));
    415         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    416         try {
    417             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
    418             fail();
    419         } catch (SecurityException e) {
    420 
    421         }
    422 
    423     }
    424 
    425     /**
    426      * Verify a SecurityException is thrown if OPSTR_CHANGE_WIFI_STATE is disabled for the app.
    427      */
    428     @Test
    429     public void testSetWifiEnableAppOpsRejected() throws Exception {
    430         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    431         doThrow(new SecurityException()).when(mAppOpsManager)
    432                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
    433         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    434         try {
    435             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
    436             fail();
    437         } catch (SecurityException e) {
    438 
    439         }
    440         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    441     }
    442 
    443     /**
    444      * Verify a SecurityException is thrown if OP_CHANGE_WIFI_STATE is set to MODE_IGNORED
    445      * for the app.
    446      */
    447     @Test // No exception expected, but the operation should not be done
    448     public void testSetWifiEnableAppOpsIgnored() throws Exception {
    449         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    450         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
    451                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
    452 
    453         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    454         mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
    455         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    456     }
    457 
    458     /**
    459      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
    460      * are in airplane mode.
    461      */
    462     @Test
    463     public void testSetWifiEnabledFromNetworkSettingsHolderWhenInAirplaneMode() throws Exception {
    464         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    465         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
    466         when(mContext.checkPermission(
    467                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
    468                         .thenReturn(PackageManager.PERMISSION_GRANTED);
    469         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
    470         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    471     }
    472 
    473     /**
    474      * Verify that a caller without the NETWORK_SETTINGS permission can't enable wifi
    475      * if we are in airplane mode.
    476      */
    477     @Test
    478     public void testSetWifiEnabledFromAppFailsWhenInAirplaneMode() throws Exception {
    479         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    480         when(mSettingsStore.isAirplaneModeOn()).thenReturn(true);
    481         when(mContext.checkPermission(
    482                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
    483                         .thenReturn(PackageManager.PERMISSION_DENIED);
    484         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    485         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    486     }
    487 
    488     /**
    489      * Verify that a call from an app with the NETWORK_SETTINGS permission can enable wifi if we
    490      * are in softap mode.
    491      */
    492     @Test
    493     public void testSetWifiEnabledFromNetworkSettingsHolderWhenApEnabled() throws Exception {
    494         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    495         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    496         mWifiServiceImpl.checkAndStartWifi();
    497 
    498         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
    499                 (IntentFilter) argThat(new IntentFilterMatcher()));
    500 
    501         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
    502                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
    503                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
    504 
    505         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    506         when(mContext.checkPermission(
    507                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
    508                         .thenReturn(PackageManager.PERMISSION_GRANTED);
    509         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    510         assertTrue(mWifiServiceImpl.setWifiEnabled(SYSUI_PACKAGE_NAME, true));
    511         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    512     }
    513 
    514     /**
    515      * Verify that a call from an app cannot enable wifi if we are in softap mode.
    516      */
    517     @Test
    518     public void testSetWifiEnabledFromAppFailsWhenApEnabled() throws Exception {
    519         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    520         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    521         mWifiServiceImpl.checkAndStartWifi();
    522 
    523         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
    524                 (IntentFilter) argThat(new IntentFilterMatcher()));
    525 
    526         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
    527                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_ENABLING, SAP_START_FAILURE_GENERAL,
    528                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
    529 
    530         when(mContext.checkPermission(
    531                 eq(android.Manifest.permission.NETWORK_SETTINGS), anyInt(), anyInt()))
    532                         .thenReturn(PackageManager.PERMISSION_DENIED);
    533         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    534         assertFalse(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    535         verify(mSettingsStore, never()).handleWifiToggled(anyBoolean());
    536         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    537     }
    538 
    539     /**
    540      * Verify that wifi can be enabled without consent UI popup when permission
    541      * review is required but got permission granted.
    542      */
    543     @Test
    544     public void testSetWifiEnabledSuccessWhenPermissionReviewRequiredAndPermissionGranted()
    545             throws Exception {
    546         // Set PermissionReviewRequired to true explicitly
    547         when(mResources.getBoolean(anyInt())).thenReturn(true);
    548         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    549         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    550         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    551         when(mContext.checkCallingPermission(
    552                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    553                         .thenReturn(PackageManager.PERMISSION_GRANTED);
    554 
    555         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    556         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    557     }
    558 
    559     /**
    560      * Verify that wifi is not enabled but got consent UI popup when permission
    561      * review is required but do not have permission.
    562      */
    563     @Test
    564     public void testSetWifiEnabledConsentUiWhenPermissionReviewRequiredAndPermissionDenied()
    565             throws Exception {
    566         // Set PermissionReviewRequired to true explicitly
    567         when(mResources.getBoolean(anyInt())).thenReturn(true);
    568         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    569         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    570         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    571         when(mContext.checkCallingPermission(
    572                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    573                         .thenReturn(PackageManager.PERMISSION_DENIED);
    574         when(mPackageManager.getApplicationInfoAsUser(
    575                 anyString(), anyInt(), anyInt()))
    576                         .thenReturn(mApplicationInfo);
    577         mApplicationInfo.uid = TEST_UID;
    578         int uid = Binder.getCallingUid();
    579         BinderUtil.setUid(TEST_UID);
    580 
    581         try {
    582             assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    583         } finally {
    584             BinderUtil.setUid(uid);
    585         }
    586 
    587         verify(mContext).startActivity(any());
    588         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    589     }
    590 
    591     /**
    592      * Verify that wifi can be enabled when wifi is off and permission review is
    593      * not required.
    594      */
    595     @Test
    596     public void testSetWifiEnabledSuccessWhenPermissionReviewNotRequired() throws Exception {
    597         // Set PermissionReviewRequired to false explicitly
    598         when(mResources.getBoolean(anyInt())).thenReturn(false);
    599         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    600         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    601         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    602 
    603         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true));
    604         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    605     }
    606 
    607     /**
    608      * Verify a SecurityException is thrown when bringing up Consent UI but caller
    609      * uid does not match application uid.
    610      *
    611      * @throws SecurityException
    612      */
    613     @Test
    614     public void testSetWifiEnabledThrowsSecurityExceptionForConsentUiIfUidNotMatch()
    615             throws Exception {
    616         // Set PermissionReviewRequired to true explicitly
    617         when(mResources.getBoolean(anyInt())).thenReturn(true);
    618         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    619         when(mSettingsStore.handleWifiToggled(eq(true))).thenReturn(true);
    620         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    621         when(mContext.checkCallingPermission(
    622                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    623                         .thenReturn(PackageManager.PERMISSION_DENIED);
    624         when(mPackageManager.getApplicationInfoAsUser(
    625                 anyString(), anyInt(), anyInt()))
    626                         .thenReturn(mApplicationInfo);
    627         mApplicationInfo.uid = TEST_UID;
    628         int uid = Binder.getCallingUid();
    629         BinderUtil.setUid(OTHER_TEST_UID);
    630 
    631         try {
    632             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, true);
    633             fail();
    634         } catch (SecurityException e) {
    635         } finally {
    636             BinderUtil.setUid(uid);
    637         }
    638     }
    639 
    640     /**
    641      * Verify that wifi can be disabled by a caller with WIFI_STATE_CHANGE permission when wifi is
    642      * on.
    643      */
    644     @Test
    645     public void testSetWifiDisabledSuccess() throws Exception {
    646         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
    647         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
    648         verifyCheckChangePermission(TEST_PACKAGE_NAME);
    649         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    650     }
    651 
    652     /**
    653      * Verify that CMD_TOGGLE_WIFI message won't be sent if wifi is already off.
    654      */
    655     @Test
    656     public void testSetWifiDisabledNoToggle() throws Exception {
    657         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(false);
    658         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
    659         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    660     }
    661 
    662     /**
    663      * Verify a SecurityException is thrown if a caller does not have the correct permission to
    664      * toggle wifi.
    665      */
    666     @Test
    667     public void testSetWifiDisabledWithoutPermission() throws Exception {
    668         doThrow(new SecurityException()).when(mContext)
    669                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
    670                                                 eq("WifiService"));
    671         try {
    672             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false);
    673             fail();
    674         } catch (SecurityException e) { }
    675     }
    676 
    677     /**
    678      * Verify that wifi can be disabled without consent UI popup when permission
    679      * review is required but got permission granted.
    680      */
    681     @Test
    682     public void testSetWifiDisabledSuccessWhenPermissionReviewRequiredAndPermissionGranted()
    683             throws Exception {
    684         // Set PermissionReviewRequired to true explicitly
    685         when(mResources.getBoolean(anyInt())).thenReturn(true);
    686         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    687         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
    688         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    689         when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED);
    690         when(mContext.checkCallingPermission(
    691                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    692                         .thenReturn(PackageManager.PERMISSION_GRANTED);
    693 
    694         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
    695         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    696     }
    697 
    698     /**
    699      * Verify that wifi is not disabled but got consent UI popup when permission
    700      * review is required but do not have permission.
    701      */
    702     @Test
    703     public void testSetWifiDisabledConsentUiWhenPermissionReviewRequiredAndPermissionDenied()
    704             throws Exception {
    705         // Set PermissionReviewRequired to true explicitly
    706         when(mResources.getBoolean(anyInt())).thenReturn(true);
    707         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    708         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
    709         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    710         when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED);
    711         when(mContext.checkCallingPermission(
    712                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    713                         .thenReturn(PackageManager.PERMISSION_DENIED);
    714         when(mPackageManager.getApplicationInfoAsUser(
    715                 anyString(), anyInt(), anyInt()))
    716                         .thenReturn(mApplicationInfo);
    717         mApplicationInfo.uid = TEST_UID;
    718         int uid = Binder.getCallingUid();
    719         BinderUtil.setUid(TEST_UID);
    720 
    721         try {
    722             assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
    723         } finally {
    724             BinderUtil.setUid(uid);
    725         }
    726         verify(mContext).startActivity(any());
    727         verify(mWifiController, never()).sendMessage(eq(CMD_WIFI_TOGGLED));
    728     }
    729 
    730     /**
    731      * Verify that wifi can be disabled when wifi is on and permission review is
    732      * not required.
    733      */
    734     @Test
    735     public void testSetWifiDisabledSuccessWhenPermissionReviewNotRequired() throws Exception {
    736         // Set PermissionReviewRequired to false explicitly
    737         when(mResources.getBoolean(anyInt())).thenReturn(false);
    738         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    739         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
    740         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    741         when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED);
    742         when(mContext.checkCallingPermission(
    743                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    744                         .thenReturn(PackageManager.PERMISSION_GRANTED);
    745 
    746         assertTrue(mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false));
    747         verify(mWifiController).sendMessage(eq(CMD_WIFI_TOGGLED));
    748     }
    749 
    750     /**
    751      * Verify a SecurityException is thrown when bringing up Consent UI but caller
    752      * uid does not match application uid.
    753      *
    754      * @throws SecurityException
    755      */
    756     @Test
    757     public void testSetWifiDisabledThrowsSecurityExceptionForConsentUiIfUidNotMatch()
    758             throws Exception {
    759         // Set PermissionReviewRequired to true explicitly
    760         when(mResources.getBoolean(anyInt())).thenReturn(true);
    761         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    762         when(mSettingsStore.handleWifiToggled(eq(false))).thenReturn(true);
    763         when(mSettingsStore.isAirplaneModeOn()).thenReturn(false);
    764         when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_ENABLED);
    765         when(mContext.checkCallingPermission(
    766                 eq(android.Manifest.permission.MANAGE_WIFI_WHEN_PERMISSION_REVIEW_REQUIRED)))
    767                         .thenReturn(PackageManager.PERMISSION_DENIED);
    768         when(mPackageManager.getApplicationInfoAsUser(
    769                 anyString(), anyInt(), anyInt()))
    770                         .thenReturn(mApplicationInfo);
    771         mApplicationInfo.uid = TEST_UID;
    772         int uid = Binder.getCallingUid();
    773         BinderUtil.setUid(OTHER_TEST_UID);
    774 
    775         try {
    776             mWifiServiceImpl.setWifiEnabled(TEST_PACKAGE_NAME, false);
    777             fail();
    778         } catch (SecurityException e) {
    779 
    780         } finally {
    781             // reset Binder uid so we do not mess up other tests
    782             BinderUtil.setUid(uid);
    783         }
    784     }
    785 
    786     /**
    787      * Ensure unpermitted callers cannot write the SoftApConfiguration.
    788      *
    789      * @throws SecurityException
    790      */
    791     @Test
    792     public void testSetWifiApConfigurationNotSavedWithoutPermission() {
    793         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
    794         WifiConfiguration apConfig = new WifiConfiguration();
    795         try {
    796             mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME);
    797             fail("Expected SecurityException");
    798         } catch (SecurityException e) { }
    799     }
    800 
    801     /**
    802      * Ensure softap config is written when the caller has the correct permission.
    803      */
    804     @Test
    805     public void testSetWifiApConfigurationSuccess() {
    806         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
    807         WifiConfiguration apConfig = createValidSoftApConfiguration();
    808 
    809         assertTrue(mWifiServiceImpl.setWifiApConfiguration(apConfig, TEST_PACKAGE_NAME));
    810         mLooper.dispatchAll();
    811         verifyCheckChangePermission(TEST_PACKAGE_NAME);
    812         verify(mWifiApConfigStore).setApConfiguration(eq(apConfig));
    813     }
    814 
    815     /**
    816      * Ensure that a null config does not overwrite the saved ap config.
    817      */
    818     @Test
    819     public void testSetWifiApConfigurationNullConfigNotSaved() {
    820         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
    821         assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME));
    822         verify(mWifiApConfigStore, never()).setApConfiguration(isNull(WifiConfiguration.class));
    823     }
    824 
    825     /**
    826      * Ensure that an invalid config does not overwrite the saved ap config.
    827      */
    828     @Test
    829     public void testSetWifiApConfigurationWithInvalidConfigNotSaved() {
    830         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
    831         assertFalse(mWifiServiceImpl.setWifiApConfiguration(new WifiConfiguration(),
    832                                                             TEST_PACKAGE_NAME));
    833         verify(mWifiApConfigStore, never()).setApConfiguration(any());
    834     }
    835 
    836     /**
    837      * Ensure unpermitted callers are not able to retrieve the softap config.
    838      *
    839      * @throws SecurityException
    840      */
    841     @Test
    842     public void testGetWifiApConfigurationNotReturnedWithoutPermission() {
    843         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(false);
    844         try {
    845             mWifiServiceImpl.getWifiApConfiguration();
    846             fail("Expected a SecurityException");
    847         } catch (SecurityException e) {
    848         }
    849     }
    850 
    851     /**
    852      * Ensure permitted callers are able to retrieve the softap config.
    853      */
    854     @Test
    855     public void testGetWifiApConfigurationSuccess() {
    856         setupWifiStateMachineHandlerForRunWithScissors();
    857 
    858         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    859         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
    860 
    861         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    862         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    863 
    864         when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
    865         WifiConfiguration apConfig = new WifiConfiguration();
    866         when(mWifiApConfigStore.getApConfiguration()).thenReturn(apConfig);
    867         assertEquals(apConfig, mWifiServiceImpl.getWifiApConfiguration());
    868     }
    869 
    870     /**
    871      * Ensure we return the proper variable for the softap state after getting an AP state change
    872      * broadcast.
    873      */
    874     @Test
    875     public void testGetWifiApEnabled() {
    876         // set up WifiServiceImpl with a live thread for testing
    877         HandlerThread serviceHandlerThread = createAndStartHandlerThreadForRunWithScissors();
    878         when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(serviceHandlerThread);
    879         mWifiServiceImpl = new WifiServiceImpl(mContext, mWifiInjector, mAsyncChannel);
    880         mWifiServiceImpl.setWifiHandlerLogForTest(mLog);
    881 
    882         // ap should be disabled when wifi hasn't been started
    883         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
    884 
    885         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    886         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    887         mWifiServiceImpl.checkAndStartWifi();
    888         mLooper.dispatchAll();
    889 
    890         // ap should be disabled initially
    891         assertEquals(WifiManager.WIFI_AP_STATE_DISABLED, mWifiServiceImpl.getWifiApEnabledState());
    892 
    893         // send an ap state change to verify WifiServiceImpl is updated
    894         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
    895                 (IntentFilter) argThat(new IntentFilterMatcher()));
    896 
    897         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
    898                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
    899                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
    900         mLooper.dispatchAll();
    901 
    902         assertEquals(WifiManager.WIFI_AP_STATE_FAILED, mWifiServiceImpl.getWifiApEnabledState());
    903     }
    904 
    905     /**
    906      * Ensure we do not allow unpermitted callers to get the wifi ap state.
    907      */
    908     @Ignore
    909     @Test
    910     public void testGetWifiApEnabledPermissionDenied() {
    911         // we should not be able to get the state
    912         doThrow(new SecurityException()).when(mContext)
    913                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.ACCESS_WIFI_STATE),
    914                                                 eq("WifiService"));
    915 
    916         try {
    917             mWifiServiceImpl.getWifiApEnabledState();
    918             fail("expected SecurityException");
    919         } catch (SecurityException expected) { }
    920     }
    921 
    922     /**
    923      * Make sure we do not start wifi if System services have to be restarted to decrypt the device.
    924      */
    925     @Test
    926     public void testWifiControllerDoesNotStartWhenDeviceTriggerResetMainAtBoot() {
    927         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(true);
    928         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    929         mWifiServiceImpl.checkAndStartWifi();
    930         verify(mWifiController, never()).start();
    931     }
    932 
    933     /**
    934      * Make sure we do start WifiController (wifi disabled) if the device is already decrypted.
    935      */
    936     @Test
    937     public void testWifiControllerStartsWhenDeviceIsDecryptedAtBootWithWifiDisabled() {
    938         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    939         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
    940         mWifiServiceImpl.checkAndStartWifi();
    941         verify(mWifiController).start();
    942         verify(mWifiController, never()).sendMessage(CMD_WIFI_TOGGLED);
    943     }
    944 
    945     /**
    946      * Make sure we do start WifiController (wifi enabled) if the device is already decrypted.
    947      */
    948     @Test
    949     public void testWifiFullyStartsWhenDeviceIsDecryptedAtBootWithWifiEnabled() {
    950         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
    951         when(mSettingsStore.handleWifiToggled(true)).thenReturn(true);
    952         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(true);
    953         when(mWifiStateMachine.syncGetWifiState()).thenReturn(WIFI_STATE_DISABLED);
    954         when(mContext.getPackageName()).thenReturn(ANDROID_SYSTEM_PACKAGE);
    955         mWifiServiceImpl.checkAndStartWifi();
    956         verify(mWifiController).start();
    957         verify(mWifiController).sendMessage(CMD_WIFI_TOGGLED);
    958     }
    959 
    960     /**
    961      * Verify caller with proper permission can call startSoftAp.
    962      */
    963     @Test
    964     public void testStartSoftApWithPermissionsAndNullConfig() {
    965         boolean result = mWifiServiceImpl.startSoftAp(null);
    966         assertTrue(result);
    967         verify(mWifiController)
    968                 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
    969         assertNull(mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
    970     }
    971 
    972     /**
    973      * Verify caller with proper permissions but an invalid config does not start softap.
    974      */
    975     @Test
    976     public void testStartSoftApWithPermissionsAndInvalidConfig() {
    977         boolean result = mWifiServiceImpl.startSoftAp(mApConfig);
    978         assertFalse(result);
    979         verifyZeroInteractions(mWifiController);
    980     }
    981 
    982     /**
    983      * Verify caller with proper permission and valid config does start softap.
    984      */
    985     @Test
    986     public void testStartSoftApWithPermissionsAndValidConfig() {
    987         WifiConfiguration config = createValidSoftApConfiguration();
    988         boolean result = mWifiServiceImpl.startSoftAp(config);
    989         assertTrue(result);
    990         verify(mWifiController)
    991                 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture());
    992         assertEquals(config, mSoftApModeConfigCaptor.getValue().getWifiConfiguration());
    993     }
    994 
    995     /**
    996      * Verify a SecurityException is thrown when a caller without the correct permission attempts to
    997      * start softap.
    998      */
    999     @Test(expected = SecurityException.class)
   1000     public void testStartSoftApWithoutPermissionThrowsException() throws Exception {
   1001         doThrow(new SecurityException()).when(mContext)
   1002                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
   1003                                                 eq("WifiService"));
   1004         mWifiServiceImpl.startSoftAp(null);
   1005     }
   1006 
   1007     /**
   1008      * Verify caller with proper permission can call stopSoftAp.
   1009      */
   1010     @Test
   1011     public void testStopSoftApWithPermissions() {
   1012         boolean result = mWifiServiceImpl.stopSoftAp();
   1013         assertTrue(result);
   1014         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   1015     }
   1016 
   1017     /**
   1018      * Verify SecurityException is thrown when a caller without the correct permission attempts to
   1019      * stop softap.
   1020      */
   1021     @Test(expected = SecurityException.class)
   1022     public void testStopSoftApWithoutPermissionThrowsException() throws Exception {
   1023         doThrow(new SecurityException()).when(mContext)
   1024                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_STACK),
   1025                                                 eq("WifiService"));
   1026         mWifiServiceImpl.stopSoftAp();
   1027     }
   1028 
   1029     /**
   1030      * Ensure that we handle app ops check failure when handling scan request.
   1031      */
   1032     @Test
   1033     public void testStartScanFailureAppOpsIgnored() {
   1034         setupWifiStateMachineHandlerForRunWithScissors();
   1035         doReturn(AppOpsManager.MODE_IGNORED).when(mAppOpsManager)
   1036                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), SCAN_PACKAGE_NAME);
   1037         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   1038         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   1039     }
   1040 
   1041     /**
   1042      * Ensure that we handle scan access permission check failure when handling scan request.
   1043      */
   1044     @Test
   1045     public void testStartScanFailureInCanAccessScanResultsPermission() {
   1046         setupWifiStateMachineHandlerForRunWithScissors();
   1047         doThrow(new SecurityException()).when(mWifiPermissionsUtil)
   1048                 .enforceCanAccessScanResults(SCAN_PACKAGE_NAME, Process.myUid());
   1049         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   1050         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   1051     }
   1052 
   1053     /**
   1054      * Ensure that we handle scan request failure when posting the runnable to handler fails.
   1055      */
   1056     @Ignore
   1057     @Test
   1058     public void testStartScanFailureInRunWithScissors() {
   1059         setupWifiStateMachineHandlerForRunWithScissors();
   1060         doReturn(false).when(mHandlerSpyForWsmRunWithScissors)
   1061                 .runWithScissors(any(), anyLong());
   1062         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   1063         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   1064     }
   1065 
   1066     /**
   1067      * Ensure that we handle scan request failure from ScanRequestProxy fails.
   1068      */
   1069     @Test
   1070     public void testStartScanFailureFromScanRequestProxy() {
   1071         setupWifiStateMachineHandlerForRunWithScissors();
   1072         when(mScanRequestProxy.startScan(anyInt(), anyString())).thenReturn(false);
   1073         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   1074         verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   1075     }
   1076 
   1077     static final String TEST_SSID = "Sid's Place";
   1078     static final String TEST_SSID_WITH_QUOTES = "\"" + TEST_SSID + "\"";
   1079     static final String TEST_BSSID = "01:02:03:04:05:06";
   1080     static final String TEST_PACKAGE = "package";
   1081 
   1082     private void setupForGetConnectionInfo() {
   1083         WifiInfo wifiInfo = new WifiInfo();
   1084         wifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
   1085         wifiInfo.setBSSID(TEST_BSSID);
   1086         when(mWifiStateMachine.syncRequestConnectionInfo()).thenReturn(wifiInfo);
   1087     }
   1088 
   1089     /**
   1090      * Test that connected SSID and BSSID are not exposed to an app that does not have the
   1091      * appropriate permissions.
   1092      */
   1093     @Test
   1094     public void testConnectedIdsAreHiddenFromAppWithoutPermission() throws Exception {
   1095         setupForGetConnectionInfo();
   1096 
   1097         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
   1098                 anyString(), anyInt());
   1099 
   1100         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
   1101 
   1102         assertEquals(WifiSsid.NONE, connectionInfo.getSSID());
   1103         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
   1104     }
   1105 
   1106     /**
   1107      * Test that connected SSID and BSSID are not exposed to an app that does not have the
   1108      * appropriate permissions, when enforceCanAccessScanResults raises a SecurityException.
   1109      */
   1110     @Test
   1111     public void testConnectedIdsAreHiddenOnSecurityException() throws Exception {
   1112         setupForGetConnectionInfo();
   1113 
   1114         doThrow(new SecurityException()).when(mWifiPermissionsUtil).enforceCanAccessScanResults(
   1115                 anyString(), anyInt());
   1116 
   1117         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
   1118 
   1119         assertEquals(WifiSsid.NONE, connectionInfo.getSSID());
   1120         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, connectionInfo.getBSSID());
   1121     }
   1122 
   1123     /**
   1124      * Test that connected SSID and BSSID are exposed to an app that does have the
   1125      * appropriate permissions.
   1126      */
   1127     @Test
   1128     public void testConnectedIdsAreVisibleFromPermittedApp() throws Exception {
   1129         setupForGetConnectionInfo();
   1130 
   1131         WifiInfo connectionInfo = mWifiServiceImpl.getConnectionInfo(TEST_PACKAGE);
   1132 
   1133         assertEquals(TEST_SSID_WITH_QUOTES, connectionInfo.getSSID());
   1134         assertEquals(TEST_BSSID, connectionInfo.getBSSID());
   1135     }
   1136 
   1137     /**
   1138      * Test fetching of scan results.
   1139      */
   1140     @Test
   1141     public void testGetScanResults() {
   1142         setupWifiStateMachineHandlerForRunWithScissors();
   1143 
   1144         ScanResult[] scanResults =
   1145                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
   1146                         .getResults();
   1147         List<ScanResult> scanResultList =
   1148                 new ArrayList<>(Arrays.asList(scanResults));
   1149         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
   1150 
   1151         String packageName = "test.com";
   1152         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
   1153         verify(mScanRequestProxy).getScanResults();
   1154 
   1155         ScanTestUtil.assertScanResultsEquals(scanResults,
   1156                 retrievedScanResultList.toArray(new ScanResult[retrievedScanResultList.size()]));
   1157     }
   1158 
   1159     /**
   1160      * Ensure that we handle scan results failure when posting the runnable to handler fails.
   1161      */
   1162     @Ignore
   1163     @Test
   1164     public void testGetScanResultsFailureInRunWithScissors() {
   1165         setupWifiStateMachineHandlerForRunWithScissors();
   1166         doReturn(false).when(mHandlerSpyForWsmRunWithScissors)
   1167                 .runWithScissors(any(), anyLong());
   1168 
   1169         ScanResult[] scanResults =
   1170                 ScanTestUtil.createScanDatas(new int[][]{{2417, 2427, 5180, 5170}})[0]
   1171                         .getResults();
   1172         List<ScanResult> scanResultList =
   1173                 new ArrayList<>(Arrays.asList(scanResults));
   1174         when(mScanRequestProxy.getScanResults()).thenReturn(scanResultList);
   1175 
   1176         String packageName = "test.com";
   1177         List<ScanResult> retrievedScanResultList = mWifiServiceImpl.getScanResults(packageName);
   1178         verify(mScanRequestProxy, never()).getScanResults();
   1179 
   1180         assertTrue(retrievedScanResultList.isEmpty());
   1181     }
   1182 
   1183     private void registerLOHSRequestFull() {
   1184         // allow test to proceed without a permission check failure
   1185         when(mSettingsStore.getLocationModeSetting(mContext))
   1186                 .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
   1187         try {
   1188             when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
   1189         } catch (RemoteException e) { }
   1190         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
   1191                 .thenReturn(false);
   1192         int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
   1193                 TEST_PACKAGE_NAME);
   1194         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
   1195         verifyCheckChangePermission(TEST_PACKAGE_NAME);
   1196     }
   1197 
   1198     /**
   1199      * Verify that the call to startLocalOnlyHotspot returns REQUEST_REGISTERED when successfully
   1200      * called.
   1201      */
   1202     @Test
   1203     public void testStartLocalOnlyHotspotSingleRegistrationReturnsRequestRegistered() {
   1204         registerLOHSRequestFull();
   1205     }
   1206 
   1207     /**
   1208      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
   1209      * have the CHANGE_WIFI_STATE permission.
   1210      */
   1211     @Test(expected = SecurityException.class)
   1212     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutCorrectPermission() {
   1213         doThrow(new SecurityException()).when(mContext)
   1214                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.CHANGE_WIFI_STATE),
   1215                                                 eq("WifiService"));
   1216         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1217     }
   1218 
   1219     /**
   1220      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if the caller does not
   1221      * have Location permission.
   1222      */
   1223     @Test(expected = SecurityException.class)
   1224     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationPermission() {
   1225         doThrow(new SecurityException())
   1226                 .when(mWifiPermissionsUtil).enforceLocationPermission(eq(TEST_PACKAGE_NAME),
   1227                                                                       anyInt());
   1228         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1229     }
   1230 
   1231     /**
   1232      * Verify that a call to startLocalOnlyHotspot throws a SecurityException if Location mode is
   1233      * disabled.
   1234      */
   1235     @Test(expected = SecurityException.class)
   1236     public void testStartLocalOnlyHotspotThrowsSecurityExceptionWithoutLocationEnabled() {
   1237         when(mSettingsStore.getLocationModeSetting(mContext)).thenReturn(LOCATION_MODE_OFF);
   1238         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1239     }
   1240 
   1241     /**
   1242      * Only start LocalOnlyHotspot if the caller is the foreground app at the time of the request.
   1243      */
   1244     @Test
   1245     public void testStartLocalOnlyHotspotFailsIfRequestorNotForegroundApp() throws Exception {
   1246         when(mSettingsStore.getLocationModeSetting(mContext))
   1247                 .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
   1248 
   1249         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(false);
   1250         int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
   1251                 TEST_PACKAGE_NAME);
   1252         assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
   1253     }
   1254 
   1255     /**
   1256      * Do not register the LocalOnlyHotspot request if the caller app cannot be verified as the
   1257      * foreground app at the time of the request (ie, throws an exception in the check).
   1258      */
   1259     @Test
   1260     public void testStartLocalOnlyHotspotFailsIfForegroundAppCheckThrowsRemoteException()
   1261             throws Exception {
   1262         when(mSettingsStore.getLocationModeSetting(mContext))
   1263                 .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
   1264 
   1265         when(mFrameworkFacade.isAppForeground(anyInt())).thenThrow(new RemoteException());
   1266         int result = mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder,
   1267                 TEST_PACKAGE_NAME);
   1268         assertEquals(LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE, result);
   1269     }
   1270 
   1271     /**
   1272      * Only start LocalOnlyHotspot if we are not tethering.
   1273      */
   1274     @Test
   1275     public void testHotspotDoesNotStartWhenAlreadyTethering() throws Exception {
   1276         when(mSettingsStore.getLocationModeSetting(mContext))
   1277                             .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
   1278         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
   1279         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
   1280         mLooper.dispatchAll();
   1281         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
   1282                 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1283         assertEquals(ERROR_INCOMPATIBLE_MODE, returnCode);
   1284     }
   1285 
   1286     /**
   1287      * Only start LocalOnlyHotspot if admin setting does not disallow tethering.
   1288      */
   1289     @Test
   1290     public void testHotspotDoesNotStartWhenTetheringDisallowed() throws Exception {
   1291         when(mSettingsStore.getLocationModeSetting(mContext))
   1292                 .thenReturn(LOCATION_MODE_HIGH_ACCURACY);
   1293         when(mFrameworkFacade.isAppForeground(anyInt())).thenReturn(true);
   1294         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING))
   1295                 .thenReturn(true);
   1296         int returnCode = mWifiServiceImpl.startLocalOnlyHotspot(
   1297                 mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1298         assertEquals(ERROR_TETHERING_DISALLOWED, returnCode);
   1299     }
   1300 
   1301     /**
   1302      * Verify that callers can only have one registered LOHS request.
   1303      */
   1304     @Test(expected = IllegalStateException.class)
   1305     public void testStartLocalOnlyHotspotThrowsExceptionWhenCallerAlreadyRegistered() {
   1306         registerLOHSRequestFull();
   1307 
   1308         // now do the second request that will fail
   1309         mWifiServiceImpl.startLocalOnlyHotspot(mAppMessenger, mAppBinder, TEST_PACKAGE_NAME);
   1310     }
   1311 
   1312     /**
   1313      * Verify that the call to stopLocalOnlyHotspot does not do anything when there aren't any
   1314      * registered callers.
   1315      */
   1316     @Test
   1317     public void testStopLocalOnlyHotspotDoesNothingWithoutRegisteredRequests() {
   1318         // allow test to proceed without a permission check failure
   1319         mWifiServiceImpl.stopLocalOnlyHotspot();
   1320         // there is nothing registered, so this shouldn't do anything
   1321         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
   1322     }
   1323 
   1324     /**
   1325      * Verify that the call to stopLocalOnlyHotspot does not do anything when one caller unregisters
   1326      * but there is still an active request
   1327      */
   1328     @Test
   1329     public void testStopLocalOnlyHotspotDoesNothingWithARemainingRegisteredRequest() {
   1330         // register a request that will remain after the stopLOHS call
   1331         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
   1332 
   1333         registerLOHSRequestFull();
   1334 
   1335         // Since we are calling with the same pid, the second register call will be removed
   1336         mWifiServiceImpl.stopLocalOnlyHotspot();
   1337         // there is still a valid registered request - do not tear down LOHS
   1338         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
   1339     }
   1340 
   1341     /**
   1342      * Verify that the call to stopLocalOnlyHotspot sends a message to WifiController to stop
   1343      * the softAp when there is one registered caller when that caller is removed.
   1344      */
   1345     @Test
   1346     public void testStopLocalOnlyHotspotTriggersSoftApStopWithOneRegisteredRequest() {
   1347         registerLOHSRequestFull();
   1348         verify(mWifiController)
   1349                 .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), any(SoftApModeConfiguration.class));
   1350 
   1351         // No permission check required for change_wifi_state.
   1352         verify(mContext, never()).enforceCallingOrSelfPermission(
   1353                 eq("android.Manifest.permission.CHANGE_WIFI_STATE"), anyString());
   1354 
   1355         mWifiServiceImpl.stopLocalOnlyHotspot();
   1356         // there is was only one request registered, we should tear down softap
   1357         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   1358     }
   1359 
   1360     /**
   1361      * Verify that WifiServiceImpl does not send the stop ap message if there were no
   1362      * pending LOHS requests upon a binder death callback.
   1363      */
   1364     @Test
   1365     public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() {
   1366         LocalOnlyRequestorCallback binderDeathCallback =
   1367                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
   1368 
   1369         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
   1370         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   1371     }
   1372 
   1373     /**
   1374      * Verify that WifiServiceImpl does not send the stop ap message if there are remaining
   1375      * registered LOHS requests upon a binder death callback.  Additionally verify that softap mode
   1376      * will be stopped if that remaining request is removed (to verify the binder death properly
   1377      * cleared the requestor that died).
   1378      */
   1379     @Test
   1380     public void testServiceImplNotCalledWhenBinderDeathTriggeredWithRegisteredRequests() {
   1381         LocalOnlyRequestorCallback binderDeathCallback =
   1382                 mWifiServiceImpl.new LocalOnlyRequestorCallback();
   1383 
   1384         // registering a request directly from the test will not trigger a message to start
   1385         // softap mode
   1386         mWifiServiceImpl.registerLOHSForTest(mPid, mRequestInfo);
   1387 
   1388         registerLOHSRequestFull();
   1389 
   1390         binderDeathCallback.onLocalOnlyHotspotRequestorDeath(mRequestInfo);
   1391         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), anyInt(), anyInt());
   1392 
   1393         reset(mWifiController);
   1394 
   1395         // now stop as the second request and confirm CMD_SET_AP will be sent to make sure binder
   1396         // death requestor was removed
   1397         mWifiServiceImpl.stopLocalOnlyHotspot();
   1398         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   1399     }
   1400 
   1401     /**
   1402      * Verify that a call to registerSoftApCallback throws a SecurityException if the caller does
   1403      * not have NETWORK_SETTINGS permission.
   1404      */
   1405     @Test
   1406     public void registerSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
   1407         doThrow(new SecurityException()).when(mContext)
   1408                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   1409                                                 eq("WifiService"));
   1410         try {
   1411             final int callbackIdentifier = 1;
   1412             mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
   1413                     callbackIdentifier);
   1414             fail("expected SecurityException");
   1415         } catch (SecurityException expected) {
   1416         }
   1417     }
   1418 
   1419     /**
   1420      * Verify that a call to registerSoftApCallback throws an IllegalArgumentException if the
   1421      * parameters are not provided.
   1422      */
   1423     @Test
   1424     public void registerSoftApCallbackThrowsIllegalArgumentExceptionOnInvalidArguments() {
   1425         try {
   1426             final int callbackIdentifier = 1;
   1427             mWifiServiceImpl.registerSoftApCallback(mAppBinder, null, callbackIdentifier);
   1428             fail("expected IllegalArgumentException");
   1429         } catch (IllegalArgumentException expected) {
   1430         }
   1431     }
   1432 
   1433     /**
   1434      * Verify that a call to unregisterSoftApCallback throws a SecurityException if the caller does
   1435      * not have NETWORK_SETTINGS permission.
   1436      */
   1437     @Test
   1438     public void unregisterSoftApCallbackThrowsSecurityExceptionOnMissingPermissions() {
   1439         doThrow(new SecurityException()).when(mContext)
   1440                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   1441                                                 eq("WifiService"));
   1442         try {
   1443             final int callbackIdentifier = 1;
   1444             mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
   1445             fail("expected SecurityException");
   1446         } catch (SecurityException expected) {
   1447         }
   1448     }
   1449 
   1450     /**
   1451      * Registers a soft AP callback, then verifies that the current soft AP state and num clients
   1452      * are sent to caller immediately after callback is registered.
   1453      */
   1454     private void registerSoftApCallbackAndVerify(ISoftApCallback callback, int callbackIdentifier)
   1455             throws Exception {
   1456         mWifiServiceImpl.registerSoftApCallback(mAppBinder, callback, callbackIdentifier);
   1457         mLooper.dispatchAll();
   1458         verify(callback).onStateChanged(WIFI_AP_STATE_DISABLED, 0);
   1459         verify(callback).onNumClientsChanged(0);
   1460     }
   1461 
   1462     /**
   1463      * Verify that registering twice with same callbackIdentifier will replace the first callback.
   1464      */
   1465     @Test
   1466     public void replacesOldCallbackWithNewCallbackWhenRegisteringTwice() throws Exception {
   1467         final int callbackIdentifier = 1;
   1468         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1469         registerSoftApCallbackAndVerify(mAnotherSoftApCallback, callbackIdentifier);
   1470 
   1471         final int testNumClients = 4;
   1472         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1473         mLooper.dispatchAll();
   1474         // Verify only the second callback is being called
   1475         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
   1476         verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
   1477     }
   1478 
   1479     /**
   1480      * Verify that unregisterSoftApCallback removes callback from registered callbacks list
   1481      */
   1482     @Test
   1483     public void unregisterSoftApCallbackRemovesCallback() throws Exception {
   1484         final int callbackIdentifier = 1;
   1485         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1486 
   1487         mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
   1488         mLooper.dispatchAll();
   1489 
   1490         final int testNumClients = 4;
   1491         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1492         mLooper.dispatchAll();
   1493         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
   1494     }
   1495 
   1496     /**
   1497      * Verify that unregisterSoftApCallback is no-op if callbackIdentifier not registered.
   1498      */
   1499     @Test
   1500     public void unregisterSoftApCallbackDoesNotRemoveCallbackIfCallbackIdentifierNotMatching()
   1501             throws Exception {
   1502         final int callbackIdentifier = 1;
   1503         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1504 
   1505         final int differentCallbackIdentifier = 2;
   1506         mWifiServiceImpl.unregisterSoftApCallback(differentCallbackIdentifier);
   1507         mLooper.dispatchAll();
   1508 
   1509         final int testNumClients = 4;
   1510         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1511         mLooper.dispatchAll();
   1512         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
   1513     }
   1514 
   1515     /**
   1516      * Registers two callbacks, remove one then verify the right callback is being called on events.
   1517      */
   1518     @Test
   1519     public void correctCallbackIsCalledAfterAddingTwoCallbacksAndRemovingOne() throws Exception {
   1520         final int callbackIdentifier = 1;
   1521         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
   1522                 callbackIdentifier);
   1523 
   1524         // Change state from default before registering the second callback
   1525         final int testNumClients = 4;
   1526         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1527         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1528 
   1529         // Register another callback and verify the new state is returned in the immediate callback
   1530         final int anotherUid = 2;
   1531         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mAnotherSoftApCallback, anotherUid);
   1532         mLooper.dispatchAll();
   1533         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1534         verify(mAnotherSoftApCallback).onNumClientsChanged(testNumClients);
   1535 
   1536         // unregister the fisrt callback
   1537         mWifiServiceImpl.unregisterSoftApCallback(callbackIdentifier);
   1538         mLooper.dispatchAll();
   1539 
   1540         // Update soft AP state and verify the remaining callback receives the event
   1541         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_FAILED,
   1542                 SAP_START_FAILURE_NO_CHANNEL);
   1543         mLooper.dispatchAll();
   1544         verify(mClientSoftApCallback, never()).onStateChanged(WIFI_AP_STATE_FAILED,
   1545                 SAP_START_FAILURE_NO_CHANNEL);
   1546         verify(mAnotherSoftApCallback).onStateChanged(WIFI_AP_STATE_FAILED,
   1547                 SAP_START_FAILURE_NO_CHANNEL);
   1548     }
   1549 
   1550     /**
   1551      * Verify that wifi service registers for callers BinderDeath event
   1552      */
   1553     @Ignore
   1554     @Test
   1555     public void registersForBinderDeathOnRegisterSoftApCallback() throws Exception {
   1556         final int callbackIdentifier = 1;
   1557         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1558         verify(mAppBinder).linkToDeath(any(IBinder.DeathRecipient.class), anyInt());
   1559     }
   1560 
   1561     /**
   1562      * Verify that we un-register the soft AP callback on receiving BinderDied event.
   1563      */
   1564     @Test
   1565     public void unregistersSoftApCallbackOnBinderDied() throws Exception {
   1566         ArgumentCaptor<IBinder.DeathRecipient> drCaptor =
   1567                 ArgumentCaptor.forClass(IBinder.DeathRecipient.class);
   1568         final int callbackIdentifier = 1;
   1569         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1570         verify(mAppBinder).linkToDeath(drCaptor.capture(), anyInt());
   1571 
   1572         drCaptor.getValue().binderDied();
   1573         mLooper.dispatchAll();
   1574         verify(mAppBinder).unlinkToDeath(drCaptor.getValue(), 0);
   1575 
   1576         // Verify callback is removed from the list as well
   1577         final int testNumClients = 4;
   1578         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1579         mLooper.dispatchAll();
   1580         verify(mClientSoftApCallback, never()).onNumClientsChanged(testNumClients);
   1581     }
   1582 
   1583     /**
   1584      * Verify that soft AP callback is called on NumClientsChanged event
   1585      */
   1586     @Test
   1587     public void callsRegisteredCallbacksOnNumClientsChangedEvent() throws Exception {
   1588         final int callbackIdentifier = 1;
   1589         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1590 
   1591         final int testNumClients = 4;
   1592         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1593         mLooper.dispatchAll();
   1594         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
   1595     }
   1596 
   1597     /**
   1598      * Verify that soft AP callback is called on SoftApStateChanged event
   1599      */
   1600     @Test
   1601     public void callsRegisteredCallbacksOnSoftApStateChangedEvent() throws Exception {
   1602         final int callbackIdentifier = 1;
   1603         registerSoftApCallbackAndVerify(mClientSoftApCallback, callbackIdentifier);
   1604 
   1605         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1606         mLooper.dispatchAll();
   1607         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1608     }
   1609 
   1610     /**
   1611      * Verify that mSoftApState and mSoftApNumClients in WifiServiceImpl are being updated on soft
   1612      * Ap events, even when no callbacks are registered.
   1613      */
   1614     @Test
   1615     public void updatesSoftApStateAndNumClientsOnSoftApEvents() throws Exception {
   1616         final int testNumClients = 4;
   1617         mStateMachineSoftApCallback.onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1618         mStateMachineSoftApCallback.onNumClientsChanged(testNumClients);
   1619 
   1620         // Register callback after num clients and soft AP are changed.
   1621         final int callbackIdentifier = 1;
   1622         mWifiServiceImpl.registerSoftApCallback(mAppBinder, mClientSoftApCallback,
   1623                 callbackIdentifier);
   1624         mLooper.dispatchAll();
   1625         verify(mClientSoftApCallback).onStateChanged(WIFI_AP_STATE_ENABLED, 0);
   1626         verify(mClientSoftApCallback).onNumClientsChanged(testNumClients);
   1627     }
   1628 
   1629     private class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
   1630         @Override
   1631         public boolean matches(IntentFilter filter) {
   1632             return filter.hasAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
   1633         }
   1634     }
   1635 
   1636     /**
   1637      * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
   1638      * broadcast is received.
   1639      */
   1640     @Test
   1641     public void testRegisteredCallbacksTriggeredOnSoftApFailureGeneric() throws Exception {
   1642         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1643         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1644         mWifiServiceImpl.checkAndStartWifi();
   1645 
   1646         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1647                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1648 
   1649         registerLOHSRequestFull();
   1650 
   1651         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1652                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_GENERAL,
   1653                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1654         mLooper.dispatchAll();
   1655         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1656         Message message = mMessageCaptor.getValue();
   1657         assertEquals(HOTSPOT_FAILED, message.what);
   1658         assertEquals(ERROR_GENERIC, message.arg1);
   1659     }
   1660 
   1661     /**
   1662      * Verify that onFailed is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
   1663      * broadcast is received with the SAP_START_FAILURE_NO_CHANNEL error.
   1664      */
   1665     @Test
   1666     public void testRegisteredCallbacksTriggeredOnSoftApFailureNoChannel() throws Exception {
   1667         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1668         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1669         mWifiServiceImpl.checkAndStartWifi();
   1670 
   1671         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1672                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1673 
   1674         registerLOHSRequestFull();
   1675 
   1676         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1677                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_DISABLED, SAP_START_FAILURE_NO_CHANNEL,
   1678                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1679 
   1680         mLooper.dispatchAll();
   1681         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1682         Message message = mMessageCaptor.getValue();
   1683         assertEquals(HOTSPOT_FAILED, message.what);
   1684         assertEquals(ERROR_NO_CHANNEL, message.arg1);
   1685     }
   1686 
   1687     /**
   1688      * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
   1689      * broadcast is received with WIFI_AP_STATE_DISABLING and LOHS was active.
   1690      */
   1691     @Test
   1692     public void testRegisteredCallbacksTriggeredOnSoftApDisabling() throws Exception {
   1693         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1694         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1695         mWifiServiceImpl.checkAndStartWifi();
   1696 
   1697         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1698                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1699 
   1700         registerLOHSRequestFull();
   1701 
   1702         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1703         mLooper.dispatchAll();
   1704         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1705         Message message = mMessageCaptor.getValue();
   1706         assertEquals(HOTSPOT_STARTED, message.what);
   1707         reset(mHandler);
   1708 
   1709         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1710                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
   1711                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1712 
   1713         mLooper.dispatchAll();
   1714         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1715         message = mMessageCaptor.getValue();
   1716         assertEquals(HOTSPOT_STOPPED, message.what);
   1717     }
   1718 
   1719 
   1720     /**
   1721      * Verify that onStopped is called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
   1722      * broadcast is received with WIFI_AP_STATE_DISABLED and LOHS was enabled.
   1723      */
   1724     @Test
   1725     public void testRegisteredCallbacksTriggeredOnSoftApDisabled() throws Exception {
   1726         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1727         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1728         mWifiServiceImpl.checkAndStartWifi();
   1729 
   1730         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1731                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1732 
   1733         registerLOHSRequestFull();
   1734 
   1735         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1736         mLooper.dispatchAll();
   1737         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1738         Message message = mMessageCaptor.getValue();
   1739         assertEquals(HOTSPOT_STARTED, message.what);
   1740         reset(mHandler);
   1741 
   1742         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1743                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
   1744                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1745 
   1746         mLooper.dispatchAll();
   1747         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1748         message = mMessageCaptor.getValue();
   1749         assertEquals(HOTSPOT_STOPPED, message.what);
   1750     }
   1751 
   1752     /**
   1753      * Verify that no callbacks are called for registered LOHS callers when a WIFI_AP_STATE_CHANGE
   1754      * broadcast is received and the softap started.
   1755      */
   1756     @Test
   1757     public void testRegisteredCallbacksNotTriggeredOnSoftApStart() throws Exception {
   1758         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1759         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1760         mWifiServiceImpl.checkAndStartWifi();
   1761 
   1762         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1763                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1764 
   1765         registerLOHSRequestFull();
   1766 
   1767         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1768                 WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_DISABLED, HOTSPOT_NO_ERROR, WIFI_IFACE_NAME,
   1769                 IFACE_IP_MODE_LOCAL_ONLY);
   1770 
   1771         mLooper.dispatchAll();
   1772         verify(mHandler, never()).handleMessage(any(Message.class));
   1773     }
   1774 
   1775     /**
   1776      * Verify that onStopped is called only once for registered LOHS callers when
   1777      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLING and
   1778      * WIFI_AP_STATE_DISABLED when LOHS was enabled.
   1779      */
   1780     @Test
   1781     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApDisabling() throws Exception {
   1782         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1783         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1784         mWifiServiceImpl.checkAndStartWifi();
   1785 
   1786         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1787                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1788 
   1789         registerLOHSRequestFull();
   1790 
   1791         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1792         mLooper.dispatchAll();
   1793         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1794         Message message = mMessageCaptor.getValue();
   1795         assertEquals(HOTSPOT_STARTED, message.what);
   1796         reset(mHandler);
   1797 
   1798         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1799                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
   1800                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1801         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1802                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
   1803                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1804 
   1805         mLooper.dispatchAll();
   1806         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1807         message = mMessageCaptor.getValue();
   1808         assertEquals(HOTSPOT_STOPPED, message.what);
   1809     }
   1810 
   1811     /**
   1812      * Verify that onFailed is called only once for registered LOHS callers when
   1813      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED twice.
   1814      */
   1815     @Test
   1816     public void testRegisteredCallbacksTriggeredOnlyOnceWhenSoftApFailsTwice() throws Exception {
   1817         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1818         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1819         mWifiServiceImpl.checkAndStartWifi();
   1820 
   1821         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1822                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1823 
   1824         registerLOHSRequestFull();
   1825 
   1826         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1827                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
   1828                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1829         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1830                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
   1831                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1832 
   1833         mLooper.dispatchAll();
   1834         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1835         Message message = mMessageCaptor.getValue();
   1836         assertEquals(HOTSPOT_FAILED, message.what);
   1837         assertEquals(ERROR_GENERIC, message.arg1);
   1838     }
   1839 
   1840     /**
   1841      * Verify that onFailed is called for all registered LOHS callers when
   1842      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_FAILED.
   1843      */
   1844     @Test
   1845     public void testAllRegisteredCallbacksTriggeredWhenSoftApFails() throws Exception {
   1846         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1847         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1848         mWifiServiceImpl.checkAndStartWifi();
   1849 
   1850         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1851                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1852 
   1853         // make an additional request for this test
   1854         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   1855 
   1856         registerLOHSRequestFull();
   1857 
   1858         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1859                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
   1860                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1861         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1862                 WIFI_AP_STATE_FAILED, WIFI_AP_STATE_FAILED, ERROR_GENERIC,
   1863                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1864 
   1865         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
   1866         mLooper.dispatchAll();
   1867         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1868         Message message = mMessageCaptor.getValue();
   1869         assertEquals(HOTSPOT_FAILED, message.what);
   1870         assertEquals(ERROR_GENERIC, message.arg1);
   1871     }
   1872 
   1873     /**
   1874      * Verify that onStopped is called for all registered LOHS callers when
   1875      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
   1876      * active.
   1877      */
   1878     @Test
   1879     public void testAllRegisteredCallbacksTriggeredWhenSoftApStops() throws Exception {
   1880         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1881         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1882         mWifiServiceImpl.checkAndStartWifi();
   1883 
   1884         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1885                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1886 
   1887         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   1888 
   1889         registerLOHSRequestFull();
   1890 
   1891         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1892         mLooper.dispatchAll();
   1893         verify(mRequestInfo).sendHotspotStartedMessage(any());
   1894         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1895         Message message = mMessageCaptor.getValue();
   1896         assertEquals(HOTSPOT_STARTED, message.what);
   1897         reset(mHandler);
   1898 
   1899         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1900                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
   1901                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1902         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1903                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
   1904                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1905 
   1906         verify(mRequestInfo).sendHotspotStoppedMessage();
   1907         mLooper.dispatchAll();
   1908         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1909         message = mMessageCaptor.getValue();
   1910         assertEquals(HOTSPOT_STOPPED, message.what);
   1911     }
   1912 
   1913     /**
   1914      * Verify that onFailed is called for all registered LOHS callers when
   1915      * WIFI_AP_STATE_CHANGE broadcasts are received with WIFI_AP_STATE_DISABLED when LOHS was
   1916      * not active.
   1917      */
   1918     @Test
   1919     public void testAllRegisteredCallbacksTriggeredWhenSoftApStopsLOHSNotActive() throws Exception {
   1920         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   1921         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   1922         mWifiServiceImpl.checkAndStartWifi();
   1923 
   1924         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   1925                 (IntentFilter) argThat(new IntentFilterMatcher()));
   1926 
   1927         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   1928         mWifiServiceImpl.registerLOHSForTest(TEST_PID2, mRequestInfo2);
   1929 
   1930         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1931                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
   1932                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1933         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   1934                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
   1935                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1936 
   1937         verify(mRequestInfo).sendHotspotFailedMessage(ERROR_GENERIC);
   1938         verify(mRequestInfo2).sendHotspotFailedMessage(ERROR_GENERIC);
   1939     }
   1940 
   1941     /**
   1942      * Verify that if we do not have registered LOHS requestors and we receive an update that LOHS
   1943      * is up and ready for use, we tell WifiController to tear it down.  This can happen if softap
   1944      * mode fails to come up properly and we get an onFailed message for a tethering call and we
   1945      * had registered callers for LOHS.
   1946      */
   1947     @Test
   1948     public void testLOHSReadyWithoutRegisteredRequestsStopsSoftApMode() {
   1949         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1950         mLooper.dispatchAll();
   1951 
   1952         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   1953     }
   1954 
   1955     /**
   1956      * Verify that all registered LOHS requestors are notified via a HOTSPOT_STARTED message that
   1957      * the hotspot is up and ready to use.
   1958      */
   1959     @Test
   1960     public void testRegisteredLocalOnlyHotspotRequestorsGetOnStartedCallbackWhenReady()
   1961             throws Exception {
   1962         registerLOHSRequestFull();
   1963 
   1964         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   1965 
   1966         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1967         mLooper.dispatchAll();
   1968         verify(mRequestInfo).sendHotspotStartedMessage(any(WifiConfiguration.class));
   1969 
   1970         mLooper.dispatchAll();
   1971         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1972         Message message = mMessageCaptor.getValue();
   1973         assertEquals(HOTSPOT_STARTED, message.what);
   1974         assertNotNull((WifiConfiguration) message.obj);
   1975     }
   1976 
   1977     /**
   1978      * Verify that if a LOHS is already active, a new call to register a request will trigger the
   1979      * onStarted callback.
   1980      */
   1981     @Test
   1982     public void testRegisterLocalOnlyHotspotRequestAfterAlreadyStartedGetsOnStartedCallback()
   1983             throws Exception {
   1984         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   1985 
   1986         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   1987         mLooper.dispatchAll();
   1988 
   1989         registerLOHSRequestFull();
   1990 
   1991         mLooper.dispatchAll();
   1992 
   1993         verify(mHandler).handleMessage(mMessageCaptor.capture());
   1994         Message message = mMessageCaptor.getValue();
   1995         assertEquals(HOTSPOT_STARTED, message.what);
   1996         // since the first request was registered out of band, the config will be null
   1997         assertNull((WifiConfiguration) message.obj);
   1998     }
   1999 
   2000     /**
   2001      * Verify that if a LOHS request is active and we receive an update with an ip mode
   2002      * configuration error, callers are notified via the onFailed callback with the generic
   2003      * error and are unregistered.
   2004      */
   2005     @Test
   2006     public void testCallOnFailedLocalOnlyHotspotRequestWhenIpConfigFails() throws Exception {
   2007         registerLOHSRequestFull();
   2008 
   2009         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
   2010         mLooper.dispatchAll();
   2011 
   2012         verify(mHandler).handleMessage(mMessageCaptor.capture());
   2013         Message message = mMessageCaptor.getValue();
   2014         assertEquals(HOTSPOT_FAILED, message.what);
   2015         assertEquals(ERROR_GENERIC, message.arg1);
   2016 
   2017         verify(mWifiController, never()).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   2018 
   2019         // sendMessage should only happen once since the requestor should be unregistered
   2020         reset(mHandler);
   2021 
   2022         // send HOTSPOT_FAILED message should only happen once since the requestor should be
   2023         // unregistered
   2024         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
   2025         mLooper.dispatchAll();
   2026         verify(mHandler, never()).handleMessage(any(Message.class));
   2027     }
   2028 
   2029     /**
   2030      * Verify that softap mode is stopped for tethering if we receive an update with an ip mode
   2031      * configuration error.
   2032      */
   2033     @Test
   2034     public void testStopSoftApWhenIpConfigFails() throws Exception {
   2035         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_CONFIGURATION_ERROR);
   2036         mLooper.dispatchAll();
   2037 
   2038         verify(mWifiController).sendMessage(eq(CMD_SET_AP), eq(0), eq(0));
   2039     }
   2040 
   2041     /**
   2042      * Verify that if a LOHS request is active and tethering starts, callers are notified on the
   2043      * incompatible mode and are unregistered.
   2044      */
   2045     @Test
   2046     public void testCallOnFailedLocalOnlyHotspotRequestWhenTetheringStarts() throws Exception {
   2047         registerLOHSRequestFull();
   2048 
   2049         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
   2050         mLooper.dispatchAll();
   2051 
   2052         verify(mHandler).handleMessage(mMessageCaptor.capture());
   2053         Message message = mMessageCaptor.getValue();
   2054         assertEquals(HOTSPOT_FAILED, message.what);
   2055         assertEquals(ERROR_INCOMPATIBLE_MODE, message.arg1);
   2056 
   2057         // sendMessage should only happen once since the requestor should be unregistered
   2058         reset(mHandler);
   2059 
   2060         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_TETHERED);
   2061         mLooper.dispatchAll();
   2062         verify(mHandler, never()).handleMessage(any(Message.class));
   2063     }
   2064 
   2065     /**
   2066      * Verify that if LOHS is disabled, a new call to register a request will not trigger the
   2067      * onStopped callback.
   2068      */
   2069     @Test
   2070     public void testRegisterLocalOnlyHotspotRequestWhenStoppedDoesNotGetOnStoppedCallback()
   2071             throws Exception {
   2072         registerLOHSRequestFull();
   2073         mLooper.dispatchAll();
   2074 
   2075         verify(mHandler, never()).handleMessage(any(Message.class));
   2076     }
   2077 
   2078     /**
   2079      * Verify that if a LOHS was active and then stopped, a new call to register a request will
   2080      * not trigger the onStarted callback.
   2081      */
   2082     @Test
   2083     public void testRegisterLocalOnlyHotspotRequestAfterStoppedNoOnStartedCallback()
   2084             throws Exception {
   2085         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   2086         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   2087         mWifiServiceImpl.checkAndStartWifi();
   2088         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2089                 (IntentFilter) argThat(new IntentFilterMatcher()));
   2090 
   2091         // register a request so we don't drop the LOHS interface ip update
   2092         mWifiServiceImpl.registerLOHSForTest(TEST_PID, mRequestInfo);
   2093 
   2094         mWifiServiceImpl.updateInterfaceIpState(WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   2095         mLooper.dispatchAll();
   2096 
   2097         registerLOHSRequestFull();
   2098         mLooper.dispatchAll();
   2099 
   2100         verify(mHandler).handleMessage(mMessageCaptor.capture());
   2101         assertEquals(HOTSPOT_STARTED, mMessageCaptor.getValue().what);
   2102 
   2103         reset(mHandler);
   2104 
   2105         // now stop the hotspot
   2106         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   2107                 WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_ENABLED, HOTSPOT_NO_ERROR,
   2108                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   2109         TestUtil.sendWifiApStateChanged(mBroadcastReceiverCaptor.getValue(), mContext,
   2110                 WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING, HOTSPOT_NO_ERROR,
   2111                 WIFI_IFACE_NAME, IFACE_IP_MODE_LOCAL_ONLY);
   2112         mLooper.dispatchAll();
   2113         verify(mHandler).handleMessage(mMessageCaptor.capture());
   2114         assertEquals(HOTSPOT_STOPPED, mMessageCaptor.getValue().what);
   2115 
   2116         reset(mHandler);
   2117 
   2118         // now register a new caller - they should not get the onStarted callback
   2119         Messenger messenger2 = new Messenger(mHandler);
   2120         IBinder binder2 = mock(IBinder.class);
   2121 
   2122         int result = mWifiServiceImpl.startLocalOnlyHotspot(messenger2, binder2, TEST_PACKAGE_NAME);
   2123         assertEquals(LocalOnlyHotspotCallback.REQUEST_REGISTERED, result);
   2124         mLooper.dispatchAll();
   2125 
   2126         verify(mHandler, never()).handleMessage(any(Message.class));
   2127     }
   2128 
   2129     /**
   2130      * Verify that a call to startWatchLocalOnlyHotspot is only allowed from callers with the
   2131      * signature only NETWORK_SETTINGS permission.
   2132      *
   2133      * This test is expecting the permission check to enforce the permission and throw a
   2134      * SecurityException for callers without the permission.  This exception should be bubbled up to
   2135      * the caller of startLocalOnlyHotspot.
   2136      */
   2137     @Test(expected = SecurityException.class)
   2138     public void testStartWatchLocalOnlyHotspotNotApprovedCaller() {
   2139         doThrow(new SecurityException()).when(mContext)
   2140                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2141                                                 eq("WifiService"));
   2142         mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
   2143     }
   2144 
   2145     /**
   2146      * Verify that the call to startWatchLocalOnlyHotspot throws the UnsupportedOperationException
   2147      * when called until the implementation is complete.
   2148      */
   2149     @Test(expected = UnsupportedOperationException.class)
   2150     public void testStartWatchLocalOnlyHotspotNotSupported() {
   2151         mWifiServiceImpl.startWatchLocalOnlyHotspot(mAppMessenger, mAppBinder);
   2152     }
   2153 
   2154     /**
   2155      * Verify that a call to stopWatchLocalOnlyHotspot is only allowed from callers with the
   2156      * signature only NETWORK_SETTINGS permission.
   2157      */
   2158     @Test(expected = SecurityException.class)
   2159     public void testStopWatchLocalOnlyHotspotNotApprovedCaller() {
   2160         doThrow(new SecurityException()).when(mContext)
   2161                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2162                                                 eq("WifiService"));
   2163         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
   2164     }
   2165 
   2166     /**
   2167      * Verify that the call to stopWatchLocalOnlyHotspot throws the UnsupportedOperationException
   2168      * until the implementation is complete.
   2169      */
   2170     @Test(expected = UnsupportedOperationException.class)
   2171     public void testStopWatchLocalOnlyHotspotNotSupported() {
   2172         mWifiServiceImpl.stopWatchLocalOnlyHotspot();
   2173     }
   2174 
   2175     /**
   2176      * Verify that the call to addOrUpdateNetwork for installing Passpoint profile is redirected
   2177      * to the Passpoint specific API addOrUpdatePasspointConfiguration.
   2178      */
   2179     @Test
   2180     public void testAddPasspointProfileViaAddNetwork() throws Exception {
   2181         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
   2182         config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
   2183 
   2184         PackageManager pm = mock(PackageManager.class);
   2185         when(pm.hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(true);
   2186         when(mContext.getPackageManager()).thenReturn(pm);
   2187 
   2188         when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(),
   2189                 any(PasspointConfiguration.class), anyInt())).thenReturn(true);
   2190         assertEquals(0, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
   2191         verifyCheckChangePermission(TEST_PACKAGE_NAME);
   2192         verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(),
   2193                 any(PasspointConfiguration.class), anyInt());
   2194         reset(mWifiStateMachine);
   2195 
   2196         when(mWifiStateMachine.syncAddOrUpdatePasspointConfig(any(),
   2197                 any(PasspointConfiguration.class), anyInt())).thenReturn(false);
   2198         assertEquals(-1, mWifiServiceImpl.addOrUpdateNetwork(config, TEST_PACKAGE_NAME));
   2199         verify(mWifiStateMachine).syncAddOrUpdatePasspointConfig(any(),
   2200                 any(PasspointConfiguration.class), anyInt());
   2201     }
   2202 
   2203     /**
   2204      * Verify that the call to startSubscriptionProvisioning is redirected to the Passpoint
   2205      * specific API startSubscriptionProvisioning when the caller has the right permissions.
   2206      */
   2207     @Test
   2208     public void testStartSubscriptionProvisioningWithPermission() throws Exception {
   2209         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
   2210         verify(mWifiStateMachine).syncStartSubscriptionProvisioning(anyInt(),
   2211                 eq(mOsuProvider), eq(mProvisioningCallback), any());
   2212     }
   2213 
   2214     /**
   2215      * Verify that the call to startSubscriptionProvisioning is not directed to the Passpoint
   2216      * specific API startSubscriptionProvisioning when the feature is not supported.
   2217      */
   2218     @Test(expected = UnsupportedOperationException.class)
   2219     public void testStartSubscriptionProvisioniningPasspointUnsupported() throws Exception {
   2220         when(mPackageManager.hasSystemFeature(
   2221                 PackageManager.FEATURE_WIFI_PASSPOINT)).thenReturn(false);
   2222         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
   2223     }
   2224 
   2225     /**
   2226      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
   2227      * specific API startSubscriptionProvisioning when the caller provides invalid arguments
   2228      */
   2229     @Test(expected = IllegalArgumentException.class)
   2230     public void testStartSubscriptionProvisioningWithInvalidProvider() throws Exception {
   2231         mWifiServiceImpl.startSubscriptionProvisioning(null, mProvisioningCallback);
   2232     }
   2233 
   2234 
   2235     /**
   2236      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
   2237      * specific API startSubscriptionProvisioning when the caller provides invalid callback
   2238      */
   2239     @Test(expected = IllegalArgumentException.class)
   2240     public void testStartSubscriptionProvisioningWithInvalidCallback() throws Exception {
   2241         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, null);
   2242     }
   2243 
   2244     /**
   2245      * Verify that the call to startSubscriptionProvisioning is not redirected to the Passpoint
   2246      * specific API startSubscriptionProvisioning when the caller doesn't have NETWORK_SETTINGS
   2247      * permissions.
   2248      */
   2249     @Test(expected = SecurityException.class)
   2250     public void testStartSubscriptionProvisioningWithoutPermission() throws Exception {
   2251         doThrow(new SecurityException()).when(mContext)
   2252                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2253                         eq("WifiService"));
   2254         mWifiServiceImpl.startSubscriptionProvisioning(mOsuProvider, mProvisioningCallback);
   2255     }
   2256 
   2257     /**
   2258      * Verify that a call to {@link WifiServiceImpl#restoreBackupData(byte[])} is only allowed from
   2259      * callers with the signature only NETWORK_SETTINGS permission.
   2260      */
   2261     @Test(expected = SecurityException.class)
   2262     public void testRestoreBackupDataNotApprovedCaller() {
   2263         doThrow(new SecurityException()).when(mContext)
   2264                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2265                         eq("WifiService"));
   2266         mWifiServiceImpl.restoreBackupData(null);
   2267         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromBackupData(any(byte[].class));
   2268     }
   2269 
   2270     /**
   2271      * Verify that a call to {@link WifiServiceImpl#restoreSupplicantBackupData(byte[], byte[])} is
   2272      * only allowed from callers with the signature only NETWORK_SETTINGS permission.
   2273      */
   2274     @Ignore
   2275     @Test(expected = SecurityException.class)
   2276     public void testRestoreSupplicantBackupDataNotApprovedCaller() {
   2277         doThrow(new SecurityException()).when(mContext)
   2278                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2279                         eq("WifiService"));
   2280         mWifiServiceImpl.restoreSupplicantBackupData(null, null);
   2281         verify(mWifiBackupRestore, never()).retrieveConfigurationsFromSupplicantBackupData(
   2282                 any(byte[].class), any(byte[].class));
   2283     }
   2284 
   2285     /**
   2286      * Verify that a call to {@link WifiServiceImpl#retrieveBackupData()} is only allowed from
   2287      * callers with the signature only NETWORK_SETTINGS permission.
   2288      */
   2289     @Test(expected = SecurityException.class)
   2290     public void testRetrieveBackupDataNotApprovedCaller() {
   2291         doThrow(new SecurityException()).when(mContext)
   2292                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2293                         eq("WifiService"));
   2294         mWifiServiceImpl.retrieveBackupData();
   2295         verify(mWifiBackupRestore, never()).retrieveBackupDataFromConfigurations(any(List.class));
   2296     }
   2297 
   2298     /**
   2299      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is allowed from
   2300      * callers with the signature only NETWORK_SETTINGS permission.
   2301      */
   2302     @Ignore("TODO: Investigate failure")
   2303     @Test
   2304     public void testEnableVerboseLoggingWithNetworkSettingsPermission() {
   2305         doNothing().when(mContext)
   2306                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2307                         eq("WifiService"));
   2308         mWifiServiceImpl.enableVerboseLogging(1);
   2309         verify(mWifiStateMachine).enableVerboseLogging(anyInt());
   2310     }
   2311 
   2312     /**
   2313      * Verify that a call to {@link WifiServiceImpl#enableVerboseLogging(int)} is not allowed from
   2314      * callers without the signature only NETWORK_SETTINGS permission.
   2315      */
   2316     @Test(expected = SecurityException.class)
   2317     public void testEnableVerboseLoggingWithNoNetworkSettingsPermission() {
   2318         doThrow(new SecurityException()).when(mContext)
   2319                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2320                         eq("WifiService"));
   2321         mWifiServiceImpl.enableVerboseLogging(1);
   2322         verify(mWifiStateMachine, never()).enableVerboseLogging(anyInt());
   2323     }
   2324 
   2325     /**
   2326      * Helper to test handling of async messages by wifi service when the message comes from an
   2327      * app without {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
   2328      */
   2329     private void verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2330             int requestMsgWhat, int expectedReplyMsgwhat) throws RemoteException {
   2331         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
   2332 
   2333         int uidWithoutPermission = 5;
   2334         when(mWifiPermissionsUtil.checkChangePermission(eq(uidWithoutPermission)))
   2335                 .thenReturn(false);
   2336 
   2337         Message request = Message.obtain();
   2338         request.what = requestMsgWhat;
   2339         request.sendingUid = uidWithoutPermission;
   2340 
   2341         mLooper.startAutoDispatch();
   2342         Message reply = tester.sendMessageSynchronously(request);
   2343         mLooper.stopAutoDispatch();
   2344 
   2345         verify(mWifiStateMachine, never()).sendMessage(any(Message.class));
   2346         assertEquals(expectedReplyMsgwhat, reply.what);
   2347         assertEquals(WifiManager.NOT_AUTHORIZED, reply.arg1);
   2348     }
   2349 
   2350     /**
   2351      * Verify that the CONNECT_NETWORK message received from an app without
   2352      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2353      * error code.
   2354      */
   2355     @Test
   2356     public void testConnectNetworkWithoutChangePermission() throws Exception {
   2357         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2358                 WifiManager.CONNECT_NETWORK, WifiManager.CONNECT_NETWORK_FAILED);
   2359     }
   2360 
   2361     /**
   2362      * Verify that the FORGET_NETWORK message received from an app without
   2363      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2364      * error code.
   2365      */
   2366     @Test
   2367     public void testForgetNetworkWithoutChangePermission() throws Exception {
   2368         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2369                 WifiManager.SAVE_NETWORK, WifiManager.SAVE_NETWORK_FAILED);
   2370     }
   2371 
   2372     /**
   2373      * Verify that the START_WPS message received from an app without
   2374      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2375      * error code.
   2376      */
   2377     @Test
   2378     public void testStartWpsWithoutChangePermission() throws Exception {
   2379         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2380                 WifiManager.START_WPS, WifiManager.WPS_FAILED);
   2381     }
   2382 
   2383     /**
   2384      * Verify that the CANCEL_WPS message received from an app without
   2385      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2386      * error code.
   2387      */
   2388     @Test
   2389     public void testCancelWpsWithoutChangePermission() throws Exception {
   2390         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2391                 WifiManager.CANCEL_WPS, WifiManager.CANCEL_WPS_FAILED);
   2392     }
   2393 
   2394     /**
   2395      * Verify that the DISABLE_NETWORK message received from an app without
   2396      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2397      * error code.
   2398      */
   2399     @Test
   2400     public void testDisableNetworkWithoutChangePermission() throws Exception {
   2401         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2402                 WifiManager.DISABLE_NETWORK, WifiManager.DISABLE_NETWORK_FAILED);
   2403     }
   2404 
   2405     /**
   2406      * Verify that the RSSI_PKTCNT_FETCH message received from an app without
   2407      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is rejected with the correct
   2408      * error code.
   2409      */
   2410     @Test
   2411     public void testRssiPktcntFetchWithoutChangePermission() throws Exception {
   2412         verifyAsyncChannelMessageHandlingWithoutChangePermisson(
   2413                 WifiManager.RSSI_PKTCNT_FETCH, WifiManager.RSSI_PKTCNT_FETCH_FAILED);
   2414     }
   2415 
   2416     /**
   2417      * Helper to test handling of async messages by wifi service when the message comes from an
   2418      * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission.
   2419      */
   2420     private void verifyAsyncChannelMessageHandlingWithChangePermisson(
   2421             int requestMsgWhat, Object requestMsgObj) throws RemoteException {
   2422         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
   2423 
   2424         when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true);
   2425 
   2426         Message request = Message.obtain();
   2427         request.what = requestMsgWhat;
   2428         request.obj = requestMsgObj;
   2429 
   2430         tester.sendMessage(request);
   2431         mLooper.dispatchAll();
   2432 
   2433         ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
   2434         verify(mWifiStateMachine).sendMessage(messageArgumentCaptor.capture());
   2435         assertEquals(requestMsgWhat, messageArgumentCaptor.getValue().what);
   2436     }
   2437 
   2438      /**
   2439      * Helper to test handling of async messages by wifi service when the message comes from an
   2440      * app with {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission where we
   2441      * immediately return an error for deprecated functionality.
   2442      */
   2443     private void verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson(
   2444             int requestMsgWhat, Object requestMsgObj) throws Exception {
   2445         WifiAsyncChannelTester tester = verifyAsyncChannelHalfConnected();
   2446 
   2447         when(mWifiPermissionsUtil.checkChangePermission(anyInt())).thenReturn(true);
   2448 
   2449         Message request = Message.obtain();
   2450         request.what = requestMsgWhat;
   2451         request.obj = requestMsgObj;
   2452 
   2453         tester.sendMessage(request);
   2454         mLooper.dispatchAll();
   2455 
   2456         verify(mWifiStateMachine, never()).sendMessage(any());
   2457     }
   2458 
   2459     /**
   2460      * Verify that the CONNECT_NETWORK message received from an app with
   2461      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2462      * WifiStateMachine.
   2463      */
   2464     @Test
   2465     public void testConnectNetworkWithChangePermission() throws Exception {
   2466         verifyAsyncChannelMessageHandlingWithChangePermisson(
   2467                 WifiManager.CONNECT_NETWORK, new WifiConfiguration());
   2468     }
   2469 
   2470     /**
   2471      * Verify that the SAVE_NETWORK message received from an app with
   2472      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2473      * WifiStateMachine.
   2474      */
   2475     @Test
   2476     public void testSaveNetworkWithChangePermission() throws Exception {
   2477         verifyAsyncChannelMessageHandlingWithChangePermisson(
   2478                 WifiManager.SAVE_NETWORK, new WifiConfiguration());
   2479     }
   2480 
   2481     /**
   2482      * Verify that the START_WPS message received from an app with
   2483      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2484      * WifiStateMachine.
   2485      */
   2486     @Test
   2487     public void testStartWpsWithChangePermission() throws Exception {
   2488         verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson(
   2489                 WifiManager.START_WPS, new Object());
   2490     }
   2491 
   2492     /**
   2493      * Verify that the CANCEL_WPS message received from an app with
   2494      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2495      * WifiStateMachine.
   2496      */
   2497     @Test
   2498     public void testCancelWpsWithChangePermission() throws Exception {
   2499         verifyAsyncChannelDeprecatedMessageHandlingNotSentToWSMWithChangePermisson(
   2500                 WifiManager.CANCEL_WPS, new Object());
   2501     }
   2502 
   2503     /**
   2504      * Verify that the DISABLE_NETWORK message received from an app with
   2505      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2506      * WifiStateMachine.
   2507      */
   2508     @Test
   2509     public void testDisableNetworkWithChangePermission() throws Exception {
   2510         verifyAsyncChannelMessageHandlingWithChangePermisson(
   2511                 WifiManager.DISABLE_NETWORK, new Object());
   2512     }
   2513 
   2514     /**
   2515      * Verify that the RSSI_PKTCNT_FETCH message received from an app with
   2516      * {@link android.Manifest.permission#CHANGE_WIFI_STATE} permission is forwarded to
   2517      * WifiStateMachine.
   2518      */
   2519     @Test
   2520     public void testRssiPktcntFetchWithChangePermission() throws Exception {
   2521         verifyAsyncChannelMessageHandlingWithChangePermisson(
   2522                 WifiManager.RSSI_PKTCNT_FETCH, new Object());
   2523     }
   2524 
   2525     /**
   2526      * Verify that setCountryCode() calls WifiCountryCode object on succeess.
   2527      */
   2528     @Test
   2529     public void testSetCountryCode() throws Exception {
   2530         mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
   2531         verify(mWifiCountryCode).setCountryCode(TEST_COUNTRY_CODE);
   2532     }
   2533 
   2534     /**
   2535      * Verify that setCountryCode() fails and doesn't call WifiCountryCode object
   2536      * if the caller doesn't have CONNECTIVITY_INTERNAL permission.
   2537      */
   2538     @Test(expected = SecurityException.class)
   2539     public void testSetCountryCodeFailsWithoutConnectivityInternalPermission() throws Exception {
   2540         doThrow(new SecurityException()).when(mContext)
   2541                 .enforceCallingOrSelfPermission(
   2542                         eq(android.Manifest.permission.CONNECTIVITY_INTERNAL),
   2543                         eq("ConnectivityService"));
   2544         mWifiServiceImpl.setCountryCode(TEST_COUNTRY_CODE);
   2545         verify(mWifiCountryCode, never()).setCountryCode(TEST_COUNTRY_CODE);
   2546     }
   2547 
   2548     /**
   2549      * Set the wifi state machine mock to return a handler created on test thread.
   2550      */
   2551     private void setupWifiStateMachineHandlerForRunWithScissors() {
   2552         HandlerThread handlerThread = createAndStartHandlerThreadForRunWithScissors();
   2553         mHandlerSpyForWsmRunWithScissors = spy(handlerThread.getThreadHandler());
   2554         when(mWifiInjector.getWifiStateMachineHandler())
   2555                 .thenReturn(mHandlerSpyForWsmRunWithScissors);
   2556     }
   2557 
   2558     private HandlerThread createAndStartHandlerThreadForRunWithScissors() {
   2559         HandlerThread handlerThread = new HandlerThread("ServiceHandlerThreadForTest");
   2560         handlerThread.start();
   2561         return handlerThread;
   2562     }
   2563 
   2564     /**
   2565      * Tests the scenario when a scan request arrives while the device is idle. In this case
   2566      * the scan is done when idle mode ends.
   2567      */
   2568     @Test
   2569     public void testHandleDelayedScanAfterIdleMode() throws Exception {
   2570         setupWifiStateMachineHandlerForRunWithScissors();
   2571         when(mFrameworkFacade.inStorageManagerCryptKeeperBounce()).thenReturn(false);
   2572         when(mSettingsStore.isWifiToggleEnabled()).thenReturn(false);
   2573         mWifiServiceImpl.checkAndStartWifi();
   2574         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2575                 (IntentFilter) argThat(new IdleModeIntentMatcher()));
   2576 
   2577         // Tell the wifi service that the device became idle.
   2578         when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
   2579         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
   2580 
   2581         // Send a scan request while the device is idle.
   2582         assertFalse(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   2583         // No scans must be made yet as the device is idle.
   2584         verify(mScanRequestProxy, never()).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   2585 
   2586         // Tell the wifi service that idle mode ended.
   2587         when(mPowerManager.isDeviceIdleMode()).thenReturn(false);
   2588         TestUtil.sendIdleModeChanged(mBroadcastReceiverCaptor.getValue(), mContext);
   2589 
   2590         // Must scan now.
   2591         verify(mScanRequestProxy).startScan(Process.myUid(), TEST_PACKAGE_NAME);
   2592         // The app ops check is executed with this package's identity (not the identity of the
   2593         // original remote caller who requested the scan while idle).
   2594         verify(mAppOpsManager).noteOp(
   2595                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
   2596 
   2597         // Send another scan request. The device is not idle anymore, so it must be executed
   2598         // immediately.
   2599         assertTrue(mWifiServiceImpl.startScan(SCAN_PACKAGE_NAME));
   2600         verify(mScanRequestProxy).startScan(Process.myUid(), SCAN_PACKAGE_NAME);
   2601     }
   2602 
   2603     /**
   2604      * Verify that if the caller has NETWORK_SETTINGS permission, then it doesn't need
   2605      * CHANGE_WIFI_STATE permission.
   2606      * @throws Exception
   2607      */
   2608     @Test
   2609     public void testDisconnectWithNetworkSettingsPerm() throws Exception {
   2610         when(mContext.checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2611                 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
   2612         doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
   2613                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
   2614         doThrow(new SecurityException()).when(mAppOpsManager)
   2615                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
   2616         mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME);
   2617         verify(mWifiStateMachine).disconnectCommand();
   2618     }
   2619 
   2620     /**
   2621      * Verify that if the caller doesn't have NETWORK_SETTINGS permission, it could still
   2622      * get access with the CHANGE_WIFI_STATE permission.
   2623      * @throws Exception
   2624      */
   2625     @Test
   2626     public void testDisconnectWithChangeWifiStatePerm() throws Exception {
   2627         mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME);
   2628         verifyCheckChangePermission(TEST_PACKAGE_NAME);
   2629         verify(mWifiStateMachine).disconnectCommand();
   2630     }
   2631 
   2632     /**
   2633      * Verify that the operation fails if the caller has neither NETWORK_SETTINGS or
   2634      * CHANGE_WIFI_STATE permissions.
   2635      * @throws Exception
   2636      */
   2637     @Test
   2638     public void testDisconnectRejected() throws Exception {
   2639         doThrow(new SecurityException()).when(mAppOpsManager)
   2640                 .noteOp(AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), TEST_PACKAGE_NAME);
   2641         try {
   2642             mWifiServiceImpl.disconnect(TEST_PACKAGE_NAME);
   2643             fail();
   2644         } catch (SecurityException e) {
   2645 
   2646         }
   2647         verifyCheckChangePermission(TEST_PACKAGE_NAME);
   2648         verify(mWifiStateMachine, never()).disconnectCommand();
   2649     }
   2650 
   2651     @Test
   2652     public void testPackageRemovedBroadcastHandling() {
   2653         mWifiServiceImpl.checkAndStartWifi();
   2654         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2655                 (IntentFilter) argThat((IntentFilter filter) ->
   2656                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
   2657 
   2658         int uid = TEST_UID;
   2659         String packageName = TEST_PACKAGE_NAME;
   2660         // Send the broadcast
   2661         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
   2662         intent.putExtra(Intent.EXTRA_UID, uid);
   2663         intent.setData(Uri.fromParts("package", packageName, ""));
   2664         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2665 
   2666         verify(mWifiStateMachine).removeAppConfigs(packageName, uid);
   2667 
   2668         mLooper.dispatchAll();
   2669         verify(mScanRequestProxy).clearScanRequestTimestampsForApp(packageName, uid);
   2670     }
   2671 
   2672     @Test
   2673     public void testPackageRemovedBroadcastHandlingWithNoUid() {
   2674         mWifiServiceImpl.checkAndStartWifi();
   2675         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2676                 (IntentFilter) argThat((IntentFilter filter) ->
   2677                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
   2678 
   2679         String packageName = TEST_PACKAGE_NAME;
   2680         // Send the broadcast
   2681         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
   2682         intent.setData(Uri.fromParts("package", packageName, ""));
   2683         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2684 
   2685         verify(mWifiStateMachine, never()).removeAppConfigs(anyString(), anyInt());
   2686 
   2687         mLooper.dispatchAll();
   2688         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
   2689     }
   2690 
   2691     @Test
   2692     public void testPackageRemovedBroadcastHandlingWithNoPackageName() {
   2693         mWifiServiceImpl.checkAndStartWifi();
   2694         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2695                 (IntentFilter) argThat((IntentFilter filter) ->
   2696                         filter.hasAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)));
   2697 
   2698         int uid = TEST_UID;
   2699         // Send the broadcast
   2700         Intent intent = new Intent(Intent.ACTION_PACKAGE_FULLY_REMOVED);
   2701         intent.putExtra(Intent.EXTRA_UID, uid);
   2702         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2703 
   2704         verify(mWifiStateMachine, never()).removeAppConfigs(anyString(), anyInt());
   2705 
   2706         mLooper.dispatchAll();
   2707         verify(mScanRequestProxy, never()).clearScanRequestTimestampsForApp(anyString(), anyInt());
   2708     }
   2709 
   2710     @Test
   2711     public void testUserRemovedBroadcastHandling() {
   2712         mWifiServiceImpl.checkAndStartWifi();
   2713         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2714                 (IntentFilter) argThat((IntentFilter filter) ->
   2715                         filter.hasAction(Intent.ACTION_USER_REMOVED)));
   2716 
   2717         int userHandle = TEST_USER_HANDLE;
   2718         // Send the broadcast
   2719         Intent intent = new Intent(Intent.ACTION_USER_REMOVED);
   2720         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
   2721         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2722 
   2723         verify(mWifiStateMachine).removeUserConfigs(userHandle);
   2724     }
   2725 
   2726     @Test
   2727     public void testUserRemovedBroadcastHandlingWithWrongIntentAction() {
   2728         mWifiServiceImpl.checkAndStartWifi();
   2729         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2730                 (IntentFilter) argThat((IntentFilter filter) ->
   2731                         filter.hasAction(Intent.ACTION_USER_REMOVED)));
   2732 
   2733         int userHandle = TEST_USER_HANDLE;
   2734         // Send the broadcast with wrong action
   2735         Intent intent = new Intent(Intent.ACTION_USER_FOREGROUND);
   2736         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
   2737         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2738 
   2739         verify(mWifiStateMachine, never()).removeUserConfigs(userHandle);
   2740     }
   2741 
   2742     /**
   2743      * Test for needs5GHzToAnyApBandConversion returns true.  Requires the NETWORK_SETTINGS
   2744      * permission.
   2745      */
   2746     @Test
   2747     public void testNeeds5GHzToAnyApBandConversionReturnedTrue() {
   2748         when(mResources.getBoolean(
   2749                 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any)))
   2750                 .thenReturn(true);
   2751         assertTrue(mWifiServiceImpl.needs5GHzToAnyApBandConversion());
   2752 
   2753         verify(mContext).enforceCallingOrSelfPermission(
   2754                 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService"));
   2755     }
   2756 
   2757     /**
   2758      * Test for needs5GHzToAnyApBandConversion returns false.  Requires the NETWORK_SETTINGS
   2759      * permission.
   2760      */
   2761     @Test
   2762     public void testNeeds5GHzToAnyApBandConversionReturnedFalse() {
   2763         when(mResources.getBoolean(
   2764                 eq(com.android.internal.R.bool.config_wifi_convert_apband_5ghz_to_any)))
   2765                 .thenReturn(false);
   2766 
   2767         assertFalse(mWifiServiceImpl.needs5GHzToAnyApBandConversion());
   2768 
   2769         verify(mContext).enforceCallingOrSelfPermission(
   2770                 eq(android.Manifest.permission.NETWORK_SETTINGS), eq("WifiService"));
   2771     }
   2772 
   2773     /**
   2774      * The API impl for needs5GHzToAnyApBandConversion requires the NETWORK_SETTINGS permission,
   2775      * verify an exception is thrown without holding the permission.
   2776      */
   2777     @Test
   2778     public void testNeeds5GHzToAnyApBandConversionThrowsWithoutProperPermissions() {
   2779         doThrow(new SecurityException()).when(mContext)
   2780                 .enforceCallingOrSelfPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2781                                                 eq("WifiService"));
   2782 
   2783         try {
   2784             mWifiServiceImpl.needs5GHzToAnyApBandConversion();
   2785             // should have thrown an exception - fail test
   2786             fail();
   2787         } catch (SecurityException e) {
   2788             // expected
   2789         }
   2790     }
   2791 
   2792 
   2793     private class IdleModeIntentMatcher implements ArgumentMatcher<IntentFilter> {
   2794         @Override
   2795         public boolean matches(IntentFilter filter) {
   2796             return filter.hasAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
   2797         }
   2798     }
   2799 
   2800     /**
   2801      * Verifies that enforceChangePermission(String package) is called and the caller doesn't
   2802      * have NETWORK_SETTINGS permission
   2803      */
   2804     private void verifyCheckChangePermission(String callingPackageName) {
   2805         verify(mContext, atLeastOnce())
   2806                 .checkPermission(eq(android.Manifest.permission.NETWORK_SETTINGS),
   2807                         anyInt(), anyInt());
   2808         verify(mContext, atLeastOnce()).enforceCallingOrSelfPermission(
   2809                 android.Manifest.permission.CHANGE_WIFI_STATE, "WifiService");
   2810         verify(mAppOpsManager, atLeastOnce()).noteOp(
   2811                 AppOpsManager.OPSTR_CHANGE_WIFI_STATE, Process.myUid(), callingPackageName);
   2812     }
   2813 
   2814     private WifiConfiguration createValidSoftApConfiguration() {
   2815         WifiConfiguration apConfig = new WifiConfiguration();
   2816         apConfig.SSID = "TestAp";
   2817         apConfig.preSharedKey = "thisIsABadPassword";
   2818         apConfig.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
   2819         apConfig.apBand = WifiConfiguration.AP_BAND_2GHZ;
   2820 
   2821         return apConfig;
   2822     }
   2823 
   2824     /**
   2825      * Verifies that sim state change does not set or reset the country code
   2826      */
   2827     @Test
   2828     public void testSimStateChangeDoesNotResetCountryCode() {
   2829         mWifiServiceImpl.checkAndStartWifi();
   2830         verify(mContext).registerReceiver(mBroadcastReceiverCaptor.capture(),
   2831                 (IntentFilter) argThat((IntentFilter filter) ->
   2832                         filter.hasAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED)));
   2833 
   2834         int userHandle = TEST_USER_HANDLE;
   2835         // Send the broadcast
   2836         Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
   2837         intent.putExtra(Intent.EXTRA_USER_HANDLE, userHandle);
   2838         mBroadcastReceiverCaptor.getValue().onReceive(mContext, intent);
   2839         verifyNoMoreInteractions(mWifiCountryCode);
   2840     }
   2841 }
   2842