From 9a99a8a4fcdc64c67f016f5a07ffae0792d5e5cf Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Wed, 9 Oct 2019 07:19:30 -0700 Subject: WifiService: Revert get/remove passpoint API deprecation Allow apps to get/remove passpoint profiles installed by them. Privileged apps can continue to get/remove all profiles. Bug: 141639265 Test: atest com.android.server.wifi Change-Id: Id073c25a021dbeb81e87064e93ead966a363390e Merged-In: Id073c25a021dbeb81e87064e93ead966a363390e --- .../com/android/server/wifi/ClientModeImpl.java | 22 +++++-- .../com/android/server/wifi/WifiServiceImpl.java | 27 ++++---- .../server/wifi/hotspot2/PasspointManager.java | 30 ++++++--- .../android/server/wifi/ClientModeImplTest.java | 26 ++++---- .../android/server/wifi/WifiServiceImplTest.java | 77 ++++++++-------------- .../server/wifi/hotspot2/PasspointManagerTest.java | 65 ++++++++++++++---- 6 files changed, 143 insertions(+), 104 deletions(-) diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java index 66f138097..134977a62 100644 --- a/service/java/com/android/server/wifi/ClientModeImpl.java +++ b/service/java/com/android/server/wifi/ClientModeImpl.java @@ -1780,12 +1780,14 @@ public class ClientModeImpl extends StateMachine { * Remove a Passpoint configuration synchronously. * * @param channel Channel for communicating with the state machine + * @param privileged Whether the caller is a privileged entity * @param fqdn The FQDN of the Passpoint configuration to remove * @return true on success */ - public boolean syncRemovePasspointConfig(AsyncChannel channel, String fqdn) { + public boolean syncRemovePasspointConfig(AsyncChannel channel, boolean privileged, + String fqdn) { Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_PASSPOINT_CONFIG, - fqdn); + privileged ? 1 : 0, 0, fqdn); if (messageIsNull(resultMsg)) return false; boolean result = (resultMsg.arg1 == SUCCESS); resultMsg.recycle(); @@ -1796,10 +1798,13 @@ public class ClientModeImpl extends StateMachine { * Get the list of installed Passpoint configurations synchronously. * * @param channel Channel for communicating with the state machine + * @param privileged Whether the caller is a privileged entity * @return List of {@link PasspointConfiguration} */ - public List syncGetPasspointConfigs(AsyncChannel channel) { - Message resultMsg = channel.sendMessageSynchronously(CMD_GET_PASSPOINT_CONFIGS); + public List syncGetPasspointConfigs(AsyncChannel channel, + boolean privileged) { + Message resultMsg = channel.sendMessageSynchronously(CMD_GET_PASSPOINT_CONFIGS, + privileged ? 1 : 0); if (messageIsNull(resultMsg)) return null; List result = (List) resultMsg.obj; resultMsg.recycle(); @@ -3685,11 +3690,13 @@ public class ClientModeImpl extends StateMachine { break; case CMD_REMOVE_PASSPOINT_CONFIG: int removeResult = mPasspointManager.removeProvider( - (String) message.obj) ? SUCCESS : FAILURE; + message.sendingUid, message.arg1 == 1, (String) message.obj) + ? SUCCESS : FAILURE; replyToMessage(message, message.what, removeResult); break; case CMD_GET_PASSPOINT_CONFIGS: - replyToMessage(message, message.what, mPasspointManager.getProviderConfigs()); + replyToMessage(message, message.what, mPasspointManager.getProviderConfigs( + message.sendingUid, message.arg1 == 1)); break; case CMD_RESET_SIM_NETWORKS: /* Defer this message until supplicant is started. */ @@ -4524,7 +4531,8 @@ public class ClientModeImpl extends StateMachine { break; case CMD_REMOVE_PASSPOINT_CONFIG: String fqdn = (String) message.obj; - if (mPasspointManager.removeProvider(fqdn)) { + if (mPasspointManager.removeProvider( + message.sendingUid, message.arg1 == 1, fqdn)) { if (isProviderOwnedNetwork(mTargetNetworkId, fqdn) || isProviderOwnedNetwork(mLastNetworkId, fqdn)) { logd("Disconnect from current network since its provider is removed"); diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index 2d15af53c..650f33d36 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -2309,18 +2309,16 @@ public class WifiServiceImpl extends BaseWifiService { @Override public boolean removePasspointConfiguration(String fqdn, String packageName) { final int uid = Binder.getCallingUid(); - if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) - && !mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) { - if (mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)) { - return false; - } - throw new SecurityException(TAG + ": Permission denied"); + boolean privileged = false; + if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) + || mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) { + privileged = true; } mLog.info("removePasspointConfiguration uid=%").c(Binder.getCallingUid()).flush(); if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_PASSPOINT)) { return false; } - return mClientModeImpl.syncRemovePasspointConfig(mClientModeImplChannel, fqdn); + return mClientModeImpl.syncRemovePasspointConfig(mClientModeImplChannel, privileged, fqdn); } /** @@ -2333,13 +2331,10 @@ public class WifiServiceImpl extends BaseWifiService { @Override public List getPasspointConfigurations(String packageName) { final int uid = Binder.getCallingUid(); - mAppOps.checkPackage(uid, packageName); - if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) - && !mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) { - if (mWifiPermissionsUtil.isTargetSdkLessThan(packageName, Build.VERSION_CODES.Q, uid)) { - return new ArrayList<>(); - } - throw new SecurityException(TAG + ": Permission denied"); + boolean privileged = false; + if (mWifiPermissionsUtil.checkNetworkSettingsPermission(uid) + || mWifiPermissionsUtil.checkNetworkSetupWizardPermission(uid)) { + privileged = true; } if (mVerboseLoggingEnabled) { mLog.info("getPasspointConfigurations uid=%").c(Binder.getCallingUid()).flush(); @@ -2348,7 +2343,7 @@ public class WifiServiceImpl extends BaseWifiService { PackageManager.FEATURE_WIFI_PASSPOINT)) { return new ArrayList<>(); } - return mClientModeImpl.syncGetPasspointConfigs(mClientModeImplChannel); + return mClientModeImpl.syncGetPasspointConfigs(mClientModeImplChannel, privileged); } /** @@ -2975,7 +2970,7 @@ public class WifiServiceImpl extends BaseWifiService { if (mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_PASSPOINT)) { List configs = mClientModeImpl.syncGetPasspointConfigs( - mClientModeImplChannel); + mClientModeImplChannel, true); if (configs != null) { for (PasspointConfiguration config : configs) { removePasspointConfiguration(config.getHomeSp().getFqdn(), packageName); diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index e54cee8e9..c46873761 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -288,7 +288,7 @@ public class PasspointManager { for (Map.Entry entry : getPasspointProviderWithPackage( packageName).entrySet()) { String fqdn = entry.getValue().getConfig().getHomeSp().getFqdn(); - removeProvider(fqdn); + removeProvider(Process.WIFI_UID /* ignored */, true, fqdn); disconnectIfPasspointNetwork(fqdn); } } @@ -658,18 +658,26 @@ public class PasspointManager { /** * Remove a Passpoint provider identified by the given FQDN. * + * @param callingUid Calling UID. + * @param privileged Whether the caller is a privileged entity * @param fqdn The FQDN of the provider to remove * @return true if a provider is removed, false otherwise */ - public boolean removeProvider(String fqdn) { + public boolean removeProvider(int callingUid, boolean privileged, String fqdn) { mWifiMetrics.incrementNumPasspointProviderUninstallation(); String packageName; - if (!mProviders.containsKey(fqdn)) { + PasspointProvider provider = mProviders.get(fqdn); + if (provider == null) { Log.e(TAG, "Config doesn't exist"); return false; } - mProviders.get(fqdn).uninstallCertsAndKeys(); - packageName = mProviders.get(fqdn).getPackageName(); + if (!privileged && callingUid != provider.getCreatorUid()) { + Log.e(TAG, "UID " + callingUid + " cannot remove profile created by " + + provider.getCreatorUid()); + return false; + } + provider.uninstallCertsAndKeys(); + packageName = provider.getPackageName(); mProviders.remove(fqdn); mWifiConfigManager.saveToStore(true /* forceWrite */); @@ -702,12 +710,17 @@ public class PasspointManager { * * An empty list will be returned when no provider is installed. * + * @param callingUid Calling UID. + * @param privileged Whether the caller is a privileged entity * @return A list of {@link PasspointConfiguration} */ - public List getProviderConfigs() { + public List getProviderConfigs(int callingUid, boolean privileged) { List configs = new ArrayList<>(); for (Map.Entry entry : mProviders.entrySet()) { - configs.add(entry.getValue().getConfig()); + PasspointProvider provider = entry.getValue(); + if (privileged || callingUid == provider.getCreatorUid()) { + configs.add(provider.getConfig()); + } } return configs; } @@ -1007,7 +1020,8 @@ public class PasspointManager { public Map getMatchingPasspointConfigsForOsuProviders( List osuProviders) { Map matchingPasspointConfigs = new HashMap<>(); - List passpointConfigurations = getProviderConfigs(); + List passpointConfigurations = + getProviderConfigs(Process.WIFI_UID /* ignored */, true); for (OsuProvider osuProvider : osuProviders) { Map friendlyNamesForOsuProvider = osuProvider.getFriendlyNameList(); diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java index 7896a8f0b..26c89adf9 100644 --- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java @@ -1866,15 +1866,15 @@ public class ClientModeImplTest { @Test public void syncRemovePasspointConfig() throws Exception { String fqdn = "test.com"; - when(mPasspointManager.removeProvider(fqdn)).thenReturn(true); + when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(true); mLooper.startAutoDispatch(); - assertTrue(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, fqdn)); + assertTrue(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, true, fqdn)); mLooper.stopAutoDispatch(); reset(mPasspointManager); - when(mPasspointManager.removeProvider(fqdn)).thenReturn(false); + when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), eq(fqdn))).thenReturn(false); mLooper.startAutoDispatch(); - assertFalse(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, fqdn)); + assertFalse(mCmi.syncRemovePasspointConfig(mCmiAsyncChannel, true, fqdn)); mLooper.stopAutoDispatch(); } @@ -1902,16 +1902,17 @@ public class ClientModeImplTest { config.setHomeSp(homeSp); expectedConfigs.add(config); - when(mPasspointManager.getProviderConfigs()).thenReturn(expectedConfigs); + when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean())) + .thenReturn(expectedConfigs); mLooper.startAutoDispatch(); - assertEquals(expectedConfigs, mCmi.syncGetPasspointConfigs(mCmiAsyncChannel)); + assertEquals(expectedConfigs, mCmi.syncGetPasspointConfigs(mCmiAsyncChannel, true)); mLooper.stopAutoDispatch(); reset(mPasspointManager); - when(mPasspointManager.getProviderConfigs()) - .thenReturn(new ArrayList()); + when(mPasspointManager.getProviderConfigs(anyInt(), anyBoolean())) + .thenReturn(new ArrayList<>()); mLooper.startAutoDispatch(); - assertTrue(mCmi.syncGetPasspointConfigs(mCmiAsyncChannel).isEmpty()); + assertTrue(mCmi.syncGetPasspointConfigs(mCmiAsyncChannel, true).isEmpty()); mLooper.stopAutoDispatch(); } @@ -3544,14 +3545,15 @@ public class ClientModeImplTest { @Test public void testRemovePasspointConfig() throws Exception { String fqdn = "test.com"; - when(mPasspointManager.removeProvider(anyString())).thenReturn(true); + when(mPasspointManager.removeProvider(anyInt(), anyBoolean(), anyString())) + .thenReturn(true); // switch to connect mode and verify wifi is reported as enabled startSupplicantAndDispatchMessages(); - mCmi.sendMessage(ClientModeImpl.CMD_REMOVE_PASSPOINT_CONFIG, fqdn); + mCmi.sendMessage(ClientModeImpl.CMD_REMOVE_PASSPOINT_CONFIG, TEST_UID, 0, fqdn); mLooper.dispatchAll(); - verify(mWifiConfigManager).removePasspointConfiguredNetwork(eq(fqdn)); + verify(mWifiConfigManager).removePasspointConfiguredNetwork(fqdn); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 9a3bd75be..494d9011b 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -174,6 +174,7 @@ public class WifiServiceImplTest { private static final String WIFI_IFACE_NAME2 = "wlan1"; private static final String TEST_COUNTRY_CODE = "US"; private static final String TEST_FACTORY_MAC = "10:22:34:56:78:92"; + private static final String TEST_FQDN = "testfqdn"; private static final List TEST_WIFI_CONFIGURATION_LIST = Arrays.asList( WifiConfigurationTestUtil.generateWifiConfig( 0, 1000000, "\"red\"", true, true, null, null), @@ -2788,77 +2789,53 @@ public class WifiServiceImplTest { } /** - * Verify that the call to getPasspointConfigurations is not redirected to specific API - * syncGetPasspointConfigs when the caller doesn't have NETWORK_SETTINGS permissions and - * NETWORK_SETUP_WIZARD. + * Verify the call to getPasspointConfigurations when the caller doesn't have + * NETWORK_SETTINGS and NETWORK_SETUP_WIZARD permissions. */ - @Test(expected = SecurityException.class) - public void testGetPasspointConfigurationsWithOutPermissions() { + public void testGetPasspointConfigurationsWithOutPrivilegedPermissions() { when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false); mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME); + + verify(mClientModeImpl).syncGetPasspointConfigs(any(), eq(false)); } /** - * Verify that getPasspointConfigurations called by apps that has invalid package will - * throw {@link SecurityException}. + * Verify that the call to getPasspointConfigurations when the caller does have + * NETWORK_SETTINGS permission. */ - @Test(expected = SecurityException.class) - public void testGetPasspointConfigurationWithInvalidPackage() { - doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), - eq(TEST_PACKAGE_NAME)); + public void testGetPasspointConfigurationsWithPrivilegedPermissions() { when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(true); - when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(true); mWifiServiceImpl.getPasspointConfigurations(TEST_PACKAGE_NAME); - } - - /** - * Verify that getPasspointConfigurations called by apps targeting below Q SDK will return - * empty list if the caller doesn't have NETWORK_SETTINGS permissions and NETWORK_SETUP_WIZARD. - */ - @Test - public void testGetPasspointConfigurationForAppsTargetingBelowQSDK() { - when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); - when(mWifiPermissionsUtil.checkNetworkSetupWizardPermission(anyInt())).thenReturn(false); - when(mWifiPermissionsUtil.isTargetSdkLessThan(eq(TEST_PACKAGE_NAME), - eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true); - List result = mWifiServiceImpl.getPasspointConfigurations( - TEST_PACKAGE_NAME); - assertNotNull(result); - assertEquals(0, result.size()); + verify(mClientModeImpl).syncGetPasspointConfigs(any(), eq(true)); } /** - * Verify that the call to removePasspointConfiguration is not redirected to specific API - * syncRemovePasspointConfig when the caller doesn't have NETWORK_SETTINGS and - * NETWORK_CARRIER_PROVISIONING permission. + * Verify the call to removePasspointConfigurations when the caller doesn't have + * NETWORK_SETTINGS and NETWORK_CARRIER_PROVISIONING permissions. */ - @Test(expected = SecurityException.class) - public void testRemovePasspointConfigurationWithOutPermissions() { + public void testRemovePasspointConfigurationWithOutPrivilegedPermissions() { when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn( false); - mWifiServiceImpl.removePasspointConfiguration(null, null); + mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME); + verify(mClientModeImpl).syncRemovePasspointConfig(any(), eq(false), eq(TEST_FQDN)); } /** - * Verify that the call to removePasspointConfiguration for apps targeting below Q SDK will - * return false if the caller doesn't have NETWORK_SETTINGS and NETWORK_CARRIER_PROVISIONING - * permission. + * Verify the call to removePasspointConfigurations when the caller does have + * NETWORK_CARRIER_PROVISIONING permission. */ - @Test - public void testRemovePasspointConfigurationForAppsTargetingBelowQSDK() { - when(mWifiPermissionsUtil.checkNetworkSettingsPermission(anyInt())).thenReturn(false); + public void testRemovePasspointConfigurationWithPrivilegedPermissions() { when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(anyInt())).thenReturn( - false); - when(mWifiPermissionsUtil.isTargetSdkLessThan(isNull(), - eq(Build.VERSION_CODES.Q), anyInt())).thenReturn(true); + true); - assertFalse(mWifiServiceImpl.removePasspointConfiguration(null, null)); + mWifiServiceImpl.removePasspointConfiguration(TEST_FQDN, TEST_PACKAGE_NAME); + verify(mClientModeImpl).syncRemovePasspointConfig(any(), eq(true), eq(TEST_FQDN)); } /** @@ -3650,13 +3627,14 @@ public class WifiServiceImplTest { mWifiServiceImpl.mClientModeImplChannel = mAsyncChannel; when(mClientModeImpl.syncGetConfiguredNetworks(anyInt(), any(), anyInt())) .thenReturn(Arrays.asList(network)); - when(mClientModeImpl.syncGetPasspointConfigs(any())).thenReturn(Arrays.asList(config)); + when(mClientModeImpl.syncGetPasspointConfigs(any(), anyBoolean())) + .thenReturn(Arrays.asList(config)); mWifiServiceImpl.factoryReset(TEST_PACKAGE_NAME); mLooper.dispatchAll(); verify(mClientModeImpl).syncRemoveNetwork(mAsyncChannel, network.networkId); - verify(mClientModeImpl).syncRemovePasspointConfig(mAsyncChannel, fqdn); + verify(mClientModeImpl).syncRemovePasspointConfig(mAsyncChannel, true, fqdn); verify(mWifiConfigManager).clearDeletedEphemeralNetworks(); verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints(); verify(mWifiNetworkSuggestionsManager).clear(); @@ -3679,8 +3657,9 @@ public class WifiServiceImplTest { mLooper.dispatchAll(); verify(mClientModeImpl).syncGetConfiguredNetworks(anyInt(), any(), anyInt()); - verify(mClientModeImpl, never()).syncGetPasspointConfigs(any()); - verify(mClientModeImpl, never()).syncRemovePasspointConfig(any(), anyString()); + verify(mClientModeImpl, never()).syncGetPasspointConfigs(any(), anyBoolean()); + verify(mClientModeImpl, never()).syncRemovePasspointConfig( + any(), anyBoolean(), anyString()); verify(mWifiConfigManager).clearDeletedEphemeralNetworks(); verify(mClientModeImpl).clearNetworkRequestUserApprovedAccessPoints(); verify(mWifiNetworkSuggestionsManager).clear(); @@ -3703,7 +3682,7 @@ public class WifiServiceImplTest { } catch (SecurityException e) { } verify(mClientModeImpl, never()).syncGetConfiguredNetworks(anyInt(), any(), anyInt()); - verify(mClientModeImpl, never()).syncGetPasspointConfigs(any()); + verify(mClientModeImpl, never()).syncGetPasspointConfigs(any(), eq(false)); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java index 338f7bc40..131425af8 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java @@ -268,7 +268,8 @@ public class PasspointManagerTest { * @param expectedConfig The expected installed Passpoint configuration */ private void verifyInstalledConfig(PasspointConfiguration expectedConfig) { - List installedConfigs = mManager.getProviderConfigs(); + List installedConfigs = + mManager.getProviderConfigs(TEST_CREATOR_UID, true); assertEquals(1, installedConfigs.size()); assertEquals(expectedConfig, installedConfigs.get(0)); } @@ -283,6 +284,7 @@ public class PasspointManagerTest { PasspointProvider provider = mock(PasspointProvider.class); when(provider.installCertsAndKeys()).thenReturn(true); lenient().when(provider.getConfig()).thenReturn(config); + lenient().when(provider.getCreatorUid()).thenReturn(TEST_CREATOR_UID); return provider; } @@ -651,14 +653,14 @@ public class PasspointManagerTest { // Provider index start with 0, should be 1 after adding a provider. assertEquals(1, mSharedDataSource.getProviderIndex()); - // Remove the provider. - assertTrue(mManager.removeProvider(TEST_FQDN)); + // Remove the provider as the creator app. + assertTrue(mManager.removeProvider(TEST_CREATOR_UID, false, TEST_FQDN)); verify(provider).uninstallCertsAndKeys(); verify(mWifiConfigManager).saveToStore(true); verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); verify(mAppOpsManager).stopWatchingMode(any(AppOpsManager.OnOpChangedListener.class)); - assertTrue(mManager.getProviderConfigs().isEmpty()); + assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); // Verify content in the data source. assertTrue(mUserDataSource.getProviders().isEmpty()); @@ -694,13 +696,13 @@ public class PasspointManagerTest { // Provider index start with 0, should be 1 after adding a provider. assertEquals(1, mSharedDataSource.getProviderIndex()); - // Remove the provider. - assertTrue(mManager.removeProvider(TEST_FQDN)); + // Remove the provider as a privileged non-creator app. + assertTrue(mManager.removeProvider(TEST_UID, true, TEST_FQDN)); verify(provider).uninstallCertsAndKeys(); verify(mWifiConfigManager).saveToStore(true); verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); verify(mWifiMetrics).incrementNumPasspointProviderUninstallSuccess(); - assertTrue(mManager.getProviderConfigs().isEmpty()); + assertTrue(mManager.getProviderConfigs(TEST_UID, true).isEmpty()); // Verify content in the data source. assertTrue(mUserDataSource.getProviders().isEmpty()); @@ -824,7 +826,7 @@ public class PasspointManagerTest { */ @Test public void removeNonExistingProvider() throws Exception { - assertFalse(mManager.removeProvider(TEST_FQDN)); + assertFalse(mManager.removeProvider(TEST_CREATOR_UID, true, TEST_FQDN)); verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); } @@ -1285,8 +1287,8 @@ public class PasspointManagerTest { mUserDataSource.setProviders(providers); // Verify the providers maintained by PasspointManager. - assertEquals(1, mManager.getProviderConfigs().size()); - assertEquals(config, mManager.getProviderConfigs().get(0)); + assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size()); + assertEquals(config, mManager.getProviderConfigs(TEST_CREATOR_UID, true).get(0)); } /** @@ -1800,7 +1802,7 @@ public class PasspointManagerTest { verify(mAppOpsManager).startWatchingMode(eq(OPSTR_CHANGE_WIFI_STATE), eq(TEST_PACKAGE), mAppOpChangedListenerCaptor.capture()); - assertEquals(1, mManager.getProviderConfigs().size()); + assertEquals(1, mManager.getProviderConfigs(TEST_CREATOR_UID, true).size()); AppOpsManager.OnOpChangedListener listener = mAppOpChangedListenerCaptor.getValue(); assertNotNull(listener); @@ -1814,6 +1816,45 @@ public class PasspointManagerTest { verify(mAppOpsManager).stopWatchingMode(mAppOpChangedListenerCaptor.getValue()); verify(mClientModeImpl).disconnectCommand(); - assertTrue(mManager.getProviderConfigs().isEmpty()); + assertTrue(mManager.getProviderConfigs(TEST_CREATOR_UID, true).isEmpty()); + } + + /** + * Verify that removing a provider with a different UID will not succeed. + * + * @throws Exception + */ + @Test + public void removeGetProviderWithDifferentUid() throws Exception { + PasspointConfiguration config = createTestConfigWithSimCredential(TEST_FQDN, TEST_IMSI, + TEST_REALM); + PasspointProvider provider = createMockProvider(config); + when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), + eq(mSimAccessor), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE))).thenReturn( + provider); + assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE)); + verifyInstalledConfig(config); + verify(mWifiConfigManager).saveToStore(true); + verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); + verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); + reset(mWifiMetrics); + reset(mWifiConfigManager); + + // no profiles available for TEST_UID + assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty()); + // 1 profile available for TEST_CREATOR_UID + assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); + + // Remove the provider as a non-privileged non-creator app. + assertFalse(mManager.removeProvider(TEST_UID, false, TEST_FQDN)); + verify(provider, never()).uninstallCertsAndKeys(); + verify(mWifiConfigManager, never()).saveToStore(true); + verify(mWifiMetrics).incrementNumPasspointProviderUninstallation(); + verify(mWifiMetrics, never()).incrementNumPasspointProviderUninstallSuccess(); + + // no profiles available for TEST_UID + assertTrue(mManager.getProviderConfigs(TEST_UID, false).isEmpty()); + // 1 profile available for TEST_CREATOR_UID + assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); } } -- cgit v1.2.3