Loading core/java/android/bluetooth/BluetoothAdapter.java +91 −273 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.annotation.SdkConstant.SdkConstantType; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.Context; Loading Loading @@ -371,12 +373,14 @@ public final class BluetoothAdapter { */ private static BluetoothAdapter sAdapter; private static BluetoothLeScanner sBluetoothLeScanner; private static BluetoothLeAdvertiser sBluetoothLeAdvertiser; private final IBluetoothManager mManagerService; private IBluetooth mService; private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients; private final Handler mHandler; // Handler to post the advertise callback to run on main thread. private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; /** * Get a handle to the default local Bluetooth adapter. Loading Loading @@ -411,8 +415,7 @@ public final class BluetoothAdapter { mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) {Log.e(TAG, "", e);} mManagerService = managerService; mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>(); mHandler = new Handler(Looper.getMainLooper()); mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); } /** Loading Loading @@ -451,19 +454,40 @@ public final class BluetoothAdapter { } /** * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations. * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations, or * null if Bluetooth LE Advertising is not support on this device. * <p> * Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported * on this device before calling this method. */ public BluetoothLeAdvertiser getBluetoothLeAdvertiser() { // TODO: Return null if this feature is not supported by hardware. return new BluetoothLeAdvertiser(mManagerService); if (getState() != STATE_ON) { return null; } if (!isMultipleAdvertisementSupported()) { return null; } synchronized(mLock) { if (sBluetoothLeAdvertiser == null) { sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService); } } return sBluetoothLeAdvertiser; } /** * Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations. */ public BluetoothLeScanner getBluetoothLeScanner() { // TODO: Return null if BLE scan is not supported by hardware. return new BluetoothLeScanner(mManagerService); if (getState() != STATE_ON) { return null; } synchronized(mLock) { if (sBluetoothLeScanner == null) { sBluetoothLeScanner = new BluetoothLeScanner(mManagerService); } } return sBluetoothLeScanner; } /** Loading Loading @@ -1625,13 +1649,17 @@ public final class BluetoothAdapter { * instead. */ @Deprecated public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) { public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) { if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids); if (callback == null) { if (DBG) Log.e(TAG, "startLeScan: null callback"); return false; } BluetoothLeScanner scanner = getBluetoothLeScanner(); if (scanner == null) { if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner"); return false; } synchronized(mLeScanClients) { if (mLeScanClients.containsKey(callback)) { Loading @@ -1646,13 +1674,50 @@ public final class BluetoothAdapter { return false; } UUID uuid = UUID.randomUUID(); GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids); iGatt.registerClient(new ParcelUuid(uuid), wrapper); if (wrapper.scanStarted()) { mLeScanClients.put(callback, wrapper); return true; ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) { // Should not happen. Log.e(TAG, "LE Scan has already started"); return; } ScanRecord scanRecord = result.getScanRecord(); if (scanRecord == null) { return; } if (serviceUuids != null) { List<ParcelUuid> uuids = new ArrayList<ParcelUuid>(); for (UUID uuid : serviceUuids) { uuids.add(new ParcelUuid(uuid)); } List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids(); if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) { if (DBG) Log.d(TAG, "uuids does not match"); return; } } callback.onLeScan(result.getDevice(), result.getRssi(), scanRecord.getBytes()); } }; ScanSettings settings = new ScanSettings.Builder() .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); List<ScanFilter> filters = new ArrayList<ScanFilter>(); if (serviceUuids != null && serviceUuids.length > 0) { // Note scan filter does not support matching an UUID array so we put one // UUID to hardware and match the whole array in callback. ScanFilter filter = new ScanFilter.Builder().setServiceUuid( new ParcelUuid(serviceUuids[0])).build(); filters.add(filter); } scanner.startScan(filters, settings, scanCallback); mLeScanClients.put(callback, scanCallback); return true; } catch (RemoteException e) { Log.e(TAG,"",e); } Loading @@ -1672,264 +1737,17 @@ public final class BluetoothAdapter { @Deprecated public void stopLeScan(LeScanCallback callback) { if (DBG) Log.d(TAG, "stopLeScan()"); GattCallbackWrapper wrapper; synchronized(mLeScanClients) { wrapper = mLeScanClients.remove(callback); if (wrapper == null) return; } wrapper.stopLeScan(); } /** * Bluetooth GATT interface callbacks */ private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub { private static final int LE_CALLBACK_REG_TIMEOUT = 2000; private static final int LE_CALLBACK_REG_WAIT_COUNT = 5; private final LeScanCallback mLeScanCb; // mLeHandle 0: not registered // -1: scan stopped // >0: registered and scan started private int mLeHandle; private final UUID[] mScanFilter; private WeakReference<BluetoothAdapter> mBluetoothAdapter; public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb, UUID[] uuid) { mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter); mLeScanCb = leScanCb; mScanFilter = uuid; mLeHandle = 0; } public boolean scanStarted() { return waitForRegisteration(LE_CALLBACK_REG_WAIT_COUNT); } private boolean waitForRegisteration(int maxWaitCount) { boolean started = false; synchronized(this) { if (mLeHandle == -1) return false; int count = 0; // wait for callback registration and LE scan to start while (mLeHandle == 0 && count < maxWaitCount) { try { wait(LE_CALLBACK_REG_TIMEOUT); } catch (InterruptedException e) { Log.e(TAG, "Callback reg wait interrupted: " + e); } count++; } started = (mLeHandle > 0); } return started; } public void stopLeScan() { synchronized(this) { if (mLeHandle <= 0) { Log.e(TAG, "Error state, mLeHandle: " + mLeHandle); BluetoothLeScanner scanner = getBluetoothLeScanner(); if (scanner == null) { return; } BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter != null) { try { IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt(); iGatt.stopScan(mLeHandle, false); iGatt.unregisterClient(mLeHandle); } catch (RemoteException e) { Log.e(TAG, "Failed to stop scan and unregister" + e); } } else { Log.e(TAG, "stopLeScan, BluetoothAdapter is null"); } mLeHandle = -1; notifyAll(); } } /** * Application interface registered - app is ready to go */ public void onClientRegistered(int status, int clientIf) { if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf); synchronized(this) { if (mLeHandle == -1) { if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled"); } if (status == BluetoothGatt.GATT_SUCCESS) { mLeHandle = clientIf; IBluetoothGatt iGatt = null; try { BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter != null) { iGatt = adapter.getBluetoothManager().getBluetoothGatt(); if (mScanFilter == null) { iGatt.startScan(mLeHandle, false); } else { ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length]; for(int i = 0; i != uuids.length; ++i) { uuids[i] = new ParcelUuid(mScanFilter[i]); } iGatt.startScanWithUuids(mLeHandle, false, uuids); } } else { Log.e(TAG, "onClientRegistered, BluetoothAdapter null"); mLeHandle = -1; } } catch (RemoteException e) { Log.e(TAG, "fail to start le scan: " + e); mLeHandle = -1; } if (mLeHandle == -1) { // registration succeeded but start scan or advertise failed if (iGatt != null) { try { iGatt.unregisterClient(mLeHandle); } catch (RemoteException e) { Log.e(TAG, "fail to unregister callback: " + mLeHandle + " error: " + e); } } } } else { // registration failed mLeHandle = -1; } notifyAll(); } } public void onClientConnectionState(int status, int clientIf, boolean connected, String address) { // no op } /** * Callback reporting an LE scan result. * @hide */ public void onScanResult(String address, int rssi, byte[] advData) { if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); // Check null in case the scan has been stopped synchronized(this) { if (mLeHandle <= 0) return; } try { BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter == null) { Log.d(TAG, "onScanResult, BluetoothAdapter null"); synchronized (mLeScanClients) { ScanCallback scanCallback = mLeScanClients.remove(callback); if (scanCallback == null) { if (DBG) Log.d(TAG, "scan not started yet"); return; } mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } } public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid) { // no op } public void onGetIncludedService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int inclSrvcType, int inclSrvcInstId, ParcelUuid inclSrvcUuid) { // no op } public void onGetCharacteristic(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int charProps) { // no op } public void onGetDescriptor(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descUuid) { // no op } public void onSearchComplete(String address, int status) { // no op } public void onCharacteristicRead(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value) { // no op } public void onCharacteristicWrite(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid) { // no op } public void onNotify(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value) { // no op } public void onDescriptorRead(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descrUuid, byte[] value) { // no op } public void onDescriptorWrite(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descrUuid) { // no op } public void onExecuteWrite(String address, int status) { // no op } public void onReadRemoteRssi(String address, int rssi, int status) { // no op } public void onAdvertiseStateChange(int advertiseState, int status) { } @Override public void onMultiAdvertiseCallback(int status) { // no op } @Override public void onConfigureMTU(String address, int mtu, int status) { // no op } @Override public void onConnectionCongested(String address, boolean congested) { // no op } @Override public void onBatchScanResults(List<ScanResult> results) { // no op } @Override public void onFoundOrLost(boolean onFound, String address,int rssi, byte[] advData) { // no op scanner.stopScan(scanCallback); } } } core/java/android/bluetooth/IBluetoothGatt.aidl +2 −4 Original line number Diff line number Diff line Loading @@ -33,10 +33,8 @@ import android.bluetooth.IBluetoothGattServerCallback; interface IBluetoothGatt { List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states); void startScan(in int appIf, in boolean isServer); void startScanWithUuids(in int appIf, in boolean isServer, in ParcelUuid[] ids); void startScanWithFilters(in int appIf, in boolean isServer, in ScanSettings settings, in List<ScanFilter> filters); void startScan(in int appIf, in boolean isServer, in ScanSettings settings, in List<ScanFilter> filters); void stopScan(in int appIf, in boolean isServer); void flushPendingBatchResults(in int appIf, in boolean isServer); void startMultiAdvertising(in int appIf, Loading core/java/android/bluetooth/le/BluetoothLeScanner.java +2 −1 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ public final class BluetoothLeScanner { synchronized (mLeScanClients) { BleScanCallbackWrapper wrapper = mLeScanClients.remove(callback); if (wrapper == null) { if (DBG) Log.d(TAG, "could not find callback wrapper"); return; } wrapper.stopLeScan(); Loading Loading @@ -266,7 +267,7 @@ public final class BluetoothLeScanner { if (status == BluetoothGatt.GATT_SUCCESS) { mClientIf = clientIf; try { mBluetoothGatt.startScanWithFilters(mClientIf, false, mSettings, mFilters); mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters); } catch (RemoteException e) { Log.e(TAG, "fail to start le scan: " + e); mClientIf = -1; Loading Loading
core/java/android/bluetooth/BluetoothAdapter.java +91 −273 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.annotation.SdkConstant.SdkConstantType; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanRecord; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.Context; Loading Loading @@ -371,12 +373,14 @@ public final class BluetoothAdapter { */ private static BluetoothAdapter sAdapter; private static BluetoothLeScanner sBluetoothLeScanner; private static BluetoothLeAdvertiser sBluetoothLeAdvertiser; private final IBluetoothManager mManagerService; private IBluetooth mService; private final Map<LeScanCallback, GattCallbackWrapper> mLeScanClients; private final Handler mHandler; // Handler to post the advertise callback to run on main thread. private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; /** * Get a handle to the default local Bluetooth adapter. Loading Loading @@ -411,8 +415,7 @@ public final class BluetoothAdapter { mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) {Log.e(TAG, "", e);} mManagerService = managerService; mLeScanClients = new HashMap<LeScanCallback, GattCallbackWrapper>(); mHandler = new Handler(Looper.getMainLooper()); mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); } /** Loading Loading @@ -451,19 +454,40 @@ public final class BluetoothAdapter { } /** * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations. * Returns a {@link BluetoothLeAdvertiser} object for Bluetooth LE Advertising operations, or * null if Bluetooth LE Advertising is not support on this device. * <p> * Use {@link #isMultipleAdvertisementSupported()} to check whether LE Advertising is supported * on this device before calling this method. */ public BluetoothLeAdvertiser getBluetoothLeAdvertiser() { // TODO: Return null if this feature is not supported by hardware. return new BluetoothLeAdvertiser(mManagerService); if (getState() != STATE_ON) { return null; } if (!isMultipleAdvertisementSupported()) { return null; } synchronized(mLock) { if (sBluetoothLeAdvertiser == null) { sBluetoothLeAdvertiser = new BluetoothLeAdvertiser(mManagerService); } } return sBluetoothLeAdvertiser; } /** * Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations. */ public BluetoothLeScanner getBluetoothLeScanner() { // TODO: Return null if BLE scan is not supported by hardware. return new BluetoothLeScanner(mManagerService); if (getState() != STATE_ON) { return null; } synchronized(mLock) { if (sBluetoothLeScanner == null) { sBluetoothLeScanner = new BluetoothLeScanner(mManagerService); } } return sBluetoothLeScanner; } /** Loading Loading @@ -1625,13 +1649,17 @@ public final class BluetoothAdapter { * instead. */ @Deprecated public boolean startLeScan(UUID[] serviceUuids, LeScanCallback callback) { public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) { if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids); if (callback == null) { if (DBG) Log.e(TAG, "startLeScan: null callback"); return false; } BluetoothLeScanner scanner = getBluetoothLeScanner(); if (scanner == null) { if (DBG) Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner"); return false; } synchronized(mLeScanClients) { if (mLeScanClients.containsKey(callback)) { Loading @@ -1646,13 +1674,50 @@ public final class BluetoothAdapter { return false; } UUID uuid = UUID.randomUUID(); GattCallbackWrapper wrapper = new GattCallbackWrapper(this, callback, serviceUuids); iGatt.registerClient(new ParcelUuid(uuid), wrapper); if (wrapper.scanStarted()) { mLeScanClients.put(callback, wrapper); return true; ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) { // Should not happen. Log.e(TAG, "LE Scan has already started"); return; } ScanRecord scanRecord = result.getScanRecord(); if (scanRecord == null) { return; } if (serviceUuids != null) { List<ParcelUuid> uuids = new ArrayList<ParcelUuid>(); for (UUID uuid : serviceUuids) { uuids.add(new ParcelUuid(uuid)); } List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids(); if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) { if (DBG) Log.d(TAG, "uuids does not match"); return; } } callback.onLeScan(result.getDevice(), result.getRssi(), scanRecord.getBytes()); } }; ScanSettings settings = new ScanSettings.Builder() .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES) .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build(); List<ScanFilter> filters = new ArrayList<ScanFilter>(); if (serviceUuids != null && serviceUuids.length > 0) { // Note scan filter does not support matching an UUID array so we put one // UUID to hardware and match the whole array in callback. ScanFilter filter = new ScanFilter.Builder().setServiceUuid( new ParcelUuid(serviceUuids[0])).build(); filters.add(filter); } scanner.startScan(filters, settings, scanCallback); mLeScanClients.put(callback, scanCallback); return true; } catch (RemoteException e) { Log.e(TAG,"",e); } Loading @@ -1672,264 +1737,17 @@ public final class BluetoothAdapter { @Deprecated public void stopLeScan(LeScanCallback callback) { if (DBG) Log.d(TAG, "stopLeScan()"); GattCallbackWrapper wrapper; synchronized(mLeScanClients) { wrapper = mLeScanClients.remove(callback); if (wrapper == null) return; } wrapper.stopLeScan(); } /** * Bluetooth GATT interface callbacks */ private static class GattCallbackWrapper extends IBluetoothGattCallback.Stub { private static final int LE_CALLBACK_REG_TIMEOUT = 2000; private static final int LE_CALLBACK_REG_WAIT_COUNT = 5; private final LeScanCallback mLeScanCb; // mLeHandle 0: not registered // -1: scan stopped // >0: registered and scan started private int mLeHandle; private final UUID[] mScanFilter; private WeakReference<BluetoothAdapter> mBluetoothAdapter; public GattCallbackWrapper(BluetoothAdapter bluetoothAdapter, LeScanCallback leScanCb, UUID[] uuid) { mBluetoothAdapter = new WeakReference<BluetoothAdapter>(bluetoothAdapter); mLeScanCb = leScanCb; mScanFilter = uuid; mLeHandle = 0; } public boolean scanStarted() { return waitForRegisteration(LE_CALLBACK_REG_WAIT_COUNT); } private boolean waitForRegisteration(int maxWaitCount) { boolean started = false; synchronized(this) { if (mLeHandle == -1) return false; int count = 0; // wait for callback registration and LE scan to start while (mLeHandle == 0 && count < maxWaitCount) { try { wait(LE_CALLBACK_REG_TIMEOUT); } catch (InterruptedException e) { Log.e(TAG, "Callback reg wait interrupted: " + e); } count++; } started = (mLeHandle > 0); } return started; } public void stopLeScan() { synchronized(this) { if (mLeHandle <= 0) { Log.e(TAG, "Error state, mLeHandle: " + mLeHandle); BluetoothLeScanner scanner = getBluetoothLeScanner(); if (scanner == null) { return; } BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter != null) { try { IBluetoothGatt iGatt = adapter.getBluetoothManager().getBluetoothGatt(); iGatt.stopScan(mLeHandle, false); iGatt.unregisterClient(mLeHandle); } catch (RemoteException e) { Log.e(TAG, "Failed to stop scan and unregister" + e); } } else { Log.e(TAG, "stopLeScan, BluetoothAdapter is null"); } mLeHandle = -1; notifyAll(); } } /** * Application interface registered - app is ready to go */ public void onClientRegistered(int status, int clientIf) { if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf); synchronized(this) { if (mLeHandle == -1) { if (DBG) Log.d(TAG, "onClientRegistered LE scan canceled"); } if (status == BluetoothGatt.GATT_SUCCESS) { mLeHandle = clientIf; IBluetoothGatt iGatt = null; try { BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter != null) { iGatt = adapter.getBluetoothManager().getBluetoothGatt(); if (mScanFilter == null) { iGatt.startScan(mLeHandle, false); } else { ParcelUuid[] uuids = new ParcelUuid[mScanFilter.length]; for(int i = 0; i != uuids.length; ++i) { uuids[i] = new ParcelUuid(mScanFilter[i]); } iGatt.startScanWithUuids(mLeHandle, false, uuids); } } else { Log.e(TAG, "onClientRegistered, BluetoothAdapter null"); mLeHandle = -1; } } catch (RemoteException e) { Log.e(TAG, "fail to start le scan: " + e); mLeHandle = -1; } if (mLeHandle == -1) { // registration succeeded but start scan or advertise failed if (iGatt != null) { try { iGatt.unregisterClient(mLeHandle); } catch (RemoteException e) { Log.e(TAG, "fail to unregister callback: " + mLeHandle + " error: " + e); } } } } else { // registration failed mLeHandle = -1; } notifyAll(); } } public void onClientConnectionState(int status, int clientIf, boolean connected, String address) { // no op } /** * Callback reporting an LE scan result. * @hide */ public void onScanResult(String address, int rssi, byte[] advData) { if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi); // Check null in case the scan has been stopped synchronized(this) { if (mLeHandle <= 0) return; } try { BluetoothAdapter adapter = mBluetoothAdapter.get(); if (adapter == null) { Log.d(TAG, "onScanResult, BluetoothAdapter null"); synchronized (mLeScanClients) { ScanCallback scanCallback = mLeScanClients.remove(callback); if (scanCallback == null) { if (DBG) Log.d(TAG, "scan not started yet"); return; } mLeScanCb.onLeScan(adapter.getRemoteDevice(address), rssi, advData); } catch (Exception ex) { Log.w(TAG, "Unhandled exception: " + ex); } } public void onGetService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid) { // no op } public void onGetIncludedService(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int inclSrvcType, int inclSrvcInstId, ParcelUuid inclSrvcUuid) { // no op } public void onGetCharacteristic(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int charProps) { // no op } public void onGetDescriptor(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descUuid) { // no op } public void onSearchComplete(String address, int status) { // no op } public void onCharacteristicRead(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value) { // no op } public void onCharacteristicWrite(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid) { // no op } public void onNotify(String address, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, byte[] value) { // no op } public void onDescriptorRead(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descrUuid, byte[] value) { // no op } public void onDescriptorWrite(String address, int status, int srvcType, int srvcInstId, ParcelUuid srvcUuid, int charInstId, ParcelUuid charUuid, int descInstId, ParcelUuid descrUuid) { // no op } public void onExecuteWrite(String address, int status) { // no op } public void onReadRemoteRssi(String address, int rssi, int status) { // no op } public void onAdvertiseStateChange(int advertiseState, int status) { } @Override public void onMultiAdvertiseCallback(int status) { // no op } @Override public void onConfigureMTU(String address, int mtu, int status) { // no op } @Override public void onConnectionCongested(String address, boolean congested) { // no op } @Override public void onBatchScanResults(List<ScanResult> results) { // no op } @Override public void onFoundOrLost(boolean onFound, String address,int rssi, byte[] advData) { // no op scanner.stopScan(scanCallback); } } }
core/java/android/bluetooth/IBluetoothGatt.aidl +2 −4 Original line number Diff line number Diff line Loading @@ -33,10 +33,8 @@ import android.bluetooth.IBluetoothGattServerCallback; interface IBluetoothGatt { List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states); void startScan(in int appIf, in boolean isServer); void startScanWithUuids(in int appIf, in boolean isServer, in ParcelUuid[] ids); void startScanWithFilters(in int appIf, in boolean isServer, in ScanSettings settings, in List<ScanFilter> filters); void startScan(in int appIf, in boolean isServer, in ScanSettings settings, in List<ScanFilter> filters); void stopScan(in int appIf, in boolean isServer); void flushPendingBatchResults(in int appIf, in boolean isServer); void startMultiAdvertising(in int appIf, Loading
core/java/android/bluetooth/le/BluetoothLeScanner.java +2 −1 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ public final class BluetoothLeScanner { synchronized (mLeScanClients) { BleScanCallbackWrapper wrapper = mLeScanClients.remove(callback); if (wrapper == null) { if (DBG) Log.d(TAG, "could not find callback wrapper"); return; } wrapper.stopLeScan(); Loading Loading @@ -266,7 +267,7 @@ public final class BluetoothLeScanner { if (status == BluetoothGatt.GATT_SUCCESS) { mClientIf = clientIf; try { mBluetoothGatt.startScanWithFilters(mClientIf, false, mSettings, mFilters); mBluetoothGatt.startScan(mClientIf, false, mSettings, mFilters); } catch (RemoteException e) { Log.e(TAG, "fail to start le scan: " + e); mClientIf = -1; Loading