From b0fe21782f2d4f9101aed3455b0c8f8632698e88 Mon Sep 17 00:00:00 2001 From: Jeremy Joslin Date: Fri, 31 Mar 2017 10:38:31 -0700 Subject: [PATCH] Migrate the NETWORK_SCORER_APP Setting. Migrate the value of NETWORK_SCORER_APP to the USE_OPEN_WIFI_PACKAGE Setting if the following conditions are true: * NETWORK_SCORER_APP has a value * An active scorer/recommender is present. * The active scorer specifies a valid UseOpenWifiActivity. * The NETWORK_SCORER_APP value matches the package name of the UseOpenWifiActivity or the active scorer. Test: runtest frameworks-services -c com.android.server.NetworkScorerAppManagerTest Bug: 36718516 Change-Id: I7d7a56c62b4a7f4a0e43824fbb2075e80d7a753b --- .../android/server/NetworkScoreService.java | 1 + .../server/NetworkScorerAppManager.java | 63 ++++++- .../server/NetworkScorerAppManagerTest.java | 169 ++++++++++++++++++ 3 files changed, 224 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index a5debda34a015..9218c25a9860e 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -280,6 +280,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { if (DBG) Log.d(TAG, "refreshBinding()"); // Make sure the scorer is up-to-date mNetworkScorerAppManager.updateState(); + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); registerPackageMonitorIfNeeded(); bindToScoringServiceIfNeeded(); } diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java index 1a3bb357eb7b0..e127eb9c44aff 100644 --- a/services/core/java/com/android/server/NetworkScorerAppManager.java +++ b/services/core/java/com/android/server/NetworkScorerAppManager.java @@ -42,7 +42,6 @@ import java.util.List; * * @hide */ -@VisibleForTesting public class NetworkScorerAppManager { private static final String TAG = "NetworkScorerAppManager"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -64,8 +63,7 @@ public class NetworkScorerAppManager { * Returns the list of available scorer apps. The list will be empty if there are * no valid scorers. */ - @VisibleForTesting - public List getAllValidScorers() { + List getAllValidScorers() { if (VERBOSE) Log.v(TAG, "getAllValidScorers()"); final PackageManager pm = mContext.getPackageManager(); final Intent serviceIntent = new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS); @@ -170,8 +168,7 @@ public class NetworkScorerAppManager { * it was disabled or uninstalled). */ @Nullable - @VisibleForTesting - public NetworkScorerAppData getActiveScorer() { + NetworkScorerAppData getActiveScorer() { final int enabledSetting = getNetworkRecommendationsEnabledSetting(); if (enabledSetting == NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF) { return null; @@ -214,8 +211,7 @@ public class NetworkScorerAppManager { * @return true if the scorer was changed, or false if the package is not a valid scorer or * a valid network recommendation provider exists. */ - @VisibleForTesting - public boolean setActiveScorer(String packageName) { + boolean setActiveScorer(String packageName) { final String oldPackageName = getNetworkRecommendationsPackage(); if (TextUtils.equals(oldPackageName, packageName)) { @@ -250,8 +246,7 @@ public class NetworkScorerAppManager { * is no longer valid then {@link Settings.Global#NETWORK_RECOMMENDATIONS_ENABLED} will be set * to 0 (disabled). */ - @VisibleForTesting - public void updateState() { + void updateState() { final int enabledSetting = getNetworkRecommendationsEnabledSetting(); if (enabledSetting == NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF) { // Don't change anything if it's forced off. @@ -286,6 +281,56 @@ public class NetworkScorerAppManager { } } + /** + * Migrates the NETWORK_SCORER_APP Setting to the USE_OPEN_WIFI_PACKAGE Setting. + */ + void migrateNetworkScorerAppSettingIfNeeded() { + final String scorerAppPkgNameSetting = + mSettingsFacade.getString(mContext, Settings.Global.NETWORK_SCORER_APP); + if (TextUtils.isEmpty(scorerAppPkgNameSetting)) { + // Early exit, nothing to do. + return; + } + + final NetworkScorerAppData currentAppData = getActiveScorer(); + if (currentAppData == null) { + // Don't touch anything until we have an active scorer to work with. + return; + } + + if (DEBUG) { + Log.d(TAG, "Migrating Settings.Global.NETWORK_SCORER_APP " + + "(" + scorerAppPkgNameSetting + ")..."); + } + + // If the new (useOpenWifi) Setting isn't set and the old Setting's value matches the + // new metadata value then update the new Setting with the old value. Otherwise it's a + // mismatch so we shouldn't enable the Setting automatically. + final ComponentName enableUseOpenWifiActivity = + currentAppData.getEnableUseOpenWifiActivity(); + final String useOpenWifiSetting = + mSettingsFacade.getString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE); + if (TextUtils.isEmpty(useOpenWifiSetting) + && enableUseOpenWifiActivity != null + && scorerAppPkgNameSetting.equals(enableUseOpenWifiActivity.getPackageName())) { + mSettingsFacade.putString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE, + scorerAppPkgNameSetting); + if (DEBUG) { + Log.d(TAG, "Settings.Global.USE_OPEN_WIFI_PACKAGE set to " + + "'" + scorerAppPkgNameSetting + "'."); + } + } + + // Clear out the old setting so we don't run through the migration code again. + mSettingsFacade.putString(mContext, Settings.Global.NETWORK_SCORER_APP, null); + if (DEBUG) { + Log.d(TAG, "Settings.Global.NETWORK_SCORER_APP migration complete."); + final String setting = + mSettingsFacade.getString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE); + Log.d(TAG, "Settings.Global.USE_OPEN_WIFI_PACKAGE is: '" + setting + "'."); + } + } + private String getDefaultPackageSetting() { return mContext.getResources().getString( R.string.config_defaultNetworkRecommendationProviderPackage); diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java index 9197ccf972c41..0694eaefd288b 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java @@ -22,6 +22,7 @@ import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertFalse; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; @@ -170,6 +171,7 @@ public class NetworkScorerAppManagerTest { mockScoreNetworksGranted(recoComponent.getPackageName()); mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, enableUseOpenWifiComponent.getPackageName()); + mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); assertNotNull(activeScorer); @@ -350,6 +352,173 @@ public class NetworkScorerAppManagerTest { eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any()); } + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsNull() + throws Exception { + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)).thenReturn(null); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsEmpty() + throws Exception { + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)).thenReturn(""); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerIsNotActive() + throws Exception { + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)).thenReturn("com.foo.package"); + // Make getActiveScorer() return null. + setRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiSettingIsNotEmpty() + throws Exception { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + enableUseOpenWifiComponent.getPackageName()); + mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)) + .thenReturn(enableUseOpenWifiComponent.getPackageName()); + // The setting has a value so the migration shouldn't touch it. + when(mSettingsFacade.getString(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)) + .thenReturn(enableUseOpenWifiComponent.getPackageName()); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiActivityNotAvail() + throws Exception { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + // The active component doesn't have an open wifi activity so the migration shouldn't + // set USE_OPEN_WIFI_PACKAGE. + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + null /*useOpenWifiActivityPackage*/); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)) + .thenReturn(enableUseOpenWifiComponent.getPackageName()); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_activity() + throws Exception { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + enableUseOpenWifiComponent.getPackageName()); + mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); + // The older network scorer app setting doesn't match the new use open wifi activity package + // so the migration shouldn't set USE_OPEN_WIFI_PACKAGE. + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)) + .thenReturn(enableUseOpenWifiComponent.getPackageName() + ".diff"); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_service() + throws Exception { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + enableUseOpenWifiComponent.getPackageName()); + mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); + // The older network scorer app setting doesn't match the active package so the migration + // shouldn't set USE_OPEN_WIFI_PACKAGE. + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)) + .thenReturn(recoComponent.getPackageName() + ".diff"); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade, never()).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); + } + + @Test + public void testMigrateNetworkScorerAppSettingIfNeeded_packageMatch_activity() + throws Exception { + final ComponentName recoComponent = new ComponentName("package1", "class1"); + final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); + setNetworkRecoPackageSetting(recoComponent.getPackageName()); + mockScoreNetworksGranted(recoComponent.getPackageName()); + mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, + enableUseOpenWifiComponent.getPackageName()); + mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); + // Old setting matches the new activity package, migration should happen. + when(mSettingsFacade.getString(mMockContext, + Settings.Global.NETWORK_SCORER_APP)) + .thenReturn(enableUseOpenWifiComponent.getPackageName()); + when(mSettingsFacade.getString(mMockContext, + Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); + + mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); + + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), + eq(enableUseOpenWifiComponent.getPackageName())); + verify(mSettingsFacade).putString(eq(mMockContext), + eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); + } + private void setRecommendationsEnabledSetting(int value) { when(mSettingsFacade.getInt(eq(mMockContext), eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt())).thenReturn(value);