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

Commit 72ecb4ca authored by Sharvil Nanavati's avatar Sharvil Nanavati
Browse files

Make location enabled check configurable when returning scan results.

Some device classes (e.g. Wear) don't allow location to be enabled but
would still like to allow LE scanning to take place. This patch allows
the location enabled check to be bypassed if the platform is so configured.
Even if the location check is disabled, the calling app must still have
one of the location permissions.

Bug: 21852542
Change-Id: I206366ce262776d4668c0c42e066f0e20f5fdfeb
parent 312e10ad
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -28,4 +28,9 @@
    <bool name="profile_supported_map">true</bool>
    <bool name="profile_supported_avrcp_controller">false</bool>
    <bool name="profile_supported_sap">false</bool>

    <!-- If true, we will require location to be enabled on the device to
         fire Bluetooth LE scan result callbacks in addition to having one
         of the location permissions. -->
    <bool name="strict_location_check">true</bool>
</resources>
+14 −6
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;

import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
@@ -582,9 +583,6 @@ public class GattService extends ProfileService {
    void onScanResult(String address, int rssi, byte[] adv_data) {
        if (VDBG) Log.d(TAG, "onScanResult() - address=" + address
                    + ", rssi=" + rssi);
        boolean locationEnabled = Settings.Secure.getInt(getContentResolver(),
                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
                != Settings.Secure.LOCATION_MODE_OFF;
        List<UUID> remoteUuids = parseUuids(adv_data);
        for (ScanClient client : mScanManager.getRegularScanQueue()) {
            if (client.uuids.length > 0) {
@@ -610,9 +608,7 @@ public class GattService extends ProfileService {
                            rssi, SystemClock.elapsedRealtimeNanos());
                    // Do no report if location mode is OFF or the client has no location permission
                    // PEERS_MAC_ADDRESS permission holders always get results
                    if ((client.hasPeersMacAddressPermission
                            || (locationEnabled && client.hasLocationPermission))
                            && matchesFilters(client, result)) {
                    if (hasScanResultPermission(client) && matchesFilters(client, result)) {
                        try {
                            ScanSettings settings = client.settings;
                            if ((settings.getCallbackType() &
@@ -641,6 +637,18 @@ public class GattService extends ProfileService {
        }
    }

    /** Determines if the given scan client has the appropriate permissions to receive callbacks. */
    private boolean hasScanResultPermission(final ScanClient client) {
        final boolean requiresLocationEnabled =
                getResources().getBoolean(R.bool.strict_location_check);
        final boolean locationEnabled = Settings.Secure.getInt(getContentResolver(),
                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
                != Settings.Secure.LOCATION_MODE_OFF;

        return (client.hasPeersMacAddressPermission ||
                (client.hasLocationPermission && (!requiresLocationEnabled || locationEnabled)));
    }

    // Check if a scan record matches a specific filters.
    private boolean matchesFilters(ScanClient client, ScanResult scanResult) {
        if (client.filters == null || client.filters.isEmpty()) {