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.java161
1 files changed, 114 insertions, 47 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index 6605a2e5f3..6b4c8062b6 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -59,7 +59,6 @@ import android.os.IBinder;
import android.os.IpcDataCache;
import android.os.ParcelUuid;
import android.os.RemoteException;
-import android.os.ResultReceiver;
import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Pair;
@@ -192,6 +191,16 @@ public final class BluetoothAdapter {
STATE_BLE_TURNING_OFF
})
@Retention(RetentionPolicy.SOURCE)
+ public @interface InternalAdapterState {}
+
+ /** @hide */
+ @IntDef(prefix = { "STATE_" }, value = {
+ STATE_OFF,
+ STATE_TURNING_ON,
+ STATE_ON,
+ STATE_TURNING_OFF,
+ })
+ @Retention(RetentionPolicy.SOURCE)
public @interface AdapterState {}
/**
@@ -272,14 +281,14 @@ public final class BluetoothAdapter {
public @interface RfcommListenerResult {}
/**
- * Human-readable string helper for AdapterState
+ * Human-readable string helper for AdapterState and InternalAdapterState
*
* @hide
*/
@SystemApi
@RequiresNoPermission
@NonNull
- public static String nameForState(@AdapterState int state) {
+ public static String nameForState(@InternalAdapterState int state) {
switch (state) {
case STATE_OFF:
return "OFF";
@@ -741,6 +750,16 @@ public final class BluetoothAdapter {
3; //BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING;
/** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "STATE_" }, value = {
+ STATE_DISCONNECTED,
+ STATE_CONNECTING,
+ STATE_CONNECTED,
+ STATE_DISCONNECTING,
+ })
+ public @interface ConnectionState {}
+
+ /** @hide */
public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
private final IBinder mToken;
@@ -824,6 +843,55 @@ public final class BluetoothAdapter {
};
/**
+ * Interface for Bluetooth activity energy info listener. Should be implemented by applications
+ * and set when calling {@link BluetoothAdapter#requestControllerActivityEnergyInfo}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface OnBluetoothActivityEnergyInfoListener {
+ /**
+ * Called when Bluetooth activity energy info is available.
+ * Note: this listener is triggered at most once for each call to
+ * {@link #requestControllerActivityEnergyInfo}.
+ *
+ * @param info the latest {@link BluetoothActivityEnergyInfo}, or null if unavailable.
+ */
+ void onBluetoothActivityEnergyInfo(@Nullable BluetoothActivityEnergyInfo info);
+ }
+
+ 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;
+
+ OnBluetoothActivityEnergyInfoProxy(Executor executor,
+ OnBluetoothActivityEnergyInfoListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onBluetoothActivityEnergyInfoAvailable(BluetoothActivityEnergyInfo info) {
+ Executor executor;
+ OnBluetoothActivityEnergyInfoListener listener;
+ synchronized (mLock) {
+ if (mExecutor == null || mListener == null) {
+ return;
+ }
+ executor = mExecutor;
+ listener = mListener;
+ // null out to allow garbage collection, prevent triggering listener more than once
+ mExecutor = null;
+ mListener = null;
+ }
+ Binder.clearCallingIdentity();
+ executor.execute(() -> listener.onBluetoothActivityEnergyInfo(info));
+ }
+ }
+
+ /**
* Get a handle to the default local Bluetooth adapter.
* <p>
* Currently Android only supports one Bluetooth adapter, but the API could
@@ -1155,9 +1223,8 @@ public final class BluetoothAdapter {
new IpcDataCache.QueryHandler<>() {
@RequiresLegacyBluetoothPermission
@RequiresNoPermission
- @AdapterState
@Override
- public Integer apply(Void query) {
+ public @InternalAdapterState Integer apply(Void query) {
int state = BluetoothAdapter.STATE_OFF;
mServiceLock.readLock().lock();
try {
@@ -1193,8 +1260,7 @@ public final class BluetoothAdapter {
* Fetch the current bluetooth state. If the service is down, return
* OFF.
*/
- @AdapterState
- private int getStateInternal() {
+ private @InternalAdapterState int getStateInternal() {
return mBluetoothGetStateCache.query(null);
}
@@ -1210,8 +1276,7 @@ public final class BluetoothAdapter {
*/
@RequiresLegacyBluetoothPermission
@RequiresNoPermission
- @AdapterState
- public int getState() {
+ public @AdapterState int getState() {
android.util.SeempLog.record(63);
int state = getStateInternal();
@@ -1248,10 +1313,9 @@ public final class BluetoothAdapter {
*/
@RequiresLegacyBluetoothPermission
@RequiresNoPermission
- @AdapterState
@UnsupportedAppUsage(publicAlternatives = "Use {@link #getState()} instead to determine "
+ "whether you can use BLE & BT classic.")
- public int getLeState() {
+ public @InternalAdapterState int getLeState() {
int state = getStateInternal();
if (VDBG) {
@@ -1490,31 +1554,40 @@ public final class BluetoothAdapter {
* @return the UUIDs supported by the local Bluetooth Adapter.
* @hide
*/
- @SystemApi
+ @UnsupportedAppUsage
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @SuppressLint(value = {"ArrayReturn", "NullableCollection"})
public @NonNull ParcelUuid[] getUuids() {
- if (getState() != STATE_ON) {
- return new ParcelUuid[0];
+ List<ParcelUuid> parcels = getUuidsList();
+ return parcels.toArray(new ParcelUuid[parcels.size()]);
+ }
+
+ /**
+ * Get the UUIDs supported by the local Bluetooth adapter.
+ *
+ * @return a list of the UUIDs supported by the local Bluetooth Adapter.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public @NonNull List<ParcelUuid> getUuidsList() {
+ List<ParcelUuid> defaultValue = new ArrayList<>();
+ if (getState() != STATE_ON || mService == null) {
+ return defaultValue;
}
+ mServiceLock.readLock().lock();
try {
- mServiceLock.readLock().lock();
- if (mService != null) {
- final SynchronousResultReceiver<List<ParcelUuid>> recv =
- new SynchronousResultReceiver();
- mService.getUuids(mAttributionSource, recv);
- List<ParcelUuid> parcels = recv.awaitResultNoInterrupt(getSyncTimeout())
- .getValue(new ArrayList<>());
- return parcels.toArray(new ParcelUuid[parcels.size()]);
- }
+ final SynchronousResultReceiver<List<ParcelUuid>> recv =
+ new SynchronousResultReceiver();
+ mService.getUuids(mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
} finally {
mServiceLock.readLock().unlock();
}
- return new ParcelUuid[0];
+ return defaultValue;
}
/**
@@ -2690,7 +2763,9 @@ public final class BluetoothAdapter {
* 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.
*
- * @param result The callback to which to send the activity info.
+ * @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
* @hide
*/
@SystemApi
@@ -2699,22 +2774,22 @@ public final class BluetoothAdapter {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public void requestControllerActivityEnergyInfo(@NonNull ResultReceiver result) {
- requireNonNull(result, "ResultReceiver cannot be null");
+ public void requestControllerActivityEnergyInfo(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnBluetoothActivityEnergyInfoListener listener) {
+ requireNonNull(executor, "executor cannot be null");
+ requireNonNull(listener, "listener cannot be null");
try {
mServiceLock.readLock().lock();
if (mService != null) {
- mService.requestActivityInfo(result, mAttributionSource);
- result = null;
+ mService.requestActivityInfo(
+ new OnBluetoothActivityEnergyInfoProxy(executor, listener),
+ mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
} finally {
mServiceLock.readLock().unlock();
- if (result != null) {
- // Only send an immediate result if we failed.
- result.send(0, null);
- }
}
}
@@ -2887,13 +2962,12 @@ public final class BluetoothAdapter {
* <p> Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED}
* intent to get the connection state of the adapter.
*
- * @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED}, {@link
- * #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
+ * @return the connection state
* @hide
*/
@SystemApi
@RequiresNoPermission
- public int getConnectionState() {
+ public @ConnectionState int getConnectionState() {
if (getState() != STATE_ON) {
return BluetoothAdapter.STATE_DISCONNECTED;
}
@@ -2949,17 +3023,13 @@ public final class BluetoothAdapter {
* is connected to any remote device for a specific profile.
* Profile can be one of {@link BluetoothProfile#HEADSET}, {@link BluetoothProfile#A2DP}.
*
- * <p> Return value can be one of
- * {@link BluetoothProfile#STATE_DISCONNECTED},
- * {@link BluetoothProfile#STATE_CONNECTING},
- * {@link BluetoothProfile#STATE_CONNECTED},
- * {@link BluetoothProfile#STATE_DISCONNECTING}
+ * <p> Return the profile connection state
*/
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@SuppressLint("AndroidFrameworkRequiresPermission")
- public int getProfileConnectionState(int profile) {
+ public @ConnectionState int getProfileConnectionState(int profile) {
android.util.SeempLog.record(64);
if (getState() != STATE_ON) {
return BluetoothProfile.STATE_DISCONNECTED;
@@ -4351,7 +4421,6 @@ public final class BluetoothAdapter {
* @hide
*/
@RequiresNoPermission
- @SystemApi
public boolean registerServiceLifecycleCallback(@NonNull ServiceLifecycleCallback callback) {
return getBluetoothService(callback.mRemote) != null;
}
@@ -4362,7 +4431,6 @@ public final class BluetoothAdapter {
* @hide
*/
@RequiresNoPermission
- @SystemApi
public void unregisterServiceLifecycleCallback(@NonNull ServiceLifecycleCallback callback) {
removeServiceStateCallback(callback.mRemote);
}
@@ -4372,7 +4440,6 @@ public final class BluetoothAdapter {
*
* @hide
*/
- @SystemApi
public abstract static class ServiceLifecycleCallback {
/** Called when the bluetooth stack is up */
@@ -4985,7 +5052,7 @@ public final class BluetoothAdapter {
* Returns human-readable strings corresponding to {@link DisconnectReason}.
*/
@NonNull
- public static String disconnectReasonText(@DisconnectReason int reason) {
+ public static String disconnectReasonToString(@DisconnectReason int reason) {
switch (reason) {
case BluetoothStatusCodes.ERROR_UNKNOWN:
return "Reason unknown";