Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ LOCAL_SRC_FILES += \ core/java/android/net/INetworkManagementEventObserver.aidl \ core/java/android/net/INetworkPolicyListener.aidl \ core/java/android/net/INetworkPolicyManager.aidl \ core/java/android/net/INetworkScoreService.aidl \ core/java/android/net/INetworkStatsService.aidl \ core/java/android/net/INetworkStatsSession.aidl \ core/java/android/net/nsd/INsdManager.aidl \ Loading core/java/android/net/INetworkScoreService.aidl 0 → 100644 +49 −0 Original line number Diff line number Diff line /** * Copyright (c) 2014, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.net.ScoredNetwork; /** * A service for updating network scores from a network scorer application. * @hide */ interface INetworkScoreService { /** * Update scores. * @return whether the update was successful. * @throws SecurityException if the caller is not the current active scorer. */ boolean updateScores(in ScoredNetwork[] networks); /** * Clear all scores. * @return whether the clear was successful. * @throws SecurityException if the caller is neither the current active scorer nor the scorer * manager. */ boolean clearScores(); /** * Set the active scorer and clear existing scores. * @param packageName the package name of the new scorer to use. * @return true if the operation succeeded, or false if the new package is not a valid scorer. * @throws SecurityException if the caller is not the scorer manager. */ boolean setActiveScorer(in String packageName); } core/java/android/net/NetworkKey.java +23 −0 Original line number Diff line number Diff line Loading @@ -19,11 +19,19 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; import java.util.Objects; /** * Information which identifies a specific network. * * @hide */ // NOTE: Ideally, we would abstract away the details of what identifies a network of a specific // type, so that all networks appear the same and can be scored without concern to the network type // itself. However, because no such cross-type identifier currently exists in the Android framework, // and because systems might obtain information about networks from sources other than Android // devices, we need to provide identifying details about each specific network type (wifi, cell, // etc.) so that clients can pull out these details depending on the type of network. public class NetworkKey implements Parcelable { /** A wifi network, for which {@link #wifiKey} will be populated. */ Loading Loading @@ -78,6 +86,21 @@ public class NetworkKey implements Parcelable { } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NetworkKey that = (NetworkKey) o; return type == that.type && Objects.equals(wifiKey, that.wifiKey); } @Override public int hashCode() { return Objects.hash(type, wifiKey); } @Override public String toString() { switch (type) { Loading core/java/android/net/NetworkScoreManager.java +60 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.net; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; /** * Class that manages communication between network subsystems and a network scorer. Loading @@ -40,7 +43,7 @@ import android.content.Context; * <p>The system keeps track of a default 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 default scorer with * {@link #getDefaultScorerPackage()} and request to change the default scorer by sending an * {@link #getActiveScorerPackage()} and request to change the default scorer by sending an * {@link #ACTION_CHANGE_DEFAULT} broadcast with another scorer. * * @hide Loading Loading @@ -81,38 +84,82 @@ public class NetworkScoreManager { public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore"; private final Context mContext; private final INetworkScoreService mService; /** @hide */ public NetworkScoreManager(Context context) { mContext = context; IBinder iBinder = ServiceManager.getService(Context.NETWORK_SCORE_SERVICE); mService = INetworkScoreService.Stub.asInterface(iBinder); } /** * Obtain the package name of the current default network scorer. * Obtain the package name of the current active network scorer. * * At any time, only one scorer application will receive {@link #ACTION_SCORE_NETWORKS} * <p>At any time, only one scorer application will receive {@link #ACTION_SCORE_NETWORKS} * broadcasts and be allowed to call {@link #updateScores}. Applications may use this method to * determine the current scorer and offer the user the ability to select a different scorer via * the {@link #ACTION_CHANGE_DEFAULT} intent. * @return the full package name of the current default scorer, or null if there is no active * @return the full package name of the current active scorer, or null if there is no active * scorer. */ public String getDefaultScorerPackage() { // TODO: Implement. return null; public String getActiveScorerPackage() { return NetworkScorerAppManager.getActiveScorer(mContext); } /** * Update network scores. * * This may be called at any time to re-score active networks. Scores will generally be updated * quickly, but if this method is called too frequently, the scores may be held and applied at * a later time. * <p>This may be called at any time to re-score active networks. Scores will generally be * updated quickly, but if this method is called too frequently, the scores may be held and * applied at a later time. * * @param networks the networks which have been scored by the scorer. * @throws SecurityException if the caller is not the default scorer. * @return whether the update was successful. * @throws SecurityException if the caller is not the active scorer. */ public void updateScores(ScoredNetwork[] networks) throws SecurityException { // TODO: Implement. public boolean updateScores(ScoredNetwork[] networks) throws SecurityException { try { return mService.updateScores(networks); } catch (RemoteException e) { return false; } } /** * Clear network scores. * * <p>Should be called when all scores need to be invalidated, i.e. because the scoring * algorithm has changed and old scores can no longer be compared to future scores. * * <p>Note that scores will be cleared automatically when the active scorer changes, as scores * from one scorer cannot be compared to those from another scorer. * * @return whether the clear was successful. * @throws SecurityException if the caller is not the active scorer or privileged. */ public boolean clearScores() throws SecurityException { try { return mService.clearScores(); } catch (RemoteException e) { return false; } } /** * Set the active scorer to a new package and clear existing scores. * * @return true if the operation succeeded, or false if the new package is not a valid scorer. * @throws SecurityException if the caller does not hold the * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission indicating that * it can manage scorer applications. * @hide */ public boolean setActiveScorer(String packageName) throws SecurityException { try { return mService.setActiveScorer(packageName); } catch (RemoteException e) { return false; } } } core/java/android/net/NetworkScorerApplication.java→core/java/android/net/NetworkScorerAppManager.java +15 −5 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.pm.ResolveInfo; import android.provider.Settings; import android.provider.Settings.Global; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.Collection; Loading @@ -36,13 +37,14 @@ import java.util.List; * * @hide */ public final class NetworkScorerApplication { public final class NetworkScorerAppManager { private static final String TAG = "NetworkScorerAppManager"; private static final Intent SCORE_INTENT = new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); /** This class cannot be instantiated. */ private NetworkScorerApplication() {} private NetworkScorerAppManager() {} /** * Returns the list of available scorer app package names. Loading Loading @@ -111,30 +113,38 @@ public final class NetworkScorerApplication { * @param context the context of the calling application * @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. * @return true if the scorer was changed, or false if the package is not a valid scorer. */ public static void setActiveScorer(Context context, String packageName) { public static boolean setActiveScorer(Context context, String packageName) { String oldPackageName = Settings.Global.getString(context.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); if (TextUtils.equals(oldPackageName, packageName)) { // No change. return; return true; } Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); if (packageName == null) { Settings.Global.putString(context.getContentResolver(), Global.NETWORK_SCORER_APP, null); return true; } else { // We only make the change if the new package is valid. Collection<String> applications = getAllValidScorers(context); if (isPackageValidScorer(applications, packageName)) { Settings.Global.putString(context.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, packageName); return true; } else { Log.w(TAG, "Requested network scorer is not valid: " + packageName); return false; } } } /** Determine whether the application with the given UID is the enabled scorer. */ public static boolean isCallerDefaultScorer(Context context, int callingUid) { public static boolean isCallerActiveScorer(Context context, int callingUid) { String defaultApp = getActiveScorer(context); if (defaultApp == null) { return false; Loading Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,7 @@ LOCAL_SRC_FILES += \ core/java/android/net/INetworkManagementEventObserver.aidl \ core/java/android/net/INetworkPolicyListener.aidl \ core/java/android/net/INetworkPolicyManager.aidl \ core/java/android/net/INetworkScoreService.aidl \ core/java/android/net/INetworkStatsService.aidl \ core/java/android/net/INetworkStatsSession.aidl \ core/java/android/net/nsd/INsdManager.aidl \ Loading
core/java/android/net/INetworkScoreService.aidl 0 → 100644 +49 −0 Original line number Diff line number Diff line /** * Copyright (c) 2014, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net; import android.net.ScoredNetwork; /** * A service for updating network scores from a network scorer application. * @hide */ interface INetworkScoreService { /** * Update scores. * @return whether the update was successful. * @throws SecurityException if the caller is not the current active scorer. */ boolean updateScores(in ScoredNetwork[] networks); /** * Clear all scores. * @return whether the clear was successful. * @throws SecurityException if the caller is neither the current active scorer nor the scorer * manager. */ boolean clearScores(); /** * Set the active scorer and clear existing scores. * @param packageName the package name of the new scorer to use. * @return true if the operation succeeded, or false if the new package is not a valid scorer. * @throws SecurityException if the caller is not the scorer manager. */ boolean setActiveScorer(in String packageName); }
core/java/android/net/NetworkKey.java +23 −0 Original line number Diff line number Diff line Loading @@ -19,11 +19,19 @@ package android.net; import android.os.Parcel; import android.os.Parcelable; import java.util.Objects; /** * Information which identifies a specific network. * * @hide */ // NOTE: Ideally, we would abstract away the details of what identifies a network of a specific // type, so that all networks appear the same and can be scored without concern to the network type // itself. However, because no such cross-type identifier currently exists in the Android framework, // and because systems might obtain information about networks from sources other than Android // devices, we need to provide identifying details about each specific network type (wifi, cell, // etc.) so that clients can pull out these details depending on the type of network. public class NetworkKey implements Parcelable { /** A wifi network, for which {@link #wifiKey} will be populated. */ Loading Loading @@ -78,6 +86,21 @@ public class NetworkKey implements Parcelable { } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NetworkKey that = (NetworkKey) o; return type == that.type && Objects.equals(wifiKey, that.wifiKey); } @Override public int hashCode() { return Objects.hash(type, wifiKey); } @Override public String toString() { switch (type) { Loading
core/java/android/net/NetworkScoreManager.java +60 −13 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package android.net; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; /** * Class that manages communication between network subsystems and a network scorer. Loading @@ -40,7 +43,7 @@ import android.content.Context; * <p>The system keeps track of a default 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 default scorer with * {@link #getDefaultScorerPackage()} and request to change the default scorer by sending an * {@link #getActiveScorerPackage()} and request to change the default scorer by sending an * {@link #ACTION_CHANGE_DEFAULT} broadcast with another scorer. * * @hide Loading Loading @@ -81,38 +84,82 @@ public class NetworkScoreManager { public static final String EXTRA_NETWORKS_TO_SCORE = "networksToScore"; private final Context mContext; private final INetworkScoreService mService; /** @hide */ public NetworkScoreManager(Context context) { mContext = context; IBinder iBinder = ServiceManager.getService(Context.NETWORK_SCORE_SERVICE); mService = INetworkScoreService.Stub.asInterface(iBinder); } /** * Obtain the package name of the current default network scorer. * Obtain the package name of the current active network scorer. * * At any time, only one scorer application will receive {@link #ACTION_SCORE_NETWORKS} * <p>At any time, only one scorer application will receive {@link #ACTION_SCORE_NETWORKS} * broadcasts and be allowed to call {@link #updateScores}. Applications may use this method to * determine the current scorer and offer the user the ability to select a different scorer via * the {@link #ACTION_CHANGE_DEFAULT} intent. * @return the full package name of the current default scorer, or null if there is no active * @return the full package name of the current active scorer, or null if there is no active * scorer. */ public String getDefaultScorerPackage() { // TODO: Implement. return null; public String getActiveScorerPackage() { return NetworkScorerAppManager.getActiveScorer(mContext); } /** * Update network scores. * * This may be called at any time to re-score active networks. Scores will generally be updated * quickly, but if this method is called too frequently, the scores may be held and applied at * a later time. * <p>This may be called at any time to re-score active networks. Scores will generally be * updated quickly, but if this method is called too frequently, the scores may be held and * applied at a later time. * * @param networks the networks which have been scored by the scorer. * @throws SecurityException if the caller is not the default scorer. * @return whether the update was successful. * @throws SecurityException if the caller is not the active scorer. */ public void updateScores(ScoredNetwork[] networks) throws SecurityException { // TODO: Implement. public boolean updateScores(ScoredNetwork[] networks) throws SecurityException { try { return mService.updateScores(networks); } catch (RemoteException e) { return false; } } /** * Clear network scores. * * <p>Should be called when all scores need to be invalidated, i.e. because the scoring * algorithm has changed and old scores can no longer be compared to future scores. * * <p>Note that scores will be cleared automatically when the active scorer changes, as scores * from one scorer cannot be compared to those from another scorer. * * @return whether the clear was successful. * @throws SecurityException if the caller is not the active scorer or privileged. */ public boolean clearScores() throws SecurityException { try { return mService.clearScores(); } catch (RemoteException e) { return false; } } /** * Set the active scorer to a new package and clear existing scores. * * @return true if the operation succeeded, or false if the new package is not a valid scorer. * @throws SecurityException if the caller does not hold the * {@link android.Manifest.permission#BROADCAST_SCORE_NETWORKS} permission indicating that * it can manage scorer applications. * @hide */ public boolean setActiveScorer(String packageName) throws SecurityException { try { return mService.setActiveScorer(packageName); } catch (RemoteException e) { return false; } } }
core/java/android/net/NetworkScorerApplication.java→core/java/android/net/NetworkScorerAppManager.java +15 −5 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.pm.ResolveInfo; import android.provider.Settings; import android.provider.Settings.Global; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.Collection; Loading @@ -36,13 +37,14 @@ import java.util.List; * * @hide */ public final class NetworkScorerApplication { public final class NetworkScorerAppManager { private static final String TAG = "NetworkScorerAppManager"; private static final Intent SCORE_INTENT = new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); /** This class cannot be instantiated. */ private NetworkScorerApplication() {} private NetworkScorerAppManager() {} /** * Returns the list of available scorer app package names. Loading Loading @@ -111,30 +113,38 @@ public final class NetworkScorerApplication { * @param context the context of the calling application * @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. * @return true if the scorer was changed, or false if the package is not a valid scorer. */ public static void setActiveScorer(Context context, String packageName) { public static boolean setActiveScorer(Context context, String packageName) { String oldPackageName = Settings.Global.getString(context.getContentResolver(), Settings.Global.NETWORK_SCORER_APP); if (TextUtils.equals(oldPackageName, packageName)) { // No change. return; return true; } Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName); if (packageName == null) { Settings.Global.putString(context.getContentResolver(), Global.NETWORK_SCORER_APP, null); return true; } else { // We only make the change if the new package is valid. Collection<String> applications = getAllValidScorers(context); if (isPackageValidScorer(applications, packageName)) { Settings.Global.putString(context.getContentResolver(), Settings.Global.NETWORK_SCORER_APP, packageName); return true; } else { Log.w(TAG, "Requested network scorer is not valid: " + packageName); return false; } } } /** Determine whether the application with the given UID is the enabled scorer. */ public static boolean isCallerDefaultScorer(Context context, int callingUid) { public static boolean isCallerActiveScorer(Context context, int callingUid) { String defaultApp = getActiveScorer(context); if (defaultApp == null) { return false; Loading