Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 589ba65d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "NetworkRecommendationProviders require the location permission." into oc-mr1-dev

parents 39a9832d 59502ebc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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>
+2 −1
Original line number Diff line number Diff line
@@ -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.
+1 −0
Original line number Diff line number Diff line
@@ -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.

+15 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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;
    }
+44 −15
Original line number Diff line number Diff line
@@ -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;
@@ -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.");
                }
@@ -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.
     *
@@ -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);
    }

    /**
@@ -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() {
@@ -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);
        }
    }

    /**
@@ -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