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

Commit d2cf3636 authored by Zach Johnson's avatar Zach Johnson
Browse files

Add scanning exemption for CDM associated devices

If a device is associated via CDM, allow its app to
find it via BLE scans even if the app itself cannot see
other scan results due to location access being blocked.

Bug: 157051467
Tag: #compatibility
Test: nRF connect: block location - no results...associate via CDM - has
result

Change-Id: I1632c627fb16e1a9b9d9b2b985cf649690afe1c6
Merged-In: I1632c627fb16e1a9b9d9b2b985cf649690afe1c6
parent 2fbf3857
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
    <uses-permission android:name="android.permission.MANAGE_COMPANION_DEVICES"/>

    <uses-sdk android:minSdkVersion="14"/>

+2 −0
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@ import java.util.UUID;
        /** Whether the calling app has the network setup wizard permission */
        boolean mHasScanWithoutLocationPermission;

        public List<String> mAssociatedDevices;

        /** Internal callback info queue, waiting to be send on congestion clear */
        private List<CallbackInfo> mCongestionQueue = new ArrayList<CallbackInfo>();

+39 −2
Original line number Diff line number Diff line
@@ -45,11 +45,14 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.companion.ICompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -181,6 +184,7 @@ public class GattService extends ProfileService {
    private PeriodicScanManager mPeriodicScanManager;
    private ScanManager mScanManager;
    private AppOpsManager mAppOps;
    private ICompanionDeviceManager mCompanionManager;

    private static GattService sGattService;

@@ -205,6 +209,8 @@ public class GattService extends ProfileService {
        }
        initializeNative();
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mCompanionManager = ICompanionDeviceManager.Stub.asInterface(
                ServiceManager.getService(Context.COMPANION_DEVICE_SERVICE));
        mAppOps = getSystemService(AppOpsManager.class);
        mAdvertiseManager = new AdvertiseManager(this, AdapterService.getAdapterService());
        mAdvertiseManager.start();
@@ -1012,8 +1018,16 @@ public class GattService extends ProfileService {
                            txPower, rssi, periodicAdvInt,
                            ScanRecord.parseFromBytes(scanRecordData),
                            SystemClock.elapsedRealtimeNanos());
            // Do not report if location mode is OFF or the client has no location permission
            if (!hasScanResultPermission(client) || !matchesFilters(client, result)) {
            boolean hasPermission = hasScanResultPermission(client);
            if (!hasPermission) {
                for (String associatedDevice : client.associatedDevices) {
                    if (associatedDevice.equalsIgnoreCase(address)) {
                        hasPermission = true;
                        break;
                    }
                }
            }
            if (!hasPermission || !matchesFilters(client, result)) {
                continue;
            }

@@ -1938,6 +1952,26 @@ public class GattService extends ProfileService {
        mScanManager.unregisterScanner(scannerId);
    }

    private List<String> getAssociatedDevices(String callingPackage, UserHandle userHandle) {
        if (mCompanionManager == null) {
            return new ArrayList<String>();
        }
        long identity = Binder.clearCallingIdentity();
        try {
            return mCompanionManager.getAssociations(
                    callingPackage, userHandle.getIdentifier());
        } catch (SecurityException se) {
            // Not an app with associated devices
        } catch (RemoteException re) {
            Log.e(TAG, "Cannot reach companion device service", re);
        } catch (Exception e) {
            Log.e(TAG, "Cannot check device associations for " + callingPackage, e);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
        return new ArrayList<String>();
    }

    void startScan(int scannerId, ScanSettings settings, List<ScanFilter> filters,
            List<List<ResultStorageDescriptor>> storages, String callingPackage,
            @Nullable String callingFeatureId) {
@@ -1966,6 +2000,7 @@ public class GattService extends ProfileService {
                Utils.checkCallerHasNetworkSetupWizardPermission(this);
        scanClient.hasScanWithoutLocationPermission =
                Utils.checkCallerHasScanWithoutLocationPermission(this);
        scanClient.associatedDevices = getAssociatedDevices(callingPackage, scanClient.userHandle);

        AppScanStats app = mScannerMap.getAppScanStatsById(scannerId);
        ScannerMap.App cbApp = mScannerMap.getById(scannerId);
@@ -2030,6 +2065,7 @@ public class GattService extends ProfileService {
                Utils.checkCallerHasNetworkSetupWizardPermission(this);
        app.mHasScanWithoutLocationPermission =
                Utils.checkCallerHasScanWithoutLocationPermission(this);
        app.mAssociatedDevices = getAssociatedDevices(callingPackage, app.mUserHandle);
        mScanManager.registerScanner(uuid);
    }

@@ -2043,6 +2079,7 @@ public class GattService extends ProfileService {
        scanClient.hasNetworkSettingsPermission = app.mHasNetworkSettingsPermission;
        scanClient.hasNetworkSetupWizardPermission = app.mHasNetworkSetupWizardPermission;
        scanClient.hasScanWithoutLocationPermission = app.mHasScanWithoutLocationPermission;
        scanClient.associatedDevices = app.mAssociatedDevices;

        AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId);
        if (scanStats != null) {
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import java.util.UUID;
    public boolean hasNetworkSettingsPermission;
    public boolean hasNetworkSetupWizardPermission;
    public boolean hasScanWithoutLocationPermission;
    public List<String> associatedDevices;

    public AppScanStats stats = null;