summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothAdapter.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothAdapter.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java121
1 files changed, 97 insertions, 24 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index c21ba6596e..d372a935e7 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -842,52 +842,106 @@ public final class BluetoothAdapter {
}
};
+ /** @hide */
+ @IntDef(value = {
+ BluetoothStatusCodes.ERROR_UNKNOWN,
+ BluetoothStatusCodes.FEATURE_NOT_SUPPORTED,
+ BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface BluetoothActivityEnergyInfoCallbackError {}
+
/**
- * Interface for Bluetooth activity energy info listener. Should be implemented by applications
- * and set when calling {@link BluetoothAdapter#requestControllerActivityEnergyInfo}.
+ * Interface for Bluetooth activity energy info callback. Should be implemented by applications
+ * and set when calling {@link #requestControllerActivityEnergyInfo}.
*
* @hide
*/
@SystemApi
- public interface OnBluetoothActivityEnergyInfoListener {
+ public interface OnBluetoothActivityEnergyInfoCallback {
/**
* Called when Bluetooth activity energy info is available.
- * Note: this listener is triggered at most once for each call to
+ * Note: this callback is triggered at most once for each call to
+ * {@link #requestControllerActivityEnergyInfo}.
+ *
+ * @param info the latest {@link BluetoothActivityEnergyInfo}
+ */
+ void onBluetoothActivityEnergyInfoAvailable(
+ @NonNull BluetoothActivityEnergyInfo info);
+
+ /**
+ * Called when the latest {@link BluetoothActivityEnergyInfo} can't be retrieved.
+ * The reason of the failure is indicated by the {@link BluetoothStatusCodes}
+ * passed as an argument to this method.
+ * Note: this callback is triggered at most once for each call to
* {@link #requestControllerActivityEnergyInfo}.
*
- * @param info the latest {@link BluetoothActivityEnergyInfo}, or null if unavailable.
+ * @param error code indicating the reason for the failure
*/
- void onBluetoothActivityEnergyInfo(@Nullable BluetoothActivityEnergyInfo info);
+ void onBluetoothActivityEnergyInfoError(
+ @BluetoothActivityEnergyInfoCallbackError int error);
}
private static class OnBluetoothActivityEnergyInfoProxy
extends IBluetoothActivityEnergyInfoListener.Stub {
private final Object mLock = new Object();
@Nullable @GuardedBy("mLock") private Executor mExecutor;
- @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoListener mListener;
+ @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoCallback mCallback;
OnBluetoothActivityEnergyInfoProxy(Executor executor,
- OnBluetoothActivityEnergyInfoListener listener) {
+ OnBluetoothActivityEnergyInfoCallback callback) {
mExecutor = executor;
- mListener = listener;
+ mCallback = callback;
}
@Override
public void onBluetoothActivityEnergyInfoAvailable(BluetoothActivityEnergyInfo info) {
Executor executor;
- OnBluetoothActivityEnergyInfoListener listener;
+ OnBluetoothActivityEnergyInfoCallback callback;
+ synchronized (mLock) {
+ if (mExecutor == null || mCallback == null) {
+ return;
+ }
+ executor = mExecutor;
+ callback = mCallback;
+ mExecutor = null;
+ mCallback = null;
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (info == null) {
+ executor.execute(() -> callback.onBluetoothActivityEnergyInfoError(
+ BluetoothStatusCodes.FEATURE_NOT_SUPPORTED));
+ } else {
+ executor.execute(() -> callback.onBluetoothActivityEnergyInfoAvailable(info));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Framework only method that is called when the service can't be reached.
+ */
+ public void onError(int errorCode) {
+ Executor executor;
+ OnBluetoothActivityEnergyInfoCallback callback;
synchronized (mLock) {
- if (mExecutor == null || mListener == null) {
+ if (mExecutor == null || mCallback == null) {
return;
}
executor = mExecutor;
- listener = mListener;
- // null out to allow garbage collection, prevent triggering listener more than once
+ callback = mCallback;
mExecutor = null;
- mListener = null;
+ mCallback = null;
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> callback.onBluetoothActivityEnergyInfoError(
+ errorCode));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- Binder.clearCallingIdentity();
- executor.execute(() -> listener.onBluetoothActivityEnergyInfo(info));
}
}
@@ -1895,6 +1949,7 @@ public final class BluetoothAdapter {
* @param mode represents the desired state of the local device scan mode
*
* @return status code indicating whether the scan mode was successfully set
+ * @throws IllegalArgumentException if the mode is not a valid scan mode
* @hide
*/
@SystemApi
@@ -1908,6 +1963,10 @@ public final class BluetoothAdapter {
if (getState() != STATE_ON) {
return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
}
+ if (mode != SCAN_MODE_NONE && mode != SCAN_MODE_CONNECTABLE
+ && mode != SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+ throw new IllegalArgumentException("Invalid scan mode param value");
+ }
try {
mServiceLock.readLock().lock();
if (mService != null) {
@@ -2776,12 +2835,12 @@ public final class BluetoothAdapter {
* has the activity and energy info. This can be used to ascertain what
* the controller has been up to, since the last sample.
*
- * A null value for the activity info object may be sent if the bluetooth service is
- * unreachable or the device does not support reporting such information.
+ * The callback will be called only once, when the record is available.
*
- * @param executor the executor that the listener will be invoked on
- * @param listener the listener that will receive the {@link BluetoothActivityEnergyInfo}
- * object when it becomes available
+ * @param executor the executor that the callback will be invoked on
+ * @param callback the callback that will be called with either the
+ * {@link BluetoothActivityEnergyInfo} object, or the
+ * error code if an error has occurred
* @hide
*/
@SystemApi
@@ -2792,18 +2851,23 @@ public final class BluetoothAdapter {
})
public void requestControllerActivityEnergyInfo(
@NonNull @CallbackExecutor Executor executor,
- @NonNull OnBluetoothActivityEnergyInfoListener listener) {
+ @NonNull OnBluetoothActivityEnergyInfoCallback callback) {
requireNonNull(executor, "executor cannot be null");
- requireNonNull(listener, "listener cannot be null");
+ requireNonNull(callback, "callback cannot be null");
+ OnBluetoothActivityEnergyInfoProxy proxy =
+ new OnBluetoothActivityEnergyInfoProxy(executor, callback);
try {
mServiceLock.readLock().lock();
if (mService != null) {
mService.requestActivityInfo(
- new OnBluetoothActivityEnergyInfoProxy(executor, listener),
+ proxy,
mAttributionSource);
+ } else {
+ proxy.onError(BluetoothStatusCodes.ERROR_PROFILE_SERVICE_NOT_BOUND);
}
} catch (RemoteException e) {
Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
+ proxy.onError(BluetoothStatusCodes.ERROR_UNKNOWN);
} finally {
mServiceLock.readLock().unlock();
}
@@ -3708,6 +3772,10 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.LE_CALL_CONTROL) {
BluetoothLeCallControl tbs = new BluetoothLeCallControl(context, listener);
return true;
+ } else if (profile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT) {
+ BluetoothLeBroadcastAssistant leAudioBroadcastAssistant =
+ new BluetoothLeBroadcastAssistant(context, listener);
+ return true;
} else {
return false;
}
@@ -3840,6 +3908,11 @@ public final class BluetoothAdapter {
BluetoothLeCallControl tbs = (BluetoothLeCallControl) proxy;
tbs.close();
break;
+ case BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT:
+ BluetoothLeBroadcastAssistant leAudioBroadcastAssistant =
+ (BluetoothLeBroadcastAssistant) proxy;
+ leAudioBroadcastAssistant.close();
+ break;
}
}