Loading core/java/android/net/NetworkRecommendationProvider.java +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import java.util.concurrent.Executor; * A network recommendation provider is any application which: * <ul> * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent * which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission. * </ul> Loading core/java/android/net/NetworkScoreManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,8 @@ import java.util.List; * * <p>A network scorer is any application which: * <ul> * <li>Declares the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action * protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} * permission. Loading core/res/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1391,6 +1391,7 @@ <!-- The package name of the default network recommendation app. A network recommendation provider must: * Be granted the SCORE_NETWORKS permission. * Be granted the ACCESS_COARSE_LOCATION permission. * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission. Loading services/core/java/com/android/server/NetworkScoreService.java +15 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.location.LocationManager; import android.net.INetworkRecommendationProvider; import android.net.INetworkScoreCache; import android.net.INetworkScoreService; Loading Loading @@ -113,6 +114,16 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } }; private BroadcastReceiver mLocationModeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { refreshBinding(); } } }; /** * Clears scores when the active scorer package is no longer valid and * manages the service connection. Loading Loading @@ -241,6 +252,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub { mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/, null /* scheduler */); mHandler = new ServiceHandler(looper); IntentFilter locationModeFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); mContext.registerReceiverAsUser( mLocationModeReceiver, UserHandle.SYSTEM, locationModeFilter, null /* broadcastPermission*/, mHandler); mContentObserver = new DispatchingContentObserver(context, mHandler); mServiceConnProducer = serviceConnProducer; } Loading services/core/java/com/android/server/NetworkScorerAppManager.java +44 −15 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server; import android.Manifest.permission; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -79,7 +80,7 @@ public class NetworkScorerAppManager { List<NetworkScorerAppData> appDataList = new ArrayList<>(); for (int i = 0; i < resolveInfos.size(); i++) { final ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo; if (hasPermissions(serviceInfo.packageName)) { if (hasPermissions(serviceInfo.applicationInfo.uid, serviceInfo.packageName)) { if (VERBOSE) { Log.v(TAG, serviceInfo.packageName + " is a valid scorer/recommender."); } Loading Loading @@ -197,12 +198,33 @@ public class NetworkScorerAppManager { return null; } private boolean hasPermissions(String packageName) { private boolean hasPermissions(final int uid, final String packageName) { return hasScoreNetworksPermission(packageName) && canAccessLocation(uid, packageName); } private boolean hasScoreNetworksPermission(String packageName) { final PackageManager pm = mContext.getPackageManager(); return pm.checkPermission(permission.SCORE_NETWORKS, packageName) == PackageManager.PERMISSION_GRANTED; } private boolean canAccessLocation(int uid, String packageName) { final PackageManager pm = mContext.getPackageManager(); final AppOpsManager appOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); return isLocationModeEnabled() && pm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName) == PackageManager.PERMISSION_GRANTED && appOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName) == AppOpsManager.MODE_ALLOWED; } private boolean isLocationModeEnabled() { return mSettingsFacade.getSecureInt(mContext, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF; } /** * Set the specified package as the default scorer application. * Loading Loading @@ -270,23 +292,20 @@ public class NetworkScorerAppManager { return; } // the active scorer isn't valid, revert to the default if it's different int newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF; // the active scorer isn't valid, revert to the default if it's different and valid final String defaultPackageName = getDefaultPackageSetting(); if (!TextUtils.equals(currentPackageName, defaultPackageName)) { setNetworkRecommendationsPackage(defaultPackageName); if (!TextUtils.equals(currentPackageName, defaultPackageName) && getScorer(defaultPackageName) != null) { if (DEBUG) { Log.d(TAG, "Defaulted the network recommendations app to: " + defaultPackageName); } if (getScorer(defaultPackageName) != null) { // the default is valid if (DEBUG) Log.d(TAG, defaultPackageName + " is now the active scorer."); setNetworkRecommendationsEnabledSetting( NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); } else { // the default isn't valid either, we're disabled at this point if (DEBUG) Log.d(TAG, defaultPackageName + " is not an active scorer."); setNetworkRecommendationsEnabledSetting( NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); Log.d(TAG, "Defaulting the network recommendations app to: " + defaultPackageName); } setNetworkRecommendationsPackage(defaultPackageName); newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON; } setNetworkRecommendationsEnabledSetting(newEnabledSetting); } /** Loading Loading @@ -352,6 +371,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsPackage(String packageName) { mSettingsFacade.putString(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, packageName); if (VERBOSE) { Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE + " set to " + packageName); } } private int getNetworkRecommendationsEnabledSetting() { Loading @@ -361,6 +383,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsEnabledSetting(int value) { mSettingsFacade.putInt(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, value); if (VERBOSE) { Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED + " set to " + value); } } /** Loading @@ -382,5 +407,9 @@ public class NetworkScorerAppManager { public int getInt(Context context, String name, int defaultValue) { return Settings.Global.getInt(context.getContentResolver(), name, defaultValue); } public int getSecureInt(Context context, String name, int defaultValue) { return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue); } } } Loading
core/java/android/net/NetworkRecommendationProvider.java +1 −0 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import java.util.concurrent.Executor; * A network recommendation provider is any application which: * <ul> * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Includes a Service for the {@link NetworkScoreManager#ACTION_RECOMMEND_NETWORKS} intent * which is protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} permission. * </ul> Loading
core/java/android/net/NetworkScoreManager.java +2 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,8 @@ import java.util.List; * * <p>A network scorer is any application which: * <ul> * <li>Declares the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#SCORE_NETWORKS} permission. * <li>Is granted the {@link permission#ACCESS_COARSE_LOCATION} permission. * <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action * protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE} * permission. Loading
core/res/res/values/config.xml +1 −0 Original line number Diff line number Diff line Loading @@ -1391,6 +1391,7 @@ <!-- The package name of the default network recommendation app. A network recommendation provider must: * Be granted the SCORE_NETWORKS permission. * Be granted the ACCESS_COARSE_LOCATION permission. * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission. Loading
services/core/java/com/android/server/NetworkScoreService.java +15 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.database.ContentObserver; import android.location.LocationManager; import android.net.INetworkRecommendationProvider; import android.net.INetworkScoreCache; import android.net.INetworkScoreService; Loading Loading @@ -113,6 +114,16 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } }; private BroadcastReceiver mLocationModeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { refreshBinding(); } } }; /** * Clears scores when the active scorer package is no longer valid and * manages the service connection. Loading Loading @@ -241,6 +252,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub { mUserIntentReceiver, UserHandle.SYSTEM, filter, null /* broadcastPermission*/, null /* scheduler */); mHandler = new ServiceHandler(looper); IntentFilter locationModeFilter = new IntentFilter(LocationManager.MODE_CHANGED_ACTION); mContext.registerReceiverAsUser( mLocationModeReceiver, UserHandle.SYSTEM, locationModeFilter, null /* broadcastPermission*/, mHandler); mContentObserver = new DispatchingContentObserver(context, mHandler); mServiceConnProducer = serviceConnProducer; } Loading
services/core/java/com/android/server/NetworkScorerAppManager.java +44 −15 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server; import android.Manifest.permission; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -79,7 +80,7 @@ public class NetworkScorerAppManager { List<NetworkScorerAppData> appDataList = new ArrayList<>(); for (int i = 0; i < resolveInfos.size(); i++) { final ServiceInfo serviceInfo = resolveInfos.get(i).serviceInfo; if (hasPermissions(serviceInfo.packageName)) { if (hasPermissions(serviceInfo.applicationInfo.uid, serviceInfo.packageName)) { if (VERBOSE) { Log.v(TAG, serviceInfo.packageName + " is a valid scorer/recommender."); } Loading Loading @@ -197,12 +198,33 @@ public class NetworkScorerAppManager { return null; } private boolean hasPermissions(String packageName) { private boolean hasPermissions(final int uid, final String packageName) { return hasScoreNetworksPermission(packageName) && canAccessLocation(uid, packageName); } private boolean hasScoreNetworksPermission(String packageName) { final PackageManager pm = mContext.getPackageManager(); return pm.checkPermission(permission.SCORE_NETWORKS, packageName) == PackageManager.PERMISSION_GRANTED; } private boolean canAccessLocation(int uid, String packageName) { final PackageManager pm = mContext.getPackageManager(); final AppOpsManager appOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); return isLocationModeEnabled() && pm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName) == PackageManager.PERMISSION_GRANTED && appOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName) == AppOpsManager.MODE_ALLOWED; } private boolean isLocationModeEnabled() { return mSettingsFacade.getSecureInt(mContext, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF; } /** * Set the specified package as the default scorer application. * Loading Loading @@ -270,23 +292,20 @@ public class NetworkScorerAppManager { return; } // the active scorer isn't valid, revert to the default if it's different int newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF; // the active scorer isn't valid, revert to the default if it's different and valid final String defaultPackageName = getDefaultPackageSetting(); if (!TextUtils.equals(currentPackageName, defaultPackageName)) { setNetworkRecommendationsPackage(defaultPackageName); if (!TextUtils.equals(currentPackageName, defaultPackageName) && getScorer(defaultPackageName) != null) { if (DEBUG) { Log.d(TAG, "Defaulted the network recommendations app to: " + defaultPackageName); } if (getScorer(defaultPackageName) != null) { // the default is valid if (DEBUG) Log.d(TAG, defaultPackageName + " is now the active scorer."); setNetworkRecommendationsEnabledSetting( NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); } else { // the default isn't valid either, we're disabled at this point if (DEBUG) Log.d(TAG, defaultPackageName + " is not an active scorer."); setNetworkRecommendationsEnabledSetting( NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); Log.d(TAG, "Defaulting the network recommendations app to: " + defaultPackageName); } setNetworkRecommendationsPackage(defaultPackageName); newEnabledSetting = NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON; } setNetworkRecommendationsEnabledSetting(newEnabledSetting); } /** Loading Loading @@ -352,6 +371,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsPackage(String packageName) { mSettingsFacade.putString(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, packageName); if (VERBOSE) { Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE + " set to " + packageName); } } private int getNetworkRecommendationsEnabledSetting() { Loading @@ -361,6 +383,9 @@ public class NetworkScorerAppManager { private void setNetworkRecommendationsEnabledSetting(int value) { mSettingsFacade.putInt(mContext, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, value); if (VERBOSE) { Log.d(TAG, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED + " set to " + value); } } /** Loading @@ -382,5 +407,9 @@ public class NetworkScorerAppManager { public int getInt(Context context, String name, int defaultValue) { return Settings.Global.getInt(context.getContentResolver(), name, defaultValue); } public int getSecureInt(Context context, String name, int defaultValue) { return Settings.Secure.getInt(context.getContentResolver(), name, defaultValue); } } }