diff options
6 files changed, 70 insertions, 66 deletions
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl index 73e52c89dcc4..d163a4441097 100644 --- a/core/java/android/net/INetworkScoreService.aidl +++ b/core/java/android/net/INetworkScoreService.aidl @@ -45,7 +45,7 @@ interface INetworkScoreService       * Set the active scorer and clear existing scores.       * @param packageName the package name of the new scorer to use.       * @return true if the operation succeeded, or false if the new package is not a valid scorer. -     * @throws SecurityException if the caller is not the system. +     * @throws SecurityException if the caller is not the system or a network scorer.       */      boolean setActiveScorer(in String packageName); diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index eeb426a4bcf9..9f6e45ca6fb5 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -16,27 +16,20 @@  package android.net; -import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT; - +import android.Manifest.permission;  import android.annotation.IntDef; -import android.annotation.NonNull;  import android.annotation.Nullable;  import android.annotation.SdkConstant;  import android.annotation.SdkConstant.SdkConstantType;  import android.annotation.SystemApi;  import android.content.Context; -import android.os.Bundle; -import android.os.Handler; -import android.os.RemoteCallback;  import android.os.RemoteException;  import android.os.ServiceManager;  import android.os.ServiceManager.ServiceNotFoundException; -import com.android.internal.util.Preconditions;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.util.List; -import java.util.concurrent.CompletableFuture;  /**   * Class that manages communication between network subsystems and a network scorer. @@ -49,9 +42,9 @@ import java.util.concurrent.CompletableFuture;   *   * <p>A network scorer is any application which:   * <ul> - * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission. + * <li>Declares the {@link permission#SCORE_NETWORKS} permission.   * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action - *     protected by the {@link android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE} + *     protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE}   *     permission.   * </ul>   * @@ -319,7 +312,7 @@ public class NetworkScoreManager {       *       * @return true if the operation succeeded, or false if the new package is not a valid scorer.       * @throws SecurityException if the caller is not a system process or does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission +     *         {@link permission#SCORE_NETWORKS} permission       * @hide       */      @SystemApi @@ -351,7 +344,7 @@ public class NetworkScoreManager {       *       * @return true if the broadcast was sent, or false if there is no active scorer.       * @throws SecurityException if the caller does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. +     *         {@link permission#REQUEST_NETWORK_SCORES} permission.       * @hide       */      public boolean requestScores(NetworkKey[] networks) throws SecurityException { @@ -368,7 +361,7 @@ public class NetworkScoreManager {       * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.       * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.       * @throws SecurityException if the caller does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. +     *         {@link permission#REQUEST_NETWORK_SCORES} permission.       * @throws IllegalArgumentException if a score cache is already registered for this type.       * @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE.       * @hide @@ -385,7 +378,7 @@ public class NetworkScoreManager {       * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores       * @param filterType the {@link CacheUpdateFilter} to apply       * @throws SecurityException if the caller does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. +     *         {@link permission#REQUEST_NETWORK_SCORES} permission.       * @throws IllegalArgumentException if a score cache is already registered for this type.       * @hide       */ @@ -404,7 +397,7 @@ public class NetworkScoreManager {       * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.       * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.       * @throws SecurityException if the caller does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. +     *         {@link permission#REQUEST_NETWORK_SCORES} permission.       * @throws IllegalArgumentException if a score cache is already registered for this type.       * @hide       */ @@ -417,25 +410,6 @@ public class NetworkScoreManager {      }      /** -     * Request a recommendation for which network to connect to. -     * -     * <p>It is not safe to call this method from the main thread. -     * -     * @param request a {@link RecommendationRequest} instance containing additional -     *                request details -     * @return a {@link RecommendationResult} instance containing the recommended network -     *         to connect to -     * @throws SecurityException if the caller does not hold the -     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. -     * @hide -     * @deprecated to be removed. -     */ -    public RecommendationResult requestRecommendation(RecommendationRequest request) -            throws SecurityException { -        return null; -    } - -    /**       * Determine whether the application with the given UID is the enabled scorer.       *       * @param callingUid the UID to check diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 114d7619a024..fdc0bba09a52 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -631,6 +631,11 @@ public class NetworkScoreService extends INetworkScoreService.Stub {                   PackageManager.PERMISSION_GRANTED;      } +    private boolean callerCanScoreNetworks() { +        return mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS) == +                PackageManager.PERMISSION_GRANTED; +    } +      @Override      public boolean clearScores() {          // Only the active scorer or the system should be allowed to flush all scores. @@ -651,9 +656,9 @@ public class NetworkScoreService extends INetworkScoreService.Stub {      @Override      public boolean setActiveScorer(String packageName) {          // Only the system can set the active scorer -        if (!isCallerSystemProcess(getCallingUid()) && !callerCanRequestScores()) { +        if (!isCallerSystemProcess(getCallingUid()) && !callerCanScoreNetworks()) {              throw new SecurityException( -                    "Caller is neither the system process nor a score requester."); +                    "Caller is neither the system process or a network scorer.");          }          return mNetworkScorerAppManager.setActiveScorer(packageName); diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java index 8404025e6726..42777bf33bd3 100644 --- a/services/core/java/com/android/server/NetworkScorerAppManager.java +++ b/services/core/java/com/android/server/NetworkScorerAppManager.java @@ -208,11 +208,11 @@ public class NetworkScorerAppManager {       *       * <p>The caller must have permission to write to {@link Settings.Global}.       * -     * @param packageName the packageName of the new scorer to use. If null, the scoring app will -     *                    revert back to the configured default. Otherwise, the scorer will only -     *                    be set if it is a valid scorer application. -     * @return true if the scorer was changed, or false if the package is not a valid scorer or -     *         a valid network recommendation provider exists. +     * @param packageName the packageName of the new scorer to use. If null, scoring will be forced +     *                    off, otherwise the scorer will only be set if it is a valid scorer +     *                    application. +     * @return true if the package was a valid scorer (including <code>null</code>) and now +     *         represents the active scorer, false otherwise.       */      @VisibleForTesting      public boolean setActiveScorer(String packageName) { @@ -223,16 +223,19 @@ public class NetworkScorerAppManager {              return true;          } -        if (packageName == null) { -            // revert to the default setting. -            packageName = getDefaultPackageSetting(); +        if (TextUtils.isEmpty(packageName)) { +            Log.i(TAG, "Network scorer forced off, was: " + oldPackageName); +            setNetworkRecommendationsPackage(null); +            setNetworkRecommendationsEnabledSetting( +                    NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF); +            return true;          } -        Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); -          // We only make the change if the new package is valid.          if (getScorer(packageName) != null) { +            Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName);              setNetworkRecommendationsPackage(packageName); +            setNetworkRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON);              return true;          } else {              Log.w(TAG, "Requested network scorer is not valid: " + packageName); diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index c78488f9d8d9..bb7e20bcb9c3 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -368,8 +368,8 @@ public class NetworkScoreServiceTest {      }      @Test -    public void testSetActiveScorer_noRequestNetworkScoresPermission() { -        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) +    public void testSetActiveScorer_noScoreNetworksPermission() { +        when(mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS))                  .thenReturn(PackageManager.PERMISSION_DENIED);          try { diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java index 0694eaefd288..ceb92dece764 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java @@ -228,30 +228,23 @@ public class NetworkScorerAppManagerTest {      }      @Test -    public void testSetActiveScorer_nullPackage_validDefault() throws Exception { -        String packageName = "package"; -        String defaultPackage = "defaultPackage"; -        setNetworkRecoPackageSetting(packageName); -        setDefaultNetworkRecommendationPackage(defaultPackage); -        final ComponentName recoComponent = new ComponentName(defaultPackage, "class1"); -        mockScoreNetworksGranted(recoComponent.getPackageName()); -        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null); +    public void testSetActiveScorer_nullPackage_currentIsSet() throws Exception { +        setNetworkRecoPackageSetting("package");          assertTrue(mNetworkScorerAppManager.setActiveScorer(null));          verify(mSettingsFacade).putString(mMockContext, -                Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, defaultPackage); +                Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, null); +        verify(mSettingsFacade).putInt(mMockContext, +                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, +                NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF);      }      @Test -    public void testSetActiveScorer_nullPackage_invalidDefault() throws Exception { -        String packageName = "package"; -        String defaultPackage = "defaultPackage"; -        setNetworkRecoPackageSetting(packageName); -        setDefaultNetworkRecommendationPackage(defaultPackage); +    public void testSetActiveScorer_nullPackage_currentIsNull() throws Exception { +        setNetworkRecoPackageSetting(null); -        assertFalse(mNetworkScorerAppManager.setActiveScorer(null)); -        verify(mSettingsFacade, never()).putString(any(), -                eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any()); +        assertTrue(mNetworkScorerAppManager.setActiveScorer(null)); +        verify(mSettingsFacade, never()).putString(any(), any(), any());      }      @Test @@ -266,6 +259,9 @@ public class NetworkScorerAppManagerTest {          assertTrue(mNetworkScorerAppManager.setActiveScorer(newPackage));          verify(mSettingsFacade).putString(mMockContext,                  Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, newPackage); +        verify(mSettingsFacade).putInt(mMockContext, +                Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, +                NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON);      }      @Test @@ -341,6 +337,32 @@ public class NetworkScorerAppManagerTest {      }      @Test +    public void testUpdateState_currentPackageNull_defaultNull() throws Exception { +        setDefaultNetworkRecommendationPackage(null); +        setNetworkRecoPackageSetting(null); + +        mNetworkScorerAppManager.updateState(); + +        verify(mSettingsFacade, never()).putString(any(), +                eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); +        verify(mSettingsFacade, never()).putInt(any(), +                eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt()); +    } + +    @Test +    public void testUpdateState_currentPackageEmpty_defaultEmpty() throws Exception { +        setDefaultNetworkRecommendationPackage(""); +        setNetworkRecoPackageSetting(""); + +        mNetworkScorerAppManager.updateState(); + +        verify(mSettingsFacade, never()).putString(any(), +                eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); +        verify(mSettingsFacade, never()).putInt(any(), +                eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt()); +    } + +    @Test      public void testUpdateState_currentPackageNotValid_sameAsDefault() throws Exception {          String defaultPackage = "defaultPackage";          setDefaultNetworkRecommendationPackage(defaultPackage);  |