diff options
5 files changed, 88 insertions, 14 deletions
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl index 932f03116f15..b097f12d460e 100644 --- a/core/java/android/net/INetworkScoreService.aidl +++ b/core/java/android/net/INetworkScoreService.aidl @@ -100,4 +100,13 @@ interface INetworkScoreService * @hide */ boolean requestScores(in NetworkKey[] networks); + + /** + * Determine whether the application with the given UID is the enabled scorer. + * + * @param callingUid the UID to check + * @return true if the provided UID is the active scorer, false otherwise. + * @hide + */ + boolean isCallerActiveScorer(int callingUid); } diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index 9a6dca013882..af0306e35aaa 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -341,4 +341,19 @@ public class NetworkScoreManager { throw e.rethrowFromSystemServer(); } } + + /** + * Determine whether the application with the given UID is the enabled scorer. + * + * @param callingUid the UID to check + * @return true if the provided UID is the active scorer, false otherwise. + * @hide + */ + public boolean isCallerActiveScorer(int callingUid) { + try { + return mService.isCallerActiveScorer(callingUid); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java index ec0bb25d28eb..23d5af55641c 100644 --- a/core/java/android/net/NetworkScorerAppManager.java +++ b/core/java/android/net/NetworkScorerAppManager.java @@ -16,7 +16,6 @@ package android.net; -import android.Manifest; import android.Manifest.permission; import android.annotation.Nullable; import android.content.ContentResolver; @@ -28,7 +27,9 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; + import com.android.internal.R; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -226,6 +227,7 @@ public class NetworkScorerAppManager { } /** Determine whether the application with the given UID is the enabled scorer. */ + @Deprecated // Use NetworkScoreManager.isCallerActiveScorer() public boolean isCallerActiveScorer(int callingUid) { NetworkScorerAppData defaultApp = getActiveScorer(); if (defaultApp == null) { diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index cef459a3ae39..2f05d0f45399 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -301,7 +301,8 @@ public class NetworkScoreService extends INetworkScoreService.Stub { // If we're not connected at all then create a new connection. if (mServiceConnection == null) { - mServiceConnection = new ScoringServiceConnection(componentName); + mServiceConnection = new ScoringServiceConnection(componentName, + scorerData.packageUid); } // Make sure the connection is connected (idempotent) @@ -325,7 +326,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public boolean updateScores(ScoredNetwork[] networks) { - if (!mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid())) { + if (!isCallerActiveScorer(getCallingUid())) { throw new SecurityException("Caller with UID " + getCallingUid() + " is not the active scorer."); } @@ -389,7 +390,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public boolean clearScores() { // Only the active scorer or the system should be allowed to flush all scores. - if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { + if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { final long token = Binder.clearCallingIdentity(); try { clearInternal(); @@ -418,10 +419,23 @@ public class NetworkScoreService extends INetworkScoreService.Stub { return false; } + /** + * Determine whether the application with the given UID is the enabled scorer. + * + * @param callingUid the UID to check + * @return true if the provided UID is the active scorer, false otherwise. + */ + @Override + public boolean isCallerActiveScorer(int callingUid) { + synchronized (mServiceConnectionLock) { + return mServiceConnection != null && mServiceConnection.mScoringAppUid == callingUid; + } + } + @Override public void disableScoring() { // Only the active scorer or the system should be allowed to disable scoring. - if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { + if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { // no-op for now but we could write to the setting if needed. } else { throw new SecurityException( @@ -623,12 +637,14 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private static class ScoringServiceConnection implements ServiceConnection { private final ComponentName mComponentName; + private final int mScoringAppUid; private volatile boolean mBound = false; private volatile boolean mConnected = false; private volatile INetworkRecommendationProvider mRecommendationProvider; - ScoringServiceConnection(ComponentName componentName) { + ScoringServiceConnection(ComponentName componentName, int scoringAppUid) { mComponentName = componentName; + mScoringAppUid = scoringAppUid; } void connect(Context context) { diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index af570b0dff08..9bb7bd1c5fd6 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -61,6 +61,7 @@ import android.net.RecommendationResult; import android.net.ScoredNetwork; import android.net.WifiKey; import android.net.wifi.WifiConfiguration; +import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IRemoteCallback; @@ -261,7 +262,7 @@ public class NetworkScoreServiceTest { @Test public void testUpdateScores_notActiveScorer() { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); + bindToScorer(false /*callerIsScorer*/); try { mNetworkScoreService.updateScores(new ScoredNetwork[0]); @@ -273,7 +274,7 @@ public class NetworkScoreServiceTest { @Test public void testUpdateScores_oneRegisteredCache() throws RemoteException { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true); + bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE); @@ -288,7 +289,7 @@ public class NetworkScoreServiceTest { @Test public void testUpdateScores_twoRegisteredCaches() throws RemoteException { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true); + bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE); @@ -323,7 +324,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_notActiveScorer_noRequestNetworkScoresPermission() { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); + bindToScorer(false /*callerIsScorer*/); when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); try { @@ -336,7 +337,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_activeScorer_noRequestNetworkScoresPermission() { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true); + bindToScorer(true /*callerIsScorer*/); when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); @@ -345,7 +346,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_activeScorer() throws RemoteException { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true); + bindToScorer(true /*callerIsScorer*/); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE); @@ -357,7 +358,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_notActiveScorer_hasRequestNetworkScoresPermission() throws RemoteException { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); + bindToScorer(false /*callerIsScorer*/); when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_GRANTED); @@ -383,7 +384,7 @@ public class NetworkScoreServiceTest { @Test public void testDisableScoring_notActiveScorer_noRequestNetworkScoresPermission() { - when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); + bindToScorer(false /*callerIsScorer*/); when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); @@ -448,6 +449,27 @@ public class NetworkScoreServiceTest { assertFalse(stringWriter.toString().isEmpty()); } + @Test + public void testIsCallerActiveScorer_noBoundService() throws Exception { + mNetworkScoreService.systemRunning(); + + assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid())); + } + + @Test + public void testIsCallerActiveScorer_boundServiceIsNotCaller() throws Exception { + bindToScorer(false /*callerIsScorer*/); + + assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid())); + } + + @Test + public void testIsCallerActiveScorer_boundServiceIsCaller() throws Exception { + bindToScorer(true /*callerIsScorer*/); + + assertTrue(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid())); + } + // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService. private void injectProvider() { final ComponentName componentName = new ComponentName(NEW_SCORER.packageName, @@ -467,4 +489,14 @@ public class NetworkScoreServiceTest { }); mNetworkScoreService.systemRunning(); } + + private void bindToScorer(boolean callerIsScorer) { + final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0; + NetworkScorerAppData appData = new NetworkScorerAppData(NEW_SCORER.packageName, + callingUid, NEW_SCORER.recommendationServiceClassName); + when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData); + when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(), + isA(UserHandle.class))).thenReturn(true); + mNetworkScoreService.systemRunning(); + } } |