Merge "Check for REQUEST_NETWORK_SCORES instead of BROADCAST_NETWORK_PRIVILEGED."
This commit is contained in:
@@ -27,7 +27,6 @@ import android.net.NetworkScorerAppManager.NetworkScorerAppData;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.UserHandle;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -44,19 +43,11 @@ import java.lang.annotation.RetentionPolicy;
|
|||||||
* <p>A network scorer is any application which:
|
* <p>A network scorer is any application which:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
|
* <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
|
||||||
* <li>Includes a receiver for {@link #ACTION_SCORE_NETWORKS} guarded by the
|
* <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action
|
||||||
* {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission which scores
|
* protected by the {@link android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE}
|
||||||
* networks and (eventually) calls {@link #updateScores} with the results. If this receiver
|
* permission.
|
||||||
* 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.
|
|
||||||
* </ul>
|
* </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
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
@@ -263,12 +254,9 @@ public class NetworkScoreManager {
|
|||||||
/**
|
/**
|
||||||
* Request scoring for networks.
|
* 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.
|
* @return true if the broadcast was sent, or false if there is no active scorer.
|
||||||
* @throws SecurityException if the caller does not hold the
|
* @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
|
* @hide
|
||||||
*/
|
*/
|
||||||
public boolean requestScores(NetworkKey[] networks) throws SecurityException {
|
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 networkType the type of network this cache can handle. See {@link NetworkKey#type}.
|
||||||
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
|
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
|
||||||
* @throws SecurityException if the caller does not hold the
|
* @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.
|
* @throws IllegalArgumentException if a score cache is already registered for this type.
|
||||||
* @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE.
|
* @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE.
|
||||||
* @hide
|
* @hide
|
||||||
@@ -302,7 +290,7 @@ public class NetworkScoreManager {
|
|||||||
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores
|
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores
|
||||||
* @param filterType the {@link CacheUpdateFilter} to apply
|
* @param filterType the {@link CacheUpdateFilter} to apply
|
||||||
* @throws SecurityException if the caller does not hold the
|
* @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.
|
* @throws IllegalArgumentException if a score cache is already registered for this type.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -321,7 +309,7 @@ public class NetworkScoreManager {
|
|||||||
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
|
* @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 scoreCache implementation of {@link INetworkScoreCache} to store the scores.
|
||||||
* @throws SecurityException if the caller does not hold the
|
* @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.
|
* @throws IllegalArgumentException if a score cache is already registered for this type.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -342,7 +330,8 @@ public class NetworkScoreManager {
|
|||||||
* request details
|
* request details
|
||||||
* @return a {@link RecommendationResult} instance containing the recommended network
|
* @return a {@link RecommendationResult} instance containing the recommended network
|
||||||
* to connect to
|
* 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)
|
public RecommendationResult requestRecommendation(RecommendationRequest request)
|
||||||
throws SecurityException {
|
throws SecurityException {
|
||||||
|
|||||||
@@ -1280,9 +1280,8 @@
|
|||||||
<!-- A list of potential packages, in priority order, that may contain a
|
<!-- A list of potential packages, in priority order, that may contain a
|
||||||
network recommendation provider. A network recommendation provider must:
|
network recommendation provider. A network recommendation provider must:
|
||||||
* Be granted the SCORE_NETWORKS permission.
|
* Be granted the SCORE_NETWORKS permission.
|
||||||
* Include a Receiver for the android.net.scoring.SCORE_NETWORKS action guarded by the
|
* Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action
|
||||||
BROADCAST_NETWORK_PRIVILEGED permission.
|
protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission.
|
||||||
* Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action.
|
|
||||||
|
|
||||||
This may be empty if network scoring and recommending isn't supported.
|
This may be empty if network scoring and recommending isn't supported.
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ import android.net.INetworkRecommendationProvider;
|
|||||||
import android.net.INetworkScoreCache;
|
import android.net.INetworkScoreCache;
|
||||||
import android.net.INetworkScoreService;
|
import android.net.INetworkScoreService;
|
||||||
import android.net.NetworkKey;
|
import android.net.NetworkKey;
|
||||||
|
import android.net.NetworkScoreManager;
|
||||||
import android.net.NetworkScorerAppManager;
|
import android.net.NetworkScorerAppManager;
|
||||||
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
|
import android.net.NetworkScorerAppManager.NetworkScorerAppData;
|
||||||
import android.net.NetworkScoreManager;
|
|
||||||
import android.net.RecommendationRequest;
|
import android.net.RecommendationRequest;
|
||||||
import android.net.RecommendationResult;
|
import android.net.RecommendationResult;
|
||||||
import android.net.ScoredNetwork;
|
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
|
@Override
|
||||||
public boolean clearScores() {
|
public boolean clearScores() {
|
||||||
// Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
|
// Only the active scorer or the system should be allowed to flush all scores.
|
||||||
// should be allowed to flush all scores.
|
if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
|
||||||
if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
|
|
||||||
mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
|
|
||||||
PackageManager.PERMISSION_GRANTED) {
|
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
clearInternal();
|
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
|
// 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.
|
// figure out another way to streamline the UX.
|
||||||
|
|
||||||
// mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
|
|
||||||
mContext.enforceCallingOrSelfPermission(permission.SCORE_NETWORKS, TAG);
|
mContext.enforceCallingOrSelfPermission(permission.SCORE_NETWORKS, TAG);
|
||||||
|
|
||||||
// Scorers (recommendation providers) are selected and no longer set.
|
// Scorers (recommendation providers) are selected and no longer set.
|
||||||
@@ -418,11 +420,8 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disableScoring() {
|
public void disableScoring() {
|
||||||
// Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
|
// Only the active scorer or the system should be allowed to disable scoring.
|
||||||
// should be allowed to disable scoring.
|
if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
|
||||||
if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
|
|
||||||
mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
|
|
||||||
PackageManager.PERMISSION_GRANTED) {
|
|
||||||
// no-op for now but we could write to the setting if needed.
|
// no-op for now but we could write to the setting if needed.
|
||||||
} else {
|
} else {
|
||||||
throw new SecurityException(
|
throw new SecurityException(
|
||||||
@@ -450,7 +449,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
|||||||
public void registerNetworkScoreCache(int networkType,
|
public void registerNetworkScoreCache(int networkType,
|
||||||
INetworkScoreCache scoreCache,
|
INetworkScoreCache scoreCache,
|
||||||
int filterType) {
|
int filterType) {
|
||||||
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
|
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
synchronized (mScoreCaches) {
|
synchronized (mScoreCaches) {
|
||||||
@@ -475,7 +474,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
|
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();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
synchronized (mScoreCaches) {
|
synchronized (mScoreCaches) {
|
||||||
@@ -496,7 +495,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RecommendationResult requestRecommendation(RecommendationRequest request) {
|
public RecommendationResult requestRecommendation(RecommendationRequest request) {
|
||||||
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
|
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||||
throwIfCalledOnMainThread();
|
throwIfCalledOnMainThread();
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
@@ -526,7 +525,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean requestScores(NetworkKey[] networks) {
|
public boolean requestScores(NetworkKey[] networks) {
|
||||||
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
|
mContext.enforceCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES, TAG);
|
||||||
final long token = Binder.clearCallingIdentity();
|
final long token = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
final INetworkRecommendationProvider provider = getRecommendationProvider();
|
final INetworkRecommendationProvider provider = getRecommendationProvider();
|
||||||
|
|||||||
@@ -147,11 +147,11 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRequestScores_noPermission() throws Exception {
|
public void testRequestScores_noPermission() throws Exception {
|
||||||
doThrow(new SecurityException()).when(mContext)
|
doThrow(new SecurityException()).when(mContext)
|
||||||
.enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
|
.enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
|
||||||
anyString());
|
anyString());
|
||||||
try {
|
try {
|
||||||
mNetworkScoreService.requestScores(null);
|
mNetworkScoreService.requestScores(null);
|
||||||
fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
|
fail("REQUEST_NETWORK_SCORES not enforced.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
@@ -184,11 +184,11 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRequestRecommendation_noPermission() throws Exception {
|
public void testRequestRecommendation_noPermission() throws Exception {
|
||||||
doThrow(new SecurityException()).when(mContext)
|
doThrow(new SecurityException()).when(mContext)
|
||||||
.enforceCallingOrSelfPermission(eq(permission.BROADCAST_NETWORK_PRIVILEGED),
|
.enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES),
|
||||||
anyString());
|
anyString());
|
||||||
try {
|
try {
|
||||||
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
mNetworkScoreService.requestRecommendation(mRecommendationRequest);
|
||||||
fail("BROADCAST_NETWORK_PRIVILEGED not enforced.");
|
fail("REQUEST_NETWORK_SCORES not enforced.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
|
public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
|
||||||
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
||||||
when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
|
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||||
.thenReturn(PackageManager.PERMISSION_DENIED);
|
.thenReturn(PackageManager.PERMISSION_DENIED);
|
||||||
try {
|
try {
|
||||||
mNetworkScoreService.clearScores();
|
mNetworkScoreService.clearScores();
|
||||||
@@ -337,7 +337,7 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
|
public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
|
||||||
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
|
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
|
||||||
when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
|
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||||
.thenReturn(PackageManager.PERMISSION_DENIED);
|
.thenReturn(PackageManager.PERMISSION_DENIED);
|
||||||
|
|
||||||
mNetworkScoreService.clearScores();
|
mNetworkScoreService.clearScores();
|
||||||
@@ -358,7 +358,7 @@ public class NetworkScoreServiceTest {
|
|||||||
public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
|
public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
||||||
when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
|
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||||
.thenReturn(PackageManager.PERMISSION_GRANTED);
|
.thenReturn(PackageManager.PERMISSION_GRANTED);
|
||||||
|
|
||||||
mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
|
mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache,
|
||||||
@@ -384,7 +384,7 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
|
public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
|
||||||
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
|
||||||
when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
|
when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
|
||||||
.thenReturn(PackageManager.PERMISSION_DENIED);
|
.thenReturn(PackageManager.PERMISSION_DENIED);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -398,7 +398,7 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
|
public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
|
||||||
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
|
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
|
||||||
eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
|
eq(permission.REQUEST_NETWORK_SCORES), anyString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mNetworkScoreService.registerNetworkScoreCache(
|
mNetworkScoreService.registerNetworkScoreCache(
|
||||||
@@ -412,7 +412,7 @@ public class NetworkScoreServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
|
public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
|
||||||
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
|
doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
|
||||||
eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
|
eq(permission.REQUEST_NETWORK_SCORES), anyString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mNetworkScoreService.unregisterNetworkScoreCache(
|
mNetworkScoreService.unregisterNetworkScoreCache(
|
||||||
|
|||||||
Reference in New Issue
Block a user