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

Commit 35f0f59b authored by Oli Lan's avatar Oli Lan
Browse files

Check if location usage has been disavowed for scans in GattService.

This populates the hasDisavowedLocation field based on whether the
client has specified neverForLocation on the BLUETOOTH_SCAN permission.

This field is then used to determine if the filter should be applied
when scan results are sent.

Bug: 183203469
Test: atest GattServiceTest
Change-Id: Id0b4402b9a1974af37d454553794dad563d10e1a
parent 1c66309e
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.bluetooth;

import static android.Manifest.permission.BLUETOOTH_SCAN;
import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.Manifest;
@@ -32,6 +33,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.PermissionChecker;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.location.LocationManager;
@@ -420,6 +422,31 @@ public final class Utils {
        return permissionCheckResult == PERMISSION_GRANTED;
    }

    /**
     * Returns true if the specified package has disavowed the use of bluetooth scans for location,
     * that is, if they have specified the {@code neverForLocation} flag on the BLUETOOTH_SCAN
     * permission.
     */
    public static boolean hasDisavowedLocationForScan(Context context, String packageName) {

        // TODO(b/183203469): Check PermissionIdentity to include dynamic disavowal cases.

        PackageManager pm = context.getPackageManager();
        try {
            // TODO(b/183478032): Cache PackageInfo for use here.
            PackageInfo pkgInfo = pm.getPackageInfo(packageName, GET_PERMISSIONS);
            for (int i = 0; i < pkgInfo.requestedPermissions.length; i++) {
                if (pkgInfo.requestedPermissions[i].equals(BLUETOOTH_SCAN)) {
                    return (pkgInfo.requestedPermissionsFlags[i]
                            & PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION) != 0;
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Could not find package for disavowal check: " + packageName);
        }
        return false;
    }

    public static boolean callerIsSystemOrActiveUser(String tag, String method) {
        if (!checkCaller()) {
          Log.w(TAG, method + "() - Not allowed for non-active user and non-system user");
+5 −10
Original line number Diff line number Diff line
@@ -197,12 +197,6 @@ public class GattService extends ProfileService {

    private final Object mDeviceConfigLock = new Object();

    /**
     * Feature flag used to enable denylist that filters devices that are
     * well-known to be used for physical location.
     */
    private static final boolean ENABLE_LOCATION_DENYLIST = false;

    /**
     * Matcher that can be applied to MAC addresses to determine if a
     * {@link BluetoothDevice} is well-known to be used for physical location.
@@ -1111,8 +1105,7 @@ public class GattService extends ProfileService {

            ScanRecord scanRecord = ScanRecord.parseFromBytes(scanRecordData);

            // TODO: only apply denylist filter based on destination capabilities
            if (ENABLE_LOCATION_DENYLIST) {
            if (client.hasDisavowedLocation) {
                synchronized (mDeviceConfigLock) {
                    final MacAddress parsedAddress = MacAddress.fromString(address);
                    if (mLocationDenylistMac.testMacAddress(parsedAddress)) {
@@ -2184,7 +2177,8 @@ public class GattService extends ProfileService {
        scanClient.eligibleForSanitizedExposureNotification =
                callingPackage.equals(mExposureNotificationPackage);

        // TODO: set hasDisavowedLocation
        scanClient.hasDisavowedLocation =
                Utils.hasDisavowedLocationForScan(this, callingPackage);

        scanClient.isQApp = Utils.isQApp(this, callingPackage);
        if (!scanClient.hasDisavowedLocation) {
@@ -2256,7 +2250,8 @@ public class GattService extends ProfileService {
        app.mEligibleForSanitizedExposureNotification =
                callingPackage.equals(mExposureNotificationPackage);

        // TODO: set hasDisavowedLocation
        app.mHasDisavowedLocation =
                Utils.hasDisavowedLocationForScan(this, callingPackage);

        app.mIsQApp = Utils.isQApp(this, callingPackage);
        if (!app.mHasDisavowedLocation) {