Update registerNetworkScoreCache() to accept a filter type.

Defined a new IntDef in NetworkScoreManager named CacheUpdateFilter
with 3 values. Caches must be registered with a filter value and will
only receive updates based on their registered filter. Actual
filtering implementation will follow.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
BUG: 32912120
Change-Id: I8940e0ed1a7bbcb5a81fb3b6a7fafe4fbbc33875
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 542a0a7..24f4504 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -58,12 +58,14 @@
     /**
      * Register a cache to receive scoring updates.
      *
-     * @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 is not the system.
+     * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}
+     * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores
+     * @param filterType the {@link CacheUpdateFilter} to apply
+     * @throws SecurityException if the caller is not the system
+     * @throws IllegalArgumentException if a score cache is already registed for this type
      * @hide
      */
-    void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
+    void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache, int filterType);
 
     /**
      * Unregister a cache to receive scoring updates.
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 236c6fc..865b8dd 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.Manifest;
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
@@ -28,6 +29,9 @@
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.UserHandle;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Class that manages communication between network subsystems and a network scorer.
  *
@@ -131,6 +135,29 @@
      */
     public static final String EXTRA_NEW_SCORER = "newScorer";
 
+    /** @hide */
+    @IntDef({CACHE_FILTER_NONE, CACHE_FILTER_CURRENT_NETWORK, CACHE_FILTER_SCAN_RESULTS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CacheUpdateFilter {}
+
+    /**
+     * Do not filter updates sent to the cache.
+     * @hide
+     */
+    public static final int CACHE_FILTER_NONE = 0;
+
+    /**
+     * Only send cache updates when the network matches the connected network.
+     * @hide
+     */
+    public static final int CACHE_FILTER_CURRENT_NETWORK = 1;
+
+    /**
+     * Only send cache updates when the network is part of the current scan result set.
+     * @hide
+     */
+    public static final int CACHE_FILTER_SCAN_RESULTS = 2;
+
     private final Context mContext;
     private final INetworkScoreService mService;
 
@@ -268,11 +295,29 @@
      * @throws SecurityException if the caller does not hold the
      *         {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} 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
      */
+    @Deprecated // migrate to registerNetworkScoreCache(int, INetworkScoreCache, int)
     public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+        registerNetworkScoreCache(networkType, scoreCache, CACHE_FILTER_NONE);
+    }
+
+    /**
+     * Register a network score cache.
+     *
+     * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}
+     * @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#BROADCAST_NETWORK_PRIVILEGED} permission.
+     * @throws IllegalArgumentException if a score cache is already registered for this type.
+     * @hide
+     */
+    public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache,
+            @CacheUpdateFilter int filterType) {
         try {
-            mService.registerNetworkScoreCache(networkType, scoreCache);
+            mService.registerNetworkScoreCache(networkType, scoreCache, filterType);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 6412e01..27e4aa4 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -425,7 +425,9 @@
     }
 
     @Override
-    public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+    public void registerNetworkScoreCache(int networkType,
+                                          INetworkScoreCache scoreCache,
+                                          int filterType) {
         mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
         synchronized (mScoreCaches) {
             RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
@@ -433,7 +435,7 @@
                 callbackList = new RemoteCallbackList<>();
                 mScoreCaches.put(networkType, callbackList);
             }
-            if (!callbackList.register(scoreCache)) {
+            if (!callbackList.register(scoreCache, filterType)) {
                 if (callbackList.getRegisteredCallbackCount() == 0) {
                     mScoreCaches.remove(networkType);
                 }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 0139671..50911cb 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static android.net.NetworkScoreManager.CACHE_FILTER_NONE;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -26,6 +28,7 @@
 import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -70,6 +73,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 /**
@@ -177,7 +181,8 @@
     public void testUpdateScores_oneRegisteredCache() throws RemoteException {
         when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
 
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
+                mNetworkScoreCache, CACHE_FILTER_NONE);
 
         mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
 
@@ -191,9 +196,10 @@
     public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
         when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
 
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
+                mNetworkScoreCache, CACHE_FILTER_NONE);
         mNetworkScoreService.registerNetworkScoreCache(
-                NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE);
 
         // updateScores should update both caches
         mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
@@ -215,6 +221,9 @@
         // updateScores should not update any caches since they are both unregistered
         mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
 
+        // The register and unregister calls grab the binder from the score cache.
+        verify(mNetworkScoreCache, atLeastOnce()).asBinder();
+        verify(mNetworkScoreCache2, atLeastOnce()).asBinder();
         verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
     }
 
@@ -244,7 +253,8 @@
     public void testClearScores_activeScorer() throws RemoteException {
         when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
 
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
         mNetworkScoreService.clearScores();
 
         verify(mNetworkScoreCache).clearScores();
@@ -257,7 +267,8 @@
         when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
 
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
         mNetworkScoreService.clearScores();
 
         verify(mNetworkScoreCache).clearScores();
@@ -280,7 +291,8 @@
     public void testSetActiveScorer_failure() throws RemoteException {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER);
         when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(false);
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
 
         boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
 
@@ -297,7 +309,8 @@
     public void testSetActiveScorer_success() throws RemoteException {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, NEW_SCORER);
         when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(true);
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
 
         boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
 
@@ -333,7 +346,8 @@
         when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
         when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
 
         mNetworkScoreService.disableScoring();
 
@@ -354,7 +368,8 @@
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
         when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
-        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+        mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
+                CACHE_FILTER_NONE);
 
         mNetworkScoreService.disableScoring();
 
@@ -374,7 +389,7 @@
 
         try {
             mNetworkScoreService.registerNetworkScoreCache(
-                NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+                NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE);
             fail("SecurityException expected");
         } catch (SecurityException e) {
             // expected