diff options
4 files changed, 36 insertions, 49 deletions
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java index 18259564974a..9a6dca013882 100644 --- a/core/java/android/net/NetworkScoreManager.java +++ b/core/java/android/net/NetworkScoreManager.java @@ -27,7 +27,6 @@ import android.net.NetworkScorerAppManager.NetworkScorerAppData; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -44,19 +43,11 @@ import java.lang.annotation.RetentionPolicy; * <p>A network scorer is any application which: * <ul> * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission. - * <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the - * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission which scores - * networks and (eventually) calls {@link #updateScores} with the results. If this receiver - * specifies an android:label attribute, this label will be used when referring to the - * application throughout system settings; otherwise, the application label will be used. + * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action + * protected by the {@link android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE} + * permission. * </ul> * - * <p>The system keeps track of an active scorer application; at any time, only this application - * will receive {@link #ACTION_SCORE_NETWORKS} broadcasts and will be permitted to call - * {@link #updateScores}. Applications may determine the current active scorer with - * {@link #getActiveScorerPackage()} and request to change the active scorer by sending an - * {@link #ACTION_CHANGE_ACTIVE} broadcast with another scorer. - * * @hide */ @SystemApi @@ -263,12 +254,9 @@ public class NetworkScoreManager { /** * Request scoring for networks. * - * <p>Note that this is just a helper method to assemble the broadcast, and will run in the - * calling process. - * * @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#BROADCAST_NETWORK_PRIVILEGED} permission. + * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. * @hide */ public boolean requestScores(NetworkKey[] networks) throws SecurityException { @@ -285,7 +273,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#BROADCAST_NETWORK_PRIVILEGED} permission. + * {@link android.Manifest.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 @@ -302,7 +290,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#BROADCAST_NETWORK_PRIVILEGED} permission. + * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. * @throws IllegalArgumentException if a score cache is already registered for this type. * @hide */ @@ -321,7 +309,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#BROADCAST_NETWORK_PRIVILEGED} permission. + * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. * @throws IllegalArgumentException if a score cache is already registered for this type. * @hide */ @@ -342,7 +330,8 @@ public class NetworkScoreManager { * request details * @return a {@link RecommendationResult} instance containing the recommended network * to connect to - * @throws SecurityException + * @throws SecurityException if the caller does not hold the + * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission. */ public RecommendationResult requestRecommendation(RecommendationRequest request) throws SecurityException { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a4c616f2c5c2..167a9ad5e625 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1295,9 +1295,8 @@ <!-- A list of potential packages, in priority order, that may contain a network recommendation provider. A network recommendation provider must: * Be granted the SCORE_NETWORKS permission. - * Include a Receiver for the android.net.scoring.SCORE_NETWORKS action guarded by the - BROADCAST_NETWORK_PRIVILEGED permission. - * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action. + * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action + protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission. This may be empty if network scoring and recommending isn't supported. --> diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 983d0392f0bc..cef459a3ae39 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -34,9 +34,9 @@ import android.net.INetworkRecommendationProvider; import android.net.INetworkScoreCache; import android.net.INetworkScoreService; import android.net.NetworkKey; +import android.net.NetworkScoreManager; import android.net.NetworkScorerAppManager; import android.net.NetworkScorerAppManager.NetworkScorerAppData; -import android.net.NetworkScoreManager; import android.net.RecommendationRequest; import android.net.RecommendationResult; import android.net.ScoredNetwork; @@ -380,13 +380,16 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } + private boolean isCallerSystemUid() { + // REQUEST_NETWORK_SCORES is a signature only permission. + return mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES) == + PackageManager.PERMISSION_GRANTED; + } + @Override public boolean clearScores() { - // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED) - // should be allowed to flush all scores. - if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || - mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == - PackageManager.PERMISSION_GRANTED) { + // Only the active scorer or the system should be allowed to flush all scores. + if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { final long token = Binder.clearCallingIdentity(); try { clearInternal(); @@ -409,7 +412,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub { // In the future, should this API be opened to 3p apps, we will need to lock this down and // figure out another way to streamline the UX. - // mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG); mContext.enforceCallingOrSelfPermission(permission.SCORE_NETWORKS, TAG); // Scorers (recommendation providers) are selected and no longer set. @@ -418,11 +420,8 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public void disableScoring() { - // Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED) - // should be allowed to disable scoring. - if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || - mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == - PackageManager.PERMISSION_GRANTED) { + // Only the active scorer or the system should be allowed to disable scoring. + if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) { // no-op for now but we could write to the setting if needed. } else { throw new SecurityException( @@ -450,7 +449,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache, int filterType) { - mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG); + mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG); final long token = Binder.clearCallingIdentity(); try { synchronized (mScoreCaches) { @@ -475,7 +474,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) { - mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG); + mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG); final long token = Binder.clearCallingIdentity(); try { synchronized (mScoreCaches) { @@ -496,7 +495,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public RecommendationResult requestRecommendation(RecommendationRequest request) { - mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG); + mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG); throwIfCalledOnMainThread(); final long token = Binder.clearCallingIdentity(); try { @@ -526,7 +525,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public boolean requestScores(NetworkKey[] networks) { - mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG); + mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG); final long token = Binder.clearCallingIdentity(); try { final INetworkRecommendationProvider provider = getRecommendationProvider(); diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java index 9a9f81e03dfd..9c5c67237fd2 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java @@ -147,11 +147,11 @@ public class NetworkScoreServiceTest { @Test public void testRequestScores_noPermission() throws Exception { doThrow(new SecurityException()).when(mContext) - .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED), + .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES), anyString()); try { mNetworkScoreService.requestScores(null); - fail("BROADCAST_NETWORK_PRIVILEGED not enforced."); + fail("REQUEST_NETWORK_SCORES not enforced."); } catch (SecurityException e) { // expected } @@ -184,11 +184,11 @@ public class NetworkScoreServiceTest { @Test public void testRequestRecommendation_noPermission() throws Exception { doThrow(new SecurityException()).when(mContext) - .enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED), + .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES), anyString()); try { mNetworkScoreService.requestRecommendation(mRecommendationRequest); - fail("BROADCAST_NETWORK_PRIVILEGED not enforced."); + fail("REQUEST_NETWORK_SCORES not enforced."); } catch (SecurityException e) { // expected } @@ -324,7 +324,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() { when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); - when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED)) + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); try { mNetworkScoreService.clearScores(); @@ -337,7 +337,7 @@ public class NetworkScoreServiceTest { @Test public void testClearScores_activeScorer_noBroadcastNetworkPermission() { when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true); - when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED)) + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); mNetworkScoreService.clearScores(); @@ -358,7 +358,7 @@ public class NetworkScoreServiceTest { public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission() throws RemoteException { when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); - when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED)) + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_GRANTED); mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, @@ -384,7 +384,7 @@ public class NetworkScoreServiceTest { @Test public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() { when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false); - when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED)) + when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) .thenReturn(PackageManager.PERMISSION_DENIED); try { @@ -398,7 +398,7 @@ public class NetworkScoreServiceTest { @Test public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() { doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission( - eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString()); + eq(permission.REQUEST_NETWORK_SCORES), anyString()); try { mNetworkScoreService.registerNetworkScoreCache( @@ -412,7 +412,7 @@ public class NetworkScoreServiceTest { @Test public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() { doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission( - eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString()); + eq(permission.REQUEST_NETWORK_SCORES), anyString()); try { mNetworkScoreService.unregisterNetworkScoreCache( |