New internal interface method to get the active scorer metadata.

Returns the cached NetworkScorerAppData from the connected service.

Test: runtest frameworks-services -c com.android.server.NetworkScoreServiceTest
Bug: 34773276
Change-Id: Ia8986e770c4ede0c0f7e2ad4f5bc0a0117a9ae2b
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 5fe8b1a..0ac51b9 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -53,6 +53,7 @@
 import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -676,6 +677,10 @@
         }
     }
 
+    private boolean isCallerSystemProcess(int callingUid) {
+        return callingUid == Process.SYSTEM_UID;
+    }
+
     /**
      * Obtain the package name of the current active network scorer.
      *
@@ -692,6 +697,27 @@
         return null;
     }
 
+
+    /**
+     * Returns metadata about the active scorer or <code>null</code> if there is no active scorer.
+     */
+    @Override
+    public NetworkScorerAppData getActiveScorer() {
+        // Only the system can access this data.
+        if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
+            synchronized (mServiceConnectionLock) {
+                if (mServiceConnection != null) {
+                    return mServiceConnection.mAppData;
+                }
+            }
+        } else {
+            throw new SecurityException(
+                    "Caller is neither the system process nor a score requester.");
+        }
+
+        return null;
+    }
+
     @Override
     public void disableScoring() {
         // Only the active scorer or the system should be allowed to disable scoring.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index fa9e9a8..3a88e9c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -829,6 +829,50 @@
         assertEquals(expectedList, actualList);
     }
 
+    @Test
+    public void testGetActiveScorer_notConnected_canRequestScores() throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        assertNull(mNetworkScoreService.getActiveScorer());
+    }
+
+    @Test
+    public void testGetActiveScorer_notConnected_canNotRequestScores() throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        try {
+            mNetworkScoreService.getActiveScorer();
+            fail("SecurityException expected.");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    @Test
+    public void testGetActiveScorer_connected_canRequestScores()
+            throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        NetworkScorerAppData expectedAppData =
+                new NetworkScorerAppData(Binder.getCallingUid(), RECOMMENDATION_SERVICE_COMP);
+        bindToScorer(expectedAppData);
+        assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
+    }
+
+    @Test
+    public void testGetActiveScorer_connected_canNotRequestScores()
+            throws Exception {
+        when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+                .thenReturn(PackageManager.PERMISSION_DENIED);
+        bindToScorer(false);
+        try {
+            mNetworkScoreService.getActiveScorer();
+            fail("SecurityException expected.");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
     // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
     private void injectProvider() {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
@@ -849,9 +893,13 @@
     }
 
     private void bindToScorer(boolean callerIsScorer) {
-        final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
+        final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1;
         NetworkScorerAppData appData =
                 new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP);
+        bindToScorer(appData);
+    }
+
+    private void bindToScorer(NetworkScorerAppData appData) {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
         when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
                 isA(UserHandle.class))).thenReturn(true);