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);