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

Commit 3eca1577 authored by Amith Yamasani's avatar Amith Yamasani Committed by android-build-merger
Browse files

Merge "BLE scan API using PendingIntent" into oc-dev

am: 7859022e

Change-Id: Ic694cf7dae7e7c151155787da5b079699cec93ed
parents a1ba99cb 7859022e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -8078,7 +8078,12 @@ package android.bluetooth.le {
    method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
    method public void startScan(android.bluetooth.le.ScanCallback);
    method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
    method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
    method public void stopScan(android.bluetooth.le.ScanCallback);
    method public void stopScan(android.app.PendingIntent);
    field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
    field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
    field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
  }
  public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+5 −0
Original line number Diff line number Diff line
@@ -8550,10 +8550,15 @@ package android.bluetooth.le {
    method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
    method public void startScan(android.bluetooth.le.ScanCallback);
    method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
    method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
    method public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
    method public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
    method public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
    method public void stopScan(android.bluetooth.le.ScanCallback);
    method public void stopScan(android.app.PendingIntent);
    field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
    field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
    field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
  }
  public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+5 −0
Original line number Diff line number Diff line
@@ -8109,7 +8109,12 @@ package android.bluetooth.le {
    method public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
    method public void startScan(android.bluetooth.le.ScanCallback);
    method public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
    method public int startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.app.PendingIntent);
    method public void stopScan(android.bluetooth.le.ScanCallback);
    method public void stopScan(android.app.PendingIntent);
    field public static final java.lang.String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
    field public static final java.lang.String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
    field public static final java.lang.String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
  }
  public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.bluetooth;

import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.AdvertiseSettings;
@@ -47,6 +48,9 @@ interface IBluetoothGatt {
    void unregisterScanner(in int scannerId);
    void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
                   in WorkSource workSource, in List scanStorages, in String callingPackage);
    void startScanForIntent(in PendingIntent intent, in ScanSettings settings, in List<ScanFilter> filters,
                            in String callingPackage);
    void stopScanForIntent(in PendingIntent intent, in String callingPackage);
    void stopScan(in int scannerId);
    void flushPendingBatchResults(in int scannerId);

+99 −25
Original line number Diff line number Diff line
@@ -17,17 +17,18 @@
package android.bluetooth.le;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.le.IScannerCallback;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.WorkSource;
import android.util.Log;
@@ -36,7 +37,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * This class provides methods to perform scan related operations for Bluetooth LE devices. An
@@ -57,6 +57,27 @@ public final class BluetoothLeScanner {
    private static final boolean DBG = true;
    private static final boolean VDBG = false;

    /**
     * Extra containing a list of ScanResults. It can have one or more results if there was no
     * error. In case of error, {@link #EXTRA_ERROR_CODE} will contain the error code and this
     * extra will not be available.
     */
    public static final String EXTRA_LIST_SCAN_RESULT
            = "android.bluetooth.le.extra.LIST_SCAN_RESULT";

    /**
     * Optional extra indicating the error code, if any. The error code will be one of the
     * SCAN_FAILED_* codes in {@link ScanCallback}.
     */
    public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";

    /**
     * Optional extra indicating the callback type, which will be one of
     * ScanSettings.CALLBACK_TYPE_*.
     * @see ScanCallback#onScanResult(int, ScanResult)
     */
    public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";

    private final IBluetoothManager mBluetoothManager;
    private final Handler mHandler;
    private BluetoothAdapter mBluetoothAdapter;
@@ -110,7 +131,27 @@ public final class BluetoothLeScanner {
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public void startScan(List<ScanFilter> filters, ScanSettings settings,
            final ScanCallback callback) {
        startScan(filters, settings, null, callback, null);
        startScan(filters, settings, null, callback, /*callbackIntent=*/ null, null);
    }

    /**
     * Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
     * the PendingIntent. Use this method of scanning if your process is not always running and it
     * should be started when scan results are available.
     *
     * @param filters Optional list of ScanFilters for finding exact BLE devices.
     * @param settings Optional settings for the scan.
     * @param callbackIntent The PendingIntent to deliver the result to.
     * @return Returns 0 for success or an error code from {@link ScanCallback} if the scan request
     * could not be sent.
     * @see #stopScan(PendingIntent)
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public int startScan(@Nullable List<ScanFilter> filters, @Nullable ScanSettings settings,
            @NonNull PendingIntent callbackIntent) {
        return startScan(filters,
                settings != null ? settings : new ScanSettings.Builder().build(),
                null, null, callbackIntent, null);
    }

    /**
@@ -145,23 +186,23 @@ public final class BluetoothLeScanner {
            Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.UPDATE_DEVICE_STATS })
    public void startScanFromSource(List<ScanFilter> filters, ScanSettings settings,
                                    final WorkSource workSource, final ScanCallback callback) {
        startScan(filters, settings, workSource, callback, null);
        startScan(filters, settings, workSource, callback, null, null);
    }

    private void startScan(List<ScanFilter> filters, ScanSettings settings,
    private int startScan(List<ScanFilter> filters, ScanSettings settings,
                           final WorkSource workSource, final ScanCallback callback,
                           final PendingIntent callbackIntent,
                           List<List<ResultStorageDescriptor>> resultStorages) {
        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
        if (callback == null) {
        if (callback == null && callbackIntent == null) {
            throw new IllegalArgumentException("callback is null");
        }
        if (settings == null) {
            throw new IllegalArgumentException("settings is null");
        }
        synchronized (mLeScanClients) {
            if (mLeScanClients.containsKey(callback)) {
            if (callback != null && mLeScanClients.containsKey(callback)) {
                postCallbackError(callback, ScanCallback.SCAN_FAILED_ALREADY_STARTED);
                return;
            }
            IBluetoothGatt gatt;
            try {
@@ -170,28 +211,34 @@ public final class BluetoothLeScanner {
                gatt = null;
            }
            if (gatt == null) {
                postCallbackError(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
                return;
                return postCallbackErrorOrReturn(callback, ScanCallback.SCAN_FAILED_INTERNAL_ERROR);
            }
            if (!isSettingsConfigAllowedForScan(settings)) {
                postCallbackError(callback,
                return postCallbackErrorOrReturn(callback,
                            ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
                return;
            }
            if (!isHardwareResourcesAvailableForScan(settings)) {
                postCallbackError(callback,
                return postCallbackErrorOrReturn(callback,
                            ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
                return;
            }
            if (!isSettingsAndFilterComboAllowed(settings, filters)) {
                postCallbackError(callback,
                return postCallbackErrorOrReturn(callback,
                        ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED);
                return;
            }
            if (callback != null) {
                BleScanCallbackWrapper wrapper = new BleScanCallbackWrapper(gatt, filters,
                        settings, workSource, callback, resultStorages);
            wrapper.startRegisteration();
                wrapper.startRegistration();
            } else {
                try {
                    gatt.startScanForIntent(callbackIntent, settings, filters,
                            ActivityThread.currentOpPackageName());
                } catch (RemoteException e) {
                    return ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
                }
            }
        }
        return ScanCallback.NO_ERROR;
    }

    /**
@@ -214,6 +261,25 @@ public final class BluetoothLeScanner {
        }
    }

    /**
     * Stops an ongoing Bluetooth LE scan started using a PendingIntent.
     * <p>
     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
     *
     * @param callbackIntent The PendingIntent that was used to start the scan.
     * @see #startScan(List, ScanSettings, PendingIntent)
     */
    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public void stopScan(PendingIntent callbackIntent) {
        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
        IBluetoothGatt gatt;
        try {
            gatt = mBluetoothManager.getBluetoothGatt();
            gatt.stopScanForIntent(callbackIntent, ActivityThread.currentOpPackageName());
        } catch (RemoteException e) {
        }
    }

    /**
     * Flush pending batch scan results stored in Bluetooth controller. This will return Bluetooth
     * LE scan results batched on bluetooth controller. Returns immediately, batch scan results data
@@ -252,7 +318,7 @@ public final class BluetoothLeScanner {
            scanFilters.add(filter.getFilter());
            scanStorages.add(filter.getStorageDescriptors());
        }
        startScan(scanFilters, settings, null, callback, scanStorages);
        startScan(scanFilters, settings, null, callback, null, scanStorages);
    }

    /**
@@ -295,7 +361,7 @@ public final class BluetoothLeScanner {
            mResultStorages = resultStorages;
        }

        public void startRegisteration() {
        public void startRegistration() {
            synchronized (this) {
                // Scan stopped.
                if (mScannerId == -1) return;
@@ -399,7 +465,6 @@ public final class BluetoothLeScanner {
                    mScanCallback.onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, scanResult);
                }
            });

        }

        @Override
@@ -453,6 +518,15 @@ public final class BluetoothLeScanner {
        }
    }

    private int postCallbackErrorOrReturn(final ScanCallback callback, final int errorCode) {
        if (callback == null) {
            return errorCode;
        } else {
            postCallbackError(callback, errorCode);
            return ScanCallback.NO_ERROR;
        }
    }

    private void postCallbackError(final ScanCallback callback, final int errorCode) {
        mHandler.post(new Runnable() {
            @Override
Loading