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

Commit 53173cbc authored by Zach Johnson's avatar Zach Johnson Committed by android-build-merger
Browse files

Merge "Adjust scan permissions"

am: 7c95714c

Change-Id: I80ba1d2b2fe2a68cabd41906343d6ebfd6696624
parents e057fd86 7c95714c
Loading
Loading
Loading
Loading
+86 −11
Original line number Diff line number Diff line
@@ -286,32 +286,98 @@ public final class Utils {
    }

    /**
     * Checks that calling process has android.Manifest.permission.ACCESS_FINE_LOCATION and
     * Checks that calling process has android.Manifest.permission.ACCESS_COARSE_LOCATION and
     * OP_COARSE_LOCATION is allowed
     */
    public static boolean checkCallerHasCoarseLocation(Context context, AppOpsManager appOps,
            String callingPackage, UserHandle userHandle) {
        if (blockedByLocationOff(context, userHandle)) {
            Log.e(TAG, "Permission denial: Location is off.");
            return false;
        }

        // Check coarse, but note fine
        if (context.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED
                && isAppOppAllowed(appOps, AppOpsManager.OP_FINE_LOCATION, callingPackage)) {
            return true;
        }

        Log.e(TAG, "Permission denial: Need ACCESS_COARSE_LOCATION "
                + "permission to get scan results");
        return false;
    }

    /**
     * Checks that calling process has android.Manifest.permission.ACCESS_COARSE_LOCATION and
     * OP_COARSE_LOCATION is allowed or android.Manifest.permission.ACCESS_FINE_LOCATION and
     * OP_FINE_LOCATION is allowed
     */
    public static boolean checkCallerHasLocationPermission(Context context, AppOpsManager appOps,
    public static boolean checkCallerHasCoarseOrFineLocation(Context context, AppOpsManager appOps,
            String callingPackage, UserHandle userHandle) {
        if (context.checkCallingOrSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED || !isAppOppAllowed(
                        appOps, AppOpsManager.OP_FINE_LOCATION, callingPackage)) {
            Log.e(TAG, "Permission denial: Need ACCESS_FINE_LOCATION "
        if (blockedByLocationOff(context, userHandle)) {
            Log.e(TAG, "Permission denial: Location is off.");
            return false;
        }

        if (context.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED
                && isAppOppAllowed(appOps, AppOpsManager.OP_FINE_LOCATION, callingPackage)) {
            return true;
        }

        // Check coarse, but note fine
        if (context.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED
                && isAppOppAllowed(appOps, AppOpsManager.OP_FINE_LOCATION, callingPackage)) {
            return true;
        }

        Log.e(TAG, "Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION"
                + "permission to get scan results");
        return false;
    }

    /**
     * Checks that calling process has android.Manifest.permission.ACCESS_FINE_LOCATION and
     * OP_FINE_LOCATION is allowed
     */
    public static boolean checkCallerHasFineLocation(Context context, AppOpsManager appOps,
            String callingPackage, UserHandle userHandle) {
        if (blockedByLocationOff(context, userHandle)) {
            Log.e(TAG, "Permission denial: Location is off.");
            return false;
        }

        if (context.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED
                && isAppOppAllowed(appOps, AppOpsManager.OP_FINE_LOCATION, callingPackage)) {
            return true;
        }

        Log.e(TAG, "Permission denial: Need ACCESS_FINE_LOCATION "
                + "permission to get scan results");
        return false;
    }

    /**
     * Returns true if the caller holds NETWORK_SETTINGS
     */
    public static boolean checkCallerHasNetworkSettingsPermission(Context context) {
        return context.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS)
                == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * Returns true if the caller holds PEERS_MAC_ADDRESS.
     * Returns true if the caller holds NETWORK_SETUP_WIZARD
     */
    public static boolean checkCallerHasPeersMacAddressPermission(Context context) {
        return context.checkCallingOrSelfPermission(android.Manifest.permission.PEERS_MAC_ADDRESS)
    public static boolean checkCallerHasNetworkSetupWizardPermission(Context context) {
        return context.checkCallingOrSelfPermission(
                android.Manifest.permission.NETWORK_SETUP_WIZARD)
                        == PackageManager.PERMISSION_GRANTED;
    }

@@ -329,6 +395,15 @@ public final class Utils {
        return true;
    }

    public static boolean isQApp(Context context, String pkgName) {
        try {
            return context.getPackageManager().getApplicationInfo(pkgName, 0).targetSdkVersion
                    >= Build.VERSION_CODES.Q;
        } catch (PackageManager.NameNotFoundException e) {
            // In case of exception, assume Q app
        }
        return true;
    }
    /**
     * Return true if the specified package name is a foreground app.
     *
+1 −0
Original line number Diff line number Diff line
@@ -923,6 +923,7 @@ class AdapterProperties {
            Intent intent;
            if (state == AbstractionLayer.BT_DISCOVERY_STOPPED) {
                mDiscovering = false;
                mService.clearDiscoveringPackages();
                mDiscoveryEndMs = System.currentTimeMillis();
                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
                mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
+33 −2
Original line number Diff line number Diff line
@@ -136,6 +136,8 @@ public class AdapterService extends Service {

    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;

    private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>();

    static {
        classInitNative();
    }
@@ -386,6 +388,7 @@ public class AdapterService extends Service {
        debugLog("onCreate()");
        mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper());
        mRemoteDevices.init();
        clearDiscoveringPackages();
        mBinder = new AdapterServiceBinder(this);
        mAdapterProperties = new AdapterProperties(this);
        mAdapterStateMachine = AdapterState.make(this);
@@ -1905,14 +1908,42 @@ public class AdapterService extends Service {
        return mAdapterProperties.setDiscoverableTimeout(timeout);
    }

    ArrayList<DiscoveringPackage> getDiscoveringPackages() {
        return mDiscoveringPackages;
    }

    void clearDiscoveringPackages() {
        synchronized (mDiscoveringPackages) {
            mDiscoveringPackages.clear();
        }
    }

    boolean startDiscovery(String callingPackage) {
        UserHandle callingUser = UserHandle.of(UserHandle.getCallingUserId());
        debugLog("startDiscovery");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
        if (!Utils.checkCallerHasLocationPermission(this, mAppOps, callingPackage, callingUser)) {
        mAppOps.checkPackage(callingUser.getIdentifier(), callingPackage);
        boolean isQApp = Utils.isQApp(this, callingPackage);
        String permission = null;
        if (Utils.checkCallerHasNetworkSettingsPermission(this)) {
            permission = android.Manifest.permission.NETWORK_SETTINGS;
        } else if (Utils.checkCallerHasNetworkSetupWizardPermission(this)) {
            permission = android.Manifest.permission.NETWORK_SETUP_WIZARD;
        } else if (isQApp) {
            if (!Utils.checkCallerHasFineLocation(this, mAppOps, callingPackage, callingUser)) {
                return false;
            }
            permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
        } else {
            if (!Utils.checkCallerHasCoarseLocation(this, mAppOps, callingPackage, callingUser)) {
                return false;
            }
            permission = android.Manifest.permission.ACCESS_COARSE_LOCATION;
        }

        synchronized (mDiscoveringPackages) {
            mDiscoveringPackages.add(new DiscoveringPackage(callingPackage, permission));
        }
        return startDiscoveryNative();
    }

+35 −0
Original line number Diff line number Diff line
/*
 * Copyright 2019 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 com.android.bluetooth.btservice;

final class DiscoveringPackage {
    private String mPackageName;
    private String mPermission;

    DiscoveringPackage(String packageName, String permission) {
        mPackageName = packageName;
        mPermission = permission;
    }

    public String getPackageName() {
        return mPackageName;
    }

    public String getPermission() {
        return mPermission;
    }
}
+9 −3
Original line number Diff line number Diff line
@@ -582,10 +582,16 @@ final class RemoteDevices {
        intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.mRssi);
        intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.mName);

        final ArrayList<DiscoveringPackage> packages = sAdapterService.getDiscoveringPackages();
        synchronized (packages) {
            for (DiscoveringPackage pkg : packages) {
                intent.setPackage(pkg.getPackageName());
                sAdapterService.sendBroadcastMultiplePermissions(intent, new String[]{
                AdapterService.BLUETOOTH_PERM, android.Manifest.permission.ACCESS_COARSE_LOCATION
                        AdapterService.BLUETOOTH_PERM, pkg.getPermission()
                });
            }
        }
    }

    void aclStateChangeCallback(int status, byte[] address, int newState) {
        BluetoothDevice device = getDevice(address);
Loading