Merge "Separate advertiser from GATT client (1/4)" am: 5f87c4539a
am: 40a16ea242
Change-Id: I0d08f623e78fdd779b39083d0da3a45aee72ff3c
This commit is contained in:
@@ -125,6 +125,7 @@ LOCAL_SRC_FILES += \
|
|||||||
core/java/android/bluetooth/IBluetoothGatt.aidl \
|
core/java/android/bluetooth/IBluetoothGatt.aidl \
|
||||||
core/java/android/bluetooth/IBluetoothGattCallback.aidl \
|
core/java/android/bluetooth/IBluetoothGattCallback.aidl \
|
||||||
core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
|
core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
|
||||||
|
core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
|
||||||
core/java/android/content/IClipboard.aidl \
|
core/java/android/content/IClipboard.aidl \
|
||||||
core/java/android/content/IContentService.aidl \
|
core/java/android/content/IContentService.aidl \
|
||||||
core/java/android/content/IIntentReceiver.aidl \
|
core/java/android/content/IIntentReceiver.aidl \
|
||||||
|
|||||||
@@ -82,11 +82,6 @@ public class BluetoothGattCallbackWrapper extends IBluetoothGattCallback.Stub {
|
|||||||
public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
|
public void onReadRemoteRssi(String address, int rssi, int status) throws RemoteException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMultiAdvertiseCallback(int status, boolean isStart,
|
|
||||||
AdvertiseSettings advertiseSettings) throws RemoteException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
|
public void onConfigureMTU(String address, int mtu, int status) throws RemoteException {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.os.WorkSource;
|
|||||||
|
|
||||||
import android.bluetooth.IBluetoothGattCallback;
|
import android.bluetooth.IBluetoothGattCallback;
|
||||||
import android.bluetooth.IBluetoothGattServerCallback;
|
import android.bluetooth.IBluetoothGattServerCallback;
|
||||||
|
import android.bluetooth.le.IAdvertiserCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API for interacting with BLE / GATT
|
* API for interacting with BLE / GATT
|
||||||
@@ -41,11 +42,15 @@ interface IBluetoothGatt {
|
|||||||
in String callingPackage);
|
in String callingPackage);
|
||||||
void stopScan(in int appIf, in boolean isServer);
|
void stopScan(in int appIf, in boolean isServer);
|
||||||
void flushPendingBatchResults(in int appIf, in boolean isServer);
|
void flushPendingBatchResults(in int appIf, in boolean isServer);
|
||||||
void startMultiAdvertising(in int appIf,
|
|
||||||
|
void registerAdvertiser(in IAdvertiserCallback callback);
|
||||||
|
void unregisterAdvertiser(in int advertiserId);
|
||||||
|
void startMultiAdvertising(in int advertiserId,
|
||||||
in AdvertiseData advertiseData,
|
in AdvertiseData advertiseData,
|
||||||
in AdvertiseData scanResponse,
|
in AdvertiseData scanResponse,
|
||||||
in AdvertiseSettings settings);
|
in AdvertiseSettings settings);
|
||||||
void stopMultiAdvertising(in int appIf);
|
void stopMultiAdvertising(in int advertiserId);
|
||||||
|
|
||||||
void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
|
void registerClient(in ParcelUuid appId, in IBluetoothGattCallback callback);
|
||||||
void unregisterClient(in int clientIf);
|
void unregisterClient(in int clientIf);
|
||||||
void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport);
|
void clientConnect(in int clientIf, in String address, in boolean isDirect, in int transport);
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ oneway interface IBluetoothGattCallback {
|
|||||||
void onDescriptorWrite(in String address, in int status, in int handle);
|
void onDescriptorWrite(in String address, in int status, in int handle);
|
||||||
void onNotify(in String address, in int handle, in byte[] value);
|
void onNotify(in String address, in int handle, in byte[] value);
|
||||||
void onReadRemoteRssi(in String address, in int rssi, in int status);
|
void onReadRemoteRssi(in String address, in int rssi, in int status);
|
||||||
void onMultiAdvertiseCallback(in int status, boolean isStart,
|
|
||||||
in AdvertiseSettings advertiseSettings);
|
|
||||||
void onScanManagerErrorCallback(in int errorCode);
|
void onScanManagerErrorCallback(in int errorCode);
|
||||||
void onConfigureMTU(in String address, in int mtu, in int status);
|
void onConfigureMTU(in String address, in int mtu, in int status);
|
||||||
void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
|
void onFoundOrLost(in boolean onFound, in ScanResult scanResult);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothGattCallbackWrapper;
|
|||||||
import android.bluetooth.BluetoothUuid;
|
import android.bluetooth.BluetoothUuid;
|
||||||
import android.bluetooth.IBluetoothGatt;
|
import android.bluetooth.IBluetoothGatt;
|
||||||
import android.bluetooth.IBluetoothManager;
|
import android.bluetooth.IBluetoothManager;
|
||||||
|
import android.bluetooth.le.IAdvertiserCallback;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.ParcelUuid;
|
import android.os.ParcelUuid;
|
||||||
@@ -162,7 +163,7 @@ public final class BluetoothLeAdvertiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up advertise clients. Should be called when bluetooth is down.
|
* Cleans up advertisers. Should be called when bluetooth is down.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@@ -228,7 +229,7 @@ public final class BluetoothLeAdvertiser {
|
|||||||
/**
|
/**
|
||||||
* Bluetooth GATT interface callbacks for advertising.
|
* Bluetooth GATT interface callbacks for advertising.
|
||||||
*/
|
*/
|
||||||
private class AdvertiseCallbackWrapper extends BluetoothGattCallbackWrapper {
|
private class AdvertiseCallbackWrapper extends IAdvertiserCallback.Stub {
|
||||||
private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
|
private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
|
||||||
private final AdvertiseCallback mAdvertiseCallback;
|
private final AdvertiseCallback mAdvertiseCallback;
|
||||||
private final AdvertiseData mAdvertisement;
|
private final AdvertiseData mAdvertisement;
|
||||||
@@ -236,10 +237,10 @@ public final class BluetoothLeAdvertiser {
|
|||||||
private final AdvertiseSettings mSettings;
|
private final AdvertiseSettings mSettings;
|
||||||
private final IBluetoothGatt mBluetoothGatt;
|
private final IBluetoothGatt mBluetoothGatt;
|
||||||
|
|
||||||
// mClientIf 0: not registered
|
// mAdvertiserId 0: not registered
|
||||||
// -1: advertise stopped or registration timeout
|
// -1: advertise stopped or registration timeout
|
||||||
// >0: registered and advertising started
|
// >0: registered and advertising started
|
||||||
private int mClientIf;
|
private int mAdvertiserId;
|
||||||
private boolean mIsAdvertising = false;
|
private boolean mIsAdvertising = false;
|
||||||
|
|
||||||
public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
|
public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
|
||||||
@@ -251,35 +252,34 @@ public final class BluetoothLeAdvertiser {
|
|||||||
mScanResponse = scanResponse;
|
mScanResponse = scanResponse;
|
||||||
mSettings = settings;
|
mSettings = settings;
|
||||||
mBluetoothGatt = bluetoothGatt;
|
mBluetoothGatt = bluetoothGatt;
|
||||||
mClientIf = 0;
|
mAdvertiserId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startRegisteration() {
|
public void startRegisteration() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (mClientIf == -1) return;
|
if (mAdvertiserId == -1) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UUID uuid = UUID.randomUUID();
|
mBluetoothGatt.registerAdvertiser(this);
|
||||||
mBluetoothGatt.registerClient(new ParcelUuid(uuid), this);
|
|
||||||
wait(LE_CALLBACK_TIMEOUT_MILLIS);
|
wait(LE_CALLBACK_TIMEOUT_MILLIS);
|
||||||
} catch (InterruptedException | RemoteException e) {
|
} catch (InterruptedException | RemoteException e) {
|
||||||
Log.e(TAG, "Failed to start registeration", e);
|
Log.e(TAG, "Failed to start registeration", e);
|
||||||
}
|
}
|
||||||
if (mClientIf > 0 && mIsAdvertising) {
|
if (mAdvertiserId > 0 && mIsAdvertising) {
|
||||||
mLeAdvertisers.put(mAdvertiseCallback, this);
|
mLeAdvertisers.put(mAdvertiseCallback, this);
|
||||||
} else if (mClientIf <= 0) {
|
} else if (mAdvertiserId <= 0) {
|
||||||
|
|
||||||
// Registration timeout, reset mClientIf to -1 so no subsequent operations can
|
// Registration timeout, reset mClientIf to -1 so no subsequent operations can
|
||||||
// proceed.
|
// proceed.
|
||||||
if (mClientIf == 0) mClientIf = -1;
|
if (mAdvertiserId == 0) mAdvertiserId = -1;
|
||||||
// Post internal error if registration failed.
|
// Post internal error if registration failed.
|
||||||
postStartFailure(mAdvertiseCallback,
|
postStartFailure(mAdvertiseCallback,
|
||||||
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
|
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
|
||||||
} else {
|
} else {
|
||||||
// Unregister application if it's already registered but advertise failed.
|
// Unregister application if it's already registered but advertise failed.
|
||||||
try {
|
try {
|
||||||
mBluetoothGatt.unregisterClient(mClientIf);
|
mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
|
||||||
mClientIf = -1;
|
mAdvertiserId = -1;
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "remote exception when unregistering", e);
|
Log.e(TAG, "remote exception when unregistering", e);
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ public final class BluetoothLeAdvertiser {
|
|||||||
public void stopAdvertising() {
|
public void stopAdvertising() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
try {
|
try {
|
||||||
mBluetoothGatt.stopMultiAdvertising(mClientIf);
|
mBluetoothGatt.stopMultiAdvertising(mAdvertiserId);
|
||||||
wait(LE_CALLBACK_TIMEOUT_MILLIS);
|
wait(LE_CALLBACK_TIMEOUT_MILLIS);
|
||||||
} catch (InterruptedException | RemoteException e) {
|
} catch (InterruptedException | RemoteException e) {
|
||||||
Log.e(TAG, "Failed to stop advertising", e);
|
Log.e(TAG, "Failed to stop advertising", e);
|
||||||
@@ -305,20 +305,20 @@ public final class BluetoothLeAdvertiser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Application interface registered - app is ready to go
|
* Advertiser interface registered - app is ready to go
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onClientRegistered(int status, int clientIf) {
|
public void onAdvertiserRegistered(int status, int advertiserId) {
|
||||||
Log.d(TAG, "onClientRegistered() - status=" + status + " clientIf=" + clientIf);
|
Log.d(TAG, "onAdvertiserRegistered() - status=" + status + " advertiserId=" + advertiserId);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
try {
|
try {
|
||||||
if (mClientIf == -1) {
|
if (mAdvertiserId == -1) {
|
||||||
// Registration succeeds after timeout, unregister client.
|
// Registration succeeds after timeout, unregister advertiser.
|
||||||
mBluetoothGatt.unregisterClient(clientIf);
|
mBluetoothGatt.unregisterAdvertiser(advertiserId);
|
||||||
} else {
|
} else {
|
||||||
mClientIf = clientIf;
|
mAdvertiserId = advertiserId;
|
||||||
mBluetoothGatt.startMultiAdvertising(mClientIf, mAdvertisement,
|
mBluetoothGatt.startMultiAdvertising(mAdvertiserId, mAdvertisement,
|
||||||
mScanResponse, mSettings);
|
mScanResponse, mSettings);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -327,7 +327,7 @@ public final class BluetoothLeAdvertiser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Registration failed.
|
// Registration failed.
|
||||||
mClientIf = -1;
|
mAdvertiserId = -1;
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,10 +346,10 @@ public final class BluetoothLeAdvertiser {
|
|||||||
postStartFailure(mAdvertiseCallback, status);
|
postStartFailure(mAdvertiseCallback, status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// unregister client for stop.
|
// unregister advertiser for stop.
|
||||||
try {
|
try {
|
||||||
mBluetoothGatt.unregisterClient(mClientIf);
|
mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
|
||||||
mClientIf = -1;
|
mAdvertiserId = -1;
|
||||||
mIsAdvertising = false;
|
mIsAdvertising = false;
|
||||||
mLeAdvertisers.remove(mAdvertiseCallback);
|
mLeAdvertisers.remove(mAdvertiseCallback);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
|||||||
29
core/java/android/bluetooth/le/IAdvertiserCallback.aidl
Normal file
29
core/java/android/bluetooth/le/IAdvertiserCallback.aidl
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package android.bluetooth.le;
|
||||||
|
|
||||||
|
import android.bluetooth.le.AdvertiseSettings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback definitions for interacting with Advertiser
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
oneway interface IAdvertiserCallback {
|
||||||
|
void onAdvertiserRegistered(in int status, in int advertiserId);
|
||||||
|
|
||||||
|
void onMultiAdvertiseCallback(in int status, boolean isStart,
|
||||||
|
in AdvertiseSettings advertiseSettings);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user