summaryrefslogtreecommitdiff
path: root/framework/java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java')
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java11
-rwxr-xr-x[-rw-r--r--]framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java259
-rwxr-xr-xframework/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java271
3 files changed, 524 insertions, 17 deletions
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 01ceaa7f7d..8c591e897d 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -1385,6 +1385,17 @@ public final class BluetoothDevice implements Parcelable, Attributable {
}
/**
+ * Returns the address type of this BluetoothDevice.
+ *
+ * @return Bluetooth address type
+ * @hide
+ */
+ public int getAddressType() {
+ if (DBG) Log.d(TAG, "mAddressType: " + mAddressType);
+ return mAddressType;
+ }
+
+ /**
* Returns the anonymized hardware address of this BluetoothDevice. The first three octets
* will be suppressed for anonymization.
* <p> For example, "XX:XX:XX:AA:BB:CC".
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
index 870ab0fb30..3eef0a9a54 100644..100755
--- a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistant.java
@@ -19,6 +19,7 @@ package android.bluetooth;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
@@ -27,13 +28,19 @@ import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
+import android.content.AttributionSource;
import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.CloseGuard;
import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.Collections;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Executor;
/**
@@ -62,9 +69,10 @@ import java.util.concurrent.Executor;
* @hide
*/
@SystemApi
-public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
+public final class BluetoothLeBroadcastAssistant implements BluetoothProfile, AutoCloseable {
private static final String TAG = "BluetoothLeBroadcastAssistant";
private static final boolean DBG = true;
+ private final Map<Callback, Executor> mCallbackMap = new HashMap<>();
/**
* This class provides a set of callbacks that are invoked when scanning for Broadcast Sources
@@ -292,6 +300,21 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
public static final String ACTION_CONNECTION_STATE_CHANGED =
"android.bluetooth.action.CONNECTION_STATE_CHANGED";
+ private CloseGuard mCloseGuard;
+ private Context mContext;
+ private BluetoothAdapter mBluetoothAdapter;
+ private final AttributionSource mAttributionSource;
+ private BluetoothLeBroadcastAssistantCallback mCallback;
+
+ private final BluetoothProfileConnector<IBluetoothLeBroadcastAssistant> mProfileConnector =
+ new BluetoothProfileConnector(this, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
+ TAG, IBluetoothLeBroadcastAssistant.class.getName()) {
+ @Override
+ public IBluetoothLeBroadcastAssistant getServiceInterface(IBinder service) {
+ return IBluetoothLeBroadcastAssistant.Stub.asInterface(service);
+ }
+ };
+
/**
* Create a new instance of an LE Audio Broadcast Assistant.
*
@@ -299,8 +322,32 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
*/
/*package*/ BluetoothLeBroadcastAssistant(
@NonNull Context context, @NonNull ServiceListener listener) {
+ mContext = context;
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ mAttributionSource = mBluetoothAdapter.getAttributionSource();
+ mProfileConnector.connect(context, listener);
+ mCloseGuard = new CloseGuard();
+ mCloseGuard.open("close");
+ }
+
+ /** @hide */
+ protected void finalize() {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ close();
+ }
+
+ /**
+ * @hide
+ */
+ public void close() {
+ mProfileConnector.disconnect();
}
+ private IBluetoothLeBroadcastAssistant getService() {
+ return mProfileConnector.getService();
+ }
/**
* {@inheritDoc}
@@ -314,7 +361,20 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
@Override
public @BluetoothProfile.BtProfileState int getConnectionState(@NonNull BluetoothDevice sink) {
- return BluetoothProfile.STATE_DISCONNECTED;
+ log("getConnectionState(" + sink + ")");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final int defaultValue = BluetoothProfile.STATE_DISCONNECTED;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(sink)) {
+ try {
+ return service.getConnectionState(sink);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -330,7 +390,20 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
@Override
public @NonNull List<BluetoothDevice> getDevicesMatchingConnectionStates(
@NonNull int[] states) {
- return Collections.emptyList();
+ log("getDevicesMatchingConnectionStates()");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ return service.getDevicesMatchingConnectionStates(states);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -345,7 +418,20 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
@Override
public @NonNull List<BluetoothDevice> getConnectedDevices() {
- return Collections.emptyList();
+ log("getConnectedDevices()");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final List<BluetoothDevice> defaultValue = new ArrayList<BluetoothDevice>();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ return service.getConnectedDevices();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -368,7 +454,22 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
@ConnectionPolicy int connectionPolicy) {
- return false;
+ log("setConnectionPolicy()");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final boolean defaultValue = false;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(device)
+ && (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ || connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED)) {
+ try {
+ return service.setConnectionPolicy(device, connectionPolicy);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -389,7 +490,20 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
- return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+ log("getConnectionPolicy()");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final int defaultValue = BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(device)) {
+ try {
+ return service.getConnectionPolicy(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -420,7 +534,16 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
throw new IllegalArgumentException("callback cannot be null");
}
log("registerCallback");
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ if (mCallback == null) {
+ mCallback = new BluetoothLeBroadcastAssistantCallback(service);
+ }
+ mCallback.register(executor, callback);
+ }
}
/**
@@ -446,7 +569,15 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
throw new IllegalArgumentException("callback cannot be null");
}
log("unregisterCallback");
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ if (mCallback != null) {
+ mCallback.unregister(callback);
+ }
+ }
}
/**
@@ -492,7 +623,17 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
if (filters == null) {
throw new IllegalArgumentException("filters can be empty, but not null");
}
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ service.startSearchingForSources(filters);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
/**
@@ -513,7 +654,17 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
public void stopSearchingForSources() {
log("stopSearchingForSources:");
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ service.stopSearchingForSources();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
/**
@@ -529,7 +680,20 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
public boolean isSearchInProgress() {
- return false;
+ log("stopSearchingForSources:");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final boolean defaultValue = false;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ return service.isSearchInProgress();
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -602,7 +766,17 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
public void addSource(@NonNull BluetoothDevice sink,
@NonNull BluetoothLeBroadcastMetadata sourceMetadata, boolean isGroupOp) {
log("addBroadcastSource: " + sourceMetadata + " on " + sink);
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(sink)) {
+ try {
+ service.addSource(sink, sourceMetadata, isGroupOp);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
/**
@@ -657,7 +831,17 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
public void modifySource(@NonNull BluetoothDevice sink, int sourceId,
@NonNull BluetoothLeBroadcastMetadata updatedMetadata) {
log("updateBroadcastSource: " + updatedMetadata + " on " + sink);
- throw new UnsupportedOperationException("Not Implemented");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(sink)) {
+ try {
+ service.modifySource(sink, sourceId, updatedMetadata);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
/**
@@ -692,7 +876,17 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
public void removeSource(@NonNull BluetoothDevice sink, int sourceId) {
log("removeBroadcastSource: " + sourceId + " from " + sink);
- return;
+ final IBluetoothLeBroadcastAssistant service = getService();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(sink)) {
+ try {
+ service.removeSource(sink, sourceId);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
@@ -713,7 +907,21 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
})
public @NonNull List<BluetoothLeBroadcastReceiveState> getAllSources(
@NonNull BluetoothDevice sink) {
- return Collections.emptyList();
+ log("getAllSources()");
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final List<BluetoothLeBroadcastReceiveState> defaultValue =
+ new ArrayList<BluetoothLeBroadcastReceiveState>();
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled()) {
+ try {
+ return service.getAllSources(sink);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
/**
@@ -726,7 +934,19 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
*/
@SystemApi
public int getMaximumSourceCapacity(@NonNull BluetoothDevice sink) {
- return 0;
+ final IBluetoothLeBroadcastAssistant service = getService();
+ final int defaultValue = 0;
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mBluetoothAdapter.isEnabled() && isValidDevice(sink)) {
+ try {
+ return service.getMaximumSourceCapacity(sink);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
}
private static void log(@NonNull String msg) {
@@ -734,4 +954,9 @@ public final class BluetoothLeBroadcastAssistant implements BluetoothProfile {
Log.d(TAG, msg);
}
}
+
+ private static boolean isValidDevice(@Nullable BluetoothDevice device) {
+ return device != null && BluetoothAdapter
+ .checkBluetoothAddress(device.getAddress());
+ }
}
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java
new file mode 100755
index 0000000000..96e04a9424
--- /dev/null
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastAssistantCallback.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2022 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;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+public class BluetoothLeBroadcastAssistantCallback
+ extends IBluetoothLeBroadcastAssistantCallback.Stub {
+ private static final String TAG = BluetoothLeBroadcastAssistantCallback.class.getSimpleName();
+ private boolean mIsRegistered = false;
+ private final Map<BluetoothLeBroadcastAssistant.Callback,
+ Executor> mCallbackMap = new HashMap<>();
+ IBluetoothLeBroadcastAssistant mAdapter;
+
+ public BluetoothLeBroadcastAssistantCallback(IBluetoothLeBroadcastAssistant adapter) {
+ mAdapter = adapter;
+ }
+
+ /**
+ * @hide
+ * @param executor an {@link Executor} to execute given callback
+ * @param callback user implementation of the {@link BluetoothLeBroadcastAssistant#Callback}
+ */
+ public void register(@NonNull Executor executor,
+ @NonNull BluetoothLeBroadcastAssistant.Callback callback) {
+ synchronized (this) {
+ if (mCallbackMap.containsKey(callback)) {
+ return;
+ }
+ mCallbackMap.put(callback, executor);
+
+ if (!mIsRegistered) {
+ try {
+ mAdapter.registerCallback(this);
+ mIsRegistered = true;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to register broaddcast assistant callback");
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ }
+ }
+
+ /**
+ * @hide
+ * @param callback user implementation of the {@link BluetoothLeBroadcastAssistant#Callback}
+ */
+ public void unregister(@NonNull BluetoothLeBroadcastAssistant.Callback callback) {
+ synchronized (this) {
+ if (!mCallbackMap.containsKey(callback)) {
+ return;
+ }
+ mCallbackMap.remove(callback);
+ if (mCallbackMap.isEmpty() && mIsRegistered) {
+ try {
+ mAdapter.unregisterCallback(this);
+ mIsRegistered = false;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to unregister broaddcast assistant with service");
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSearchStarted(int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSearchStarted(reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSearchStartFailed(int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSearchStartFailed(reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSearchStopped(int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSearchStopped(reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSearchStopFailed(int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSearchStopFailed(reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceFound(BluetoothLeBroadcastMetadata source) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceFound(source));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceAdded(BluetoothDevice sink, int sourceId, int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceAdded(sink, sourceId, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceAddFailed(BluetoothDevice sink, BluetoothLeBroadcastMetadata source,
+ int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceAddFailed(sink, source, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceModified(BluetoothDevice sink, int sourceId, int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceModified(sink, sourceId, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceModifyFailed(BluetoothDevice sink, int sourceId, int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceModifyFailed(sink, sourceId, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceRemoved(BluetoothDevice sink, int sourceId, int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceRemoved(sink, sourceId, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSourceRemoveFailed(BluetoothDevice sink, int sourceId, int reason) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onSourceRemoveFailed(sink, sourceId, reason));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onReceiveStateChanged(BluetoothDevice sink, int sourceId,
+ BluetoothLeBroadcastReceiveState state) {
+ synchronized (this) {
+ for (BluetoothLeBroadcastAssistant.Callback cb : mCallbackMap.keySet()) {
+ Executor executor = mCallbackMap.get(cb);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ executor.execute(() -> cb.onReceiveStateChanged(sink, sourceId, state));
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ }
+ }
+}