Loading core/java/android/net/NetworkScoreManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -144,7 +144,7 @@ public class NetworkScoreManager { * scorer. * scorer. */ */ public String getActiveScorerPackage() { public String getActiveScorerPackage() { NetworkScorerAppData app = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData app = new NetworkScorerAppManager(mContext).getActiveScorer(); if (app == null) { if (app == null) { return null; return null; } } Loading core/java/android/net/NetworkScorerAppManager.java +21 −19 Original line number Original line Diff line number Diff line Loading @@ -41,14 +41,17 @@ import java.util.List; * * * @hide * @hide */ */ public final class NetworkScorerAppManager { public class NetworkScorerAppManager { private static final String TAG = "NetworkScorerAppManager"; private static final String TAG = "NetworkScorerAppManager"; private static final Intent SCORE_INTENT = private static final Intent SCORE_INTENT = new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); /** This class cannot be instantiated. */ private final Context mContext; private NetworkScorerAppManager() {} public NetworkScorerAppManager(Context context) { mContext = context; } public static class NetworkScorerAppData { public static class NetworkScorerAppData { /** Package name of this scorer app. */ /** Package name of this scorer app. */ Loading Loading @@ -108,7 +111,7 @@ public final class NetworkScorerAppManager { * * * @return the list of scorers, or the empty list if there are no valid scorers. * @return the list of scorers, or the empty list if there are no valid scorers. */ */ public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) { public Collection<NetworkScorerAppData> getAllValidScorers() { // Network scorer apps can only run as the primary user so exit early if we're not the // Network scorer apps can only run as the primary user so exit early if we're not the // primary user. // primary user. if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) { if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) { Loading @@ -116,7 +119,7 @@ public final class NetworkScorerAppManager { } } List<NetworkScorerAppData> scorers = new ArrayList<>(); List<NetworkScorerAppData> scorers = new ArrayList<>(); PackageManager pm = context.getPackageManager(); PackageManager pm = mContext.getPackageManager(); // Only apps installed under the primary user of the device can be scorers. // Only apps installed under the primary user of the device can be scorers. // TODO: http://b/23422763 // TODO: http://b/23422763 List<ResolveInfo> receivers = List<ResolveInfo> receivers = Loading Loading @@ -179,10 +182,10 @@ public final class NetworkScorerAppManager { * selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because * selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because * it was disabled or uninstalled). * it was disabled or uninstalled). */ */ public static NetworkScorerAppData getActiveScorer(Context context) { public NetworkScorerAppData getActiveScorer() { String scorerPackage = Settings.Global.getString(context.getContentResolver(), String scorerPackage = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); Settings.Global.NETWORK_SCORER_APP); return getScorer(context, scorerPackage); return getScorer(scorerPackage); } } /** /** Loading @@ -190,13 +193,12 @@ public final class NetworkScorerAppManager { * * * <p>The caller must have permission to write to {@link android.provider.Settings.Global}. * <p>The caller must have permission to write to {@link android.provider.Settings.Global}. * * * @param context the context of the calling application * @param packageName the packageName of the new scorer to use. If null, scoring will be * @param packageName the packageName of the new scorer to use. If null, scoring will be * disabled. Otherwise, the scorer will only be set if it is a valid scorer application. * disabled. Otherwise, the scorer will only be set if it is a valid scorer application. * @return true if the scorer was changed, or false if the package is not a valid scorer. * @return true if the scorer was changed, or false if the package is not a valid scorer. */ */ public static boolean setActiveScorer(Context context, String packageName) { public boolean setActiveScorer(String packageName) { String oldPackageName = Settings.Global.getString(context.getContentResolver(), String oldPackageName = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); Settings.Global.NETWORK_SCORER_APP); if (TextUtils.equals(oldPackageName, packageName)) { if (TextUtils.equals(oldPackageName, packageName)) { // No change. // No change. Loading @@ -206,13 +208,13 @@ public final class NetworkScorerAppManager { Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); if (packageName == null) { if (packageName == null) { Settings.Global.putString(context.getContentResolver(), Settings.Global.putString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, null); Settings.Global.NETWORK_SCORER_APP, null); return true; return true; } else { } else { // We only make the change if the new package is valid. // We only make the change if the new package is valid. if (getScorer(context, packageName) != null) { if (getScorer(packageName) != null) { Settings.Global.putString(context.getContentResolver(), Settings.Global.putString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, packageName); Settings.Global.NETWORK_SCORER_APP, packageName); return true; return true; } else { } else { Loading @@ -223,8 +225,8 @@ public final class NetworkScorerAppManager { } } /** Determine whether the application with the given UID is the enabled scorer. */ /** Determine whether the application with the given UID is the enabled scorer. */ public static boolean isCallerActiveScorer(Context context, int callingUid) { public boolean isCallerActiveScorer(int callingUid) { NetworkScorerAppData defaultApp = getActiveScorer(context); NetworkScorerAppData defaultApp = getActiveScorer(); if (defaultApp == null) { if (defaultApp == null) { return false; return false; } } Loading @@ -233,16 +235,16 @@ public final class NetworkScorerAppManager { } } // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always // should, since it couldn't become the active scorer otherwise, but this can't hurt. // should, since it couldn't become the active scorer otherwise, but this can't hurt. return context.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == return mContext.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == PackageManager.PERMISSION_GRANTED; PackageManager.PERMISSION_GRANTED; } } /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */ /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */ public static NetworkScorerAppData getScorer(Context context, String packageName) { public NetworkScorerAppData getScorer(String packageName) { if (TextUtils.isEmpty(packageName)) { if (TextUtils.isEmpty(packageName)) { return null; return null; } } Collection<NetworkScorerAppData> applications = getAllValidScorers(context); Collection<NetworkScorerAppData> applications = getAllValidScorers(); for (NetworkScorerAppData app : applications) { for (NetworkScorerAppData app : applications) { if (packageName.equals(app.mPackageName)) { if (packageName.equals(app.mPackageName)) { return app; return app; Loading core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { @Mock private Context mMockContext; @Mock private Context mMockContext; @Mock private PackageManager mMockPm; @Mock private PackageManager mMockPm; private NetworkScorerAppManager mNetworkScorerAppManager; @Override @Override public void setUp() throws Exception { public void setUp() throws Exception { super.setUp(); super.setUp(); Loading @@ -54,6 +56,7 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this); Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm); Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm); mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext); } } public void testGetAllValidScorers() throws Exception { public void testGetAllValidScorers() throws Exception { Loading Loading @@ -81,7 +84,7 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { setScorers(scorers); setScorers(scorers); Iterator<NetworkScorerAppData> result = Iterator<NetworkScorerAppData> result = NetworkScorerAppManager.getAllValidScorers(mMockContext).iterator(); mNetworkScorerAppManager.getAllValidScorers().iterator(); assertTrue(result.hasNext()); assertTrue(result.hasNext()); NetworkScorerAppData next = result.next(); NetworkScorerAppData next = result.next(); Loading services/core/java/com/android/server/NetworkScoreService.java +18 −10 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.util.Log; import com.android.internal.R; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.content.PackageMonitor; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading @@ -61,6 +62,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private static final boolean DBG = false; private static final boolean DBG = false; private final Context mContext; private final Context mContext; private final NetworkScorerAppManager mNetworkScorerAppManager; private final Map<Integer, INetworkScoreCache> mScoreCaches; private final Map<Integer, INetworkScoreCache> mScoreCaches; /** Lock used to update mPackageMonitor when scorer package changes occur. */ /** Lock used to update mPackageMonitor when scorer package changes occur. */ private final Object mPackageMonitorLock = new Object[0]; private final Object mPackageMonitorLock = new Object[0]; Loading Loading @@ -131,7 +133,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { + ", forceUnbind=" + forceUnbind); + ", forceUnbind=" + forceUnbind); } } final NetworkScorerAppData activeScorer = final NetworkScorerAppData activeScorer = NetworkScorerAppManager.getActiveScorer(mContext); mNetworkScorerAppManager.getActiveScorer(); if (activeScorer == null) { if (activeScorer == null) { // Package change has invalidated a scorer, this will also unbind any service // Package change has invalidated a scorer, this will also unbind any service // connection. // connection. Loading @@ -152,7 +154,13 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } public NetworkScoreService(Context context) { public NetworkScoreService(Context context) { this(context, new NetworkScorerAppManager(context)); } @VisibleForTesting NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager) { mContext = context; mContext = context; mNetworkScorerAppManager = networkScoreAppManager; mScoreCaches = new HashMap<>(); mScoreCaches = new HashMap<>(); IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); // TODO: Need to update when we support per-user scorers. http://b/23422763 // TODO: Need to update when we support per-user scorers. http://b/23422763 Loading @@ -171,7 +179,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { String defaultPackage = mContext.getResources().getString( String defaultPackage = mContext.getResources().getString( R.string.config_defaultNetworkScorerPackageName); R.string.config_defaultNetworkScorerPackageName); if (!TextUtils.isEmpty(defaultPackage)) { if (!TextUtils.isEmpty(defaultPackage)) { NetworkScorerAppManager.setActiveScorer(mContext, defaultPackage); mNetworkScorerAppManager.setActiveScorer(defaultPackage); } } Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1); Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1); } } Loading @@ -192,7 +200,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private void registerPackageMonitorIfNeeded() { private void registerPackageMonitorIfNeeded() { if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded"); if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded"); NetworkScorerAppData scorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData scorer = mNetworkScorerAppManager.getActiveScorer(); synchronized (mPackageMonitorLock) { synchronized (mPackageMonitorLock) { // Unregister the current monitor if needed. // Unregister the current monitor if needed. if (mPackageMonitor != null) { if (mPackageMonitor != null) { Loading Loading @@ -220,7 +228,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private void bindToScoringServiceIfNeeded() { private void bindToScoringServiceIfNeeded() { if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded"); if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded"); NetworkScorerAppData scorerData = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData scorerData = mNetworkScorerAppManager.getActiveScorer(); bindToScoringServiceIfNeeded(scorerData); bindToScoringServiceIfNeeded(scorerData); } } Loading Loading @@ -257,7 +265,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override @Override public boolean updateScores(ScoredNetwork[] networks) { public boolean updateScores(ScoredNetwork[] networks) { if (!NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid())) { if (!mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid())) { throw new SecurityException("Caller with UID " + getCallingUid() + throw new SecurityException("Caller with UID " + getCallingUid() + " is not the active scorer."); " is not the active scorer."); } } Loading Loading @@ -296,7 +304,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { 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 (who can broadcast BROADCAST_NETWORK_PRIVILEGED) // should be allowed to flush all scores. // should be allowed to flush all scores. if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) || if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == PackageManager.PERMISSION_GRANTED) { PackageManager.PERMISSION_GRANTED) { clearInternal(); clearInternal(); Loading Loading @@ -326,7 +334,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { 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 (who can broadcast BROADCAST_NETWORK_PRIVILEGED) // should be allowed to disable scoring. // should be allowed to disable scoring. if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) || if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == PackageManager.PERMISSION_GRANTED) { PackageManager.PERMISSION_GRANTED) { // The return value is discarded here because at this point, the call should always // The return value is discarded here because at this point, the call should always Loading @@ -350,8 +358,8 @@ public class NetworkScoreService extends INetworkScoreService.Stub { // only be allowing valid apps to be set as scorers, so failure here should be rare. // only be allowing valid apps to be set as scorers, so failure here should be rare. clearInternal(); clearInternal(); // Get the scorer that is about to be replaced, if any, so we can notify it directly. // Get the scorer that is about to be replaced, if any, so we can notify it directly. NetworkScorerAppData prevScorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData prevScorer = mNetworkScorerAppManager.getActiveScorer(); boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName); boolean result = mNetworkScorerAppManager.setActiveScorer(packageName); // Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed // Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed // then we'll attempt to restore the previous binding (if any), otherwise an attempt // then we'll attempt to restore the previous binding (if any), otherwise an attempt // will be made to bind to the new scorer. // will be made to bind to the new scorer. Loading Loading @@ -409,7 +417,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); NetworkScorerAppData currentScorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer(); if (currentScorer == null) { if (currentScorer == null) { writer.println("Scoring is disabled."); writer.println("Scoring is disabled."); return; return; Loading Loading
core/java/android/net/NetworkScoreManager.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -144,7 +144,7 @@ public class NetworkScoreManager { * scorer. * scorer. */ */ public String getActiveScorerPackage() { public String getActiveScorerPackage() { NetworkScorerAppData app = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData app = new NetworkScorerAppManager(mContext).getActiveScorer(); if (app == null) { if (app == null) { return null; return null; } } Loading
core/java/android/net/NetworkScorerAppManager.java +21 −19 Original line number Original line Diff line number Diff line Loading @@ -41,14 +41,17 @@ import java.util.List; * * * @hide * @hide */ */ public final class NetworkScorerAppManager { public class NetworkScorerAppManager { private static final String TAG = "NetworkScorerAppManager"; private static final String TAG = "NetworkScorerAppManager"; private static final Intent SCORE_INTENT = private static final Intent SCORE_INTENT = new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); /** This class cannot be instantiated. */ private final Context mContext; private NetworkScorerAppManager() {} public NetworkScorerAppManager(Context context) { mContext = context; } public static class NetworkScorerAppData { public static class NetworkScorerAppData { /** Package name of this scorer app. */ /** Package name of this scorer app. */ Loading Loading @@ -108,7 +111,7 @@ public final class NetworkScorerAppManager { * * * @return the list of scorers, or the empty list if there are no valid scorers. * @return the list of scorers, or the empty list if there are no valid scorers. */ */ public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) { public Collection<NetworkScorerAppData> getAllValidScorers() { // Network scorer apps can only run as the primary user so exit early if we're not the // Network scorer apps can only run as the primary user so exit early if we're not the // primary user. // primary user. if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) { if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) { Loading @@ -116,7 +119,7 @@ public final class NetworkScorerAppManager { } } List<NetworkScorerAppData> scorers = new ArrayList<>(); List<NetworkScorerAppData> scorers = new ArrayList<>(); PackageManager pm = context.getPackageManager(); PackageManager pm = mContext.getPackageManager(); // Only apps installed under the primary user of the device can be scorers. // Only apps installed under the primary user of the device can be scorers. // TODO: http://b/23422763 // TODO: http://b/23422763 List<ResolveInfo> receivers = List<ResolveInfo> receivers = Loading Loading @@ -179,10 +182,10 @@ public final class NetworkScorerAppManager { * selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because * selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because * it was disabled or uninstalled). * it was disabled or uninstalled). */ */ public static NetworkScorerAppData getActiveScorer(Context context) { public NetworkScorerAppData getActiveScorer() { String scorerPackage = Settings.Global.getString(context.getContentResolver(), String scorerPackage = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); Settings.Global.NETWORK_SCORER_APP); return getScorer(context, scorerPackage); return getScorer(scorerPackage); } } /** /** Loading @@ -190,13 +193,12 @@ public final class NetworkScorerAppManager { * * * <p>The caller must have permission to write to {@link android.provider.Settings.Global}. * <p>The caller must have permission to write to {@link android.provider.Settings.Global}. * * * @param context the context of the calling application * @param packageName the packageName of the new scorer to use. If null, scoring will be * @param packageName the packageName of the new scorer to use. If null, scoring will be * disabled. Otherwise, the scorer will only be set if it is a valid scorer application. * disabled. Otherwise, the scorer will only be set if it is a valid scorer application. * @return true if the scorer was changed, or false if the package is not a valid scorer. * @return true if the scorer was changed, or false if the package is not a valid scorer. */ */ public static boolean setActiveScorer(Context context, String packageName) { public boolean setActiveScorer(String packageName) { String oldPackageName = Settings.Global.getString(context.getContentResolver(), String oldPackageName = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); Settings.Global.NETWORK_SCORER_APP); if (TextUtils.equals(oldPackageName, packageName)) { if (TextUtils.equals(oldPackageName, packageName)) { // No change. // No change. Loading @@ -206,13 +208,13 @@ public final class NetworkScorerAppManager { Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); if (packageName == null) { if (packageName == null) { Settings.Global.putString(context.getContentResolver(), Settings.Global.putString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, null); Settings.Global.NETWORK_SCORER_APP, null); return true; return true; } else { } else { // We only make the change if the new package is valid. // We only make the change if the new package is valid. if (getScorer(context, packageName) != null) { if (getScorer(packageName) != null) { Settings.Global.putString(context.getContentResolver(), Settings.Global.putString(mContext.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, packageName); Settings.Global.NETWORK_SCORER_APP, packageName); return true; return true; } else { } else { Loading @@ -223,8 +225,8 @@ public final class NetworkScorerAppManager { } } /** Determine whether the application with the given UID is the enabled scorer. */ /** Determine whether the application with the given UID is the enabled scorer. */ public static boolean isCallerActiveScorer(Context context, int callingUid) { public boolean isCallerActiveScorer(int callingUid) { NetworkScorerAppData defaultApp = getActiveScorer(context); NetworkScorerAppData defaultApp = getActiveScorer(); if (defaultApp == null) { if (defaultApp == null) { return false; return false; } } Loading @@ -233,16 +235,16 @@ public final class NetworkScorerAppManager { } } // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always // To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always // should, since it couldn't become the active scorer otherwise, but this can't hurt. // should, since it couldn't become the active scorer otherwise, but this can't hurt. return context.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == return mContext.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) == PackageManager.PERMISSION_GRANTED; PackageManager.PERMISSION_GRANTED; } } /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */ /** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */ public static NetworkScorerAppData getScorer(Context context, String packageName) { public NetworkScorerAppData getScorer(String packageName) { if (TextUtils.isEmpty(packageName)) { if (TextUtils.isEmpty(packageName)) { return null; return null; } } Collection<NetworkScorerAppData> applications = getAllValidScorers(context); Collection<NetworkScorerAppData> applications = getAllValidScorers(); for (NetworkScorerAppData app : applications) { for (NetworkScorerAppData app : applications) { if (packageName.equals(app.mPackageName)) { if (packageName.equals(app.mPackageName)) { return app; return app; Loading
core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -42,6 +42,8 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { @Mock private Context mMockContext; @Mock private Context mMockContext; @Mock private PackageManager mMockPm; @Mock private PackageManager mMockPm; private NetworkScorerAppManager mNetworkScorerAppManager; @Override @Override public void setUp() throws Exception { public void setUp() throws Exception { super.setUp(); super.setUp(); Loading @@ -54,6 +56,7 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this); Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm); Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm); mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext); } } public void testGetAllValidScorers() throws Exception { public void testGetAllValidScorers() throws Exception { Loading Loading @@ -81,7 +84,7 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { setScorers(scorers); setScorers(scorers); Iterator<NetworkScorerAppData> result = Iterator<NetworkScorerAppData> result = NetworkScorerAppManager.getAllValidScorers(mMockContext).iterator(); mNetworkScorerAppManager.getAllValidScorers().iterator(); assertTrue(result.hasNext()); assertTrue(result.hasNext()); NetworkScorerAppData next = result.next(); NetworkScorerAppData next = result.next(); Loading
services/core/java/com/android/server/NetworkScoreService.java +18 −10 Original line number Original line Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.util.Log; import com.android.internal.R; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.content.PackageMonitor; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading @@ -61,6 +62,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private static final boolean DBG = false; private static final boolean DBG = false; private final Context mContext; private final Context mContext; private final NetworkScorerAppManager mNetworkScorerAppManager; private final Map<Integer, INetworkScoreCache> mScoreCaches; private final Map<Integer, INetworkScoreCache> mScoreCaches; /** Lock used to update mPackageMonitor when scorer package changes occur. */ /** Lock used to update mPackageMonitor when scorer package changes occur. */ private final Object mPackageMonitorLock = new Object[0]; private final Object mPackageMonitorLock = new Object[0]; Loading Loading @@ -131,7 +133,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { + ", forceUnbind=" + forceUnbind); + ", forceUnbind=" + forceUnbind); } } final NetworkScorerAppData activeScorer = final NetworkScorerAppData activeScorer = NetworkScorerAppManager.getActiveScorer(mContext); mNetworkScorerAppManager.getActiveScorer(); if (activeScorer == null) { if (activeScorer == null) { // Package change has invalidated a scorer, this will also unbind any service // Package change has invalidated a scorer, this will also unbind any service // connection. // connection. Loading @@ -152,7 +154,13 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } public NetworkScoreService(Context context) { public NetworkScoreService(Context context) { this(context, new NetworkScorerAppManager(context)); } @VisibleForTesting NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager) { mContext = context; mContext = context; mNetworkScorerAppManager = networkScoreAppManager; mScoreCaches = new HashMap<>(); mScoreCaches = new HashMap<>(); IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED); // TODO: Need to update when we support per-user scorers. http://b/23422763 // TODO: Need to update when we support per-user scorers. http://b/23422763 Loading @@ -171,7 +179,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { String defaultPackage = mContext.getResources().getString( String defaultPackage = mContext.getResources().getString( R.string.config_defaultNetworkScorerPackageName); R.string.config_defaultNetworkScorerPackageName); if (!TextUtils.isEmpty(defaultPackage)) { if (!TextUtils.isEmpty(defaultPackage)) { NetworkScorerAppManager.setActiveScorer(mContext, defaultPackage); mNetworkScorerAppManager.setActiveScorer(defaultPackage); } } Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1); Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1); } } Loading @@ -192,7 +200,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private void registerPackageMonitorIfNeeded() { private void registerPackageMonitorIfNeeded() { if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded"); if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded"); NetworkScorerAppData scorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData scorer = mNetworkScorerAppManager.getActiveScorer(); synchronized (mPackageMonitorLock) { synchronized (mPackageMonitorLock) { // Unregister the current monitor if needed. // Unregister the current monitor if needed. if (mPackageMonitor != null) { if (mPackageMonitor != null) { Loading Loading @@ -220,7 +228,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { private void bindToScoringServiceIfNeeded() { private void bindToScoringServiceIfNeeded() { if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded"); if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded"); NetworkScorerAppData scorerData = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData scorerData = mNetworkScorerAppManager.getActiveScorer(); bindToScoringServiceIfNeeded(scorerData); bindToScoringServiceIfNeeded(scorerData); } } Loading Loading @@ -257,7 +265,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override @Override public boolean updateScores(ScoredNetwork[] networks) { public boolean updateScores(ScoredNetwork[] networks) { if (!NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid())) { if (!mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid())) { throw new SecurityException("Caller with UID " + getCallingUid() + throw new SecurityException("Caller with UID " + getCallingUid() + " is not the active scorer."); " is not the active scorer."); } } Loading Loading @@ -296,7 +304,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { 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 (who can broadcast BROADCAST_NETWORK_PRIVILEGED) // should be allowed to flush all scores. // should be allowed to flush all scores. if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) || if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == PackageManager.PERMISSION_GRANTED) { PackageManager.PERMISSION_GRANTED) { clearInternal(); clearInternal(); Loading Loading @@ -326,7 +334,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { 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 (who can broadcast BROADCAST_NETWORK_PRIVILEGED) // should be allowed to disable scoring. // should be allowed to disable scoring. if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) || if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) || mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) == PackageManager.PERMISSION_GRANTED) { PackageManager.PERMISSION_GRANTED) { // The return value is discarded here because at this point, the call should always // The return value is discarded here because at this point, the call should always Loading @@ -350,8 +358,8 @@ public class NetworkScoreService extends INetworkScoreService.Stub { // only be allowing valid apps to be set as scorers, so failure here should be rare. // only be allowing valid apps to be set as scorers, so failure here should be rare. clearInternal(); clearInternal(); // Get the scorer that is about to be replaced, if any, so we can notify it directly. // Get the scorer that is about to be replaced, if any, so we can notify it directly. NetworkScorerAppData prevScorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData prevScorer = mNetworkScorerAppManager.getActiveScorer(); boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName); boolean result = mNetworkScorerAppManager.setActiveScorer(packageName); // Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed // Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed // then we'll attempt to restore the previous binding (if any), otherwise an attempt // then we'll attempt to restore the previous binding (if any), otherwise an attempt // will be made to bind to the new scorer. // will be made to bind to the new scorer. Loading Loading @@ -409,7 +417,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override @Override protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG); NetworkScorerAppData currentScorer = NetworkScorerAppManager.getActiveScorer(mContext); NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer(); if (currentScorer == null) { if (currentScorer == null) { writer.println("Scoring is disabled."); writer.println("Scoring is disabled."); return; return; Loading