Loading framework/java/android/bluetooth/BluetoothAdapter.java +39 −80 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executor; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.BiFunction; import java.util.function.BiFunction; import java.util.function.Consumer; /** /** * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform Loading Loading @@ -890,8 +891,6 @@ public final class BluetoothAdapter { mBluetoothConnectionCallbackExecutorMap = new HashMap<>(); mBluetoothConnectionCallbackExecutorMap = new HashMap<>(); private final Map<PreferredAudioProfilesChangedCallback, Executor> private final Map<PreferredAudioProfilesChangedCallback, Executor> mAudioProfilesChangedCallbackExecutorMap = new HashMap<>(); mAudioProfilesChangedCallbackExecutorMap = new HashMap<>(); private final Map<BluetoothQualityReportReadyCallback, Executor> mBluetoothQualityReportReadyCallbackExecutorMap = new HashMap<>(); private static final class ProfileConnection { private static final class ProfileConnection { int mProfile; int mProfile; Loading Loading @@ -1106,6 +1105,29 @@ public final class BluetoothAdapter { } finally { } finally { mServiceLock.writeLock().unlock(); mServiceLock.writeLock().unlock(); } } Consumer<IBluetooth> registerQualityReportCallbackConsumer = (IBluetooth service) -> { try { service.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } }; Consumer<IBluetooth> unregisterQualityReportCallbackConsumer = (IBluetooth service) -> { try { service.unregisterBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } }; mQualityCallbackWrapper = new CallbackWrapper( registerQualityReportCallbackConsumer, unregisterQualityReportCallbackConsumer); } } /** /** Loading Loading @@ -3755,21 +3777,7 @@ public final class BluetoothAdapter { } } } } } } synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { mQualityCallbackWrapper.registerToNewService(mService); if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { try { mService.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e( TAG, "onBluetoothServiceUp: Failed to register bluetooth" + "quality report callback", e); } } } } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } Loading Loading @@ -5255,25 +5263,18 @@ public final class BluetoothAdapter { int status); int status); } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final CallbackWrapper<BluetoothQualityReportReadyCallback, IBluetooth> mQualityCallbackWrapper; private final IBluetoothQualityReportReadyCallback mBluetoothQualityReportReadyCallback = private final IBluetoothQualityReportReadyCallback mBluetoothQualityReportReadyCallback = new IBluetoothQualityReportReadyCallback.Stub() { new IBluetoothQualityReportReadyCallback.Stub() { @Override @Override public void onBluetoothQualityReportReady( public void onBluetoothQualityReportReady( BluetoothDevice device, BluetoothDevice device, BluetoothQualityReport bluetoothQualityReport, BluetoothQualityReport report, int status) { int status) { for (Map.Entry<BluetoothQualityReportReadyCallback, Executor> mQualityCallbackWrapper.forEach( callbackExecutorEntry : (cb) -> cb.onBluetoothQualityReportReady(device, report, status)); mBluetoothQualityReportReadyCallbackExecutorMap.entrySet()) { BluetoothQualityReportReadyCallback callback = callbackExecutorEntry.getKey(); Executor executor = callbackExecutorEntry.getValue(); executor.execute( () -> callback.onBluetoothQualityReportReady( device, bluetoothQualityReport, status)); } } } }; }; Loading Loading @@ -5312,38 +5313,13 @@ public final class BluetoothAdapter { @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothQualityReportReadyCallback callback) { @NonNull BluetoothQualityReportReadyCallback callback) { if (DBG) Log.d(TAG, "registerBluetoothQualityReportReadyCallback()"); if (DBG) Log.d(TAG, "registerBluetoothQualityReportReadyCallback()"); requireNonNull(executor, "executor cannot be null"); requireNonNull(callback, "callback cannot be null"); synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { // If the callback map is empty, we register the service-to-app callback if (mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { int serviceCallStatus = BluetoothStatusCodes.ERROR_UNKNOWN; mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); try { try { if (mService != null) { mQualityCallbackWrapper.registerCallback(mService, callback, executor); serviceCallStatus = mService.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } if (serviceCallStatus != BluetoothStatusCodes.SUCCESS) { return serviceCallStatus; } } // Adds the passed in callback to our local mapping if (mBluetoothQualityReportReadyCallbackExecutorMap.containsKey(callback)) { throw new IllegalArgumentException("This callback has already been registered"); } else { mBluetoothQualityReportReadyCallbackExecutorMap.put(callback, executor); } } return BluetoothStatusCodes.SUCCESS; return BluetoothStatusCodes.SUCCESS; } } Loading Loading @@ -5380,32 +5356,15 @@ public final class BluetoothAdapter { public int unregisterBluetoothQualityReportReadyCallback( public int unregisterBluetoothQualityReportReadyCallback( @NonNull BluetoothQualityReportReadyCallback callback) { @NonNull BluetoothQualityReportReadyCallback callback) { if (DBG) Log.d(TAG, "unregisterBluetoothQualityReportReadyCallback()"); if (DBG) Log.d(TAG, "unregisterBluetoothQualityReportReadyCallback()"); requireNonNull(callback, "callback cannot be null"); synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { if (mBluetoothQualityReportReadyCallbackExecutorMap.remove(callback) == null) { throw new IllegalArgumentException("This callback has not been registered"); } } if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { return BluetoothStatusCodes.SUCCESS; } // If the callback map is empty, we unregister the service-to-app callback mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); try { try { if (mService != null) { mQualityCallbackWrapper.unregisterCallback(mService, callback); return mService.unregisterBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } return BluetoothStatusCodes.ERROR_UNKNOWN; return BluetoothStatusCodes.SUCCESS; } } /** /** Loading Loading
framework/java/android/bluetooth/BluetoothAdapter.java +39 −80 Original line number Original line Diff line number Diff line Loading @@ -99,6 +99,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.Executor; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.BiFunction; import java.util.function.BiFunction; import java.util.function.Consumer; /** /** * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter} lets you perform Loading Loading @@ -890,8 +891,6 @@ public final class BluetoothAdapter { mBluetoothConnectionCallbackExecutorMap = new HashMap<>(); mBluetoothConnectionCallbackExecutorMap = new HashMap<>(); private final Map<PreferredAudioProfilesChangedCallback, Executor> private final Map<PreferredAudioProfilesChangedCallback, Executor> mAudioProfilesChangedCallbackExecutorMap = new HashMap<>(); mAudioProfilesChangedCallbackExecutorMap = new HashMap<>(); private final Map<BluetoothQualityReportReadyCallback, Executor> mBluetoothQualityReportReadyCallbackExecutorMap = new HashMap<>(); private static final class ProfileConnection { private static final class ProfileConnection { int mProfile; int mProfile; Loading Loading @@ -1106,6 +1105,29 @@ public final class BluetoothAdapter { } finally { } finally { mServiceLock.writeLock().unlock(); mServiceLock.writeLock().unlock(); } } Consumer<IBluetooth> registerQualityReportCallbackConsumer = (IBluetooth service) -> { try { service.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } }; Consumer<IBluetooth> unregisterQualityReportCallbackConsumer = (IBluetooth service) -> { try { service.unregisterBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } }; mQualityCallbackWrapper = new CallbackWrapper( registerQualityReportCallbackConsumer, unregisterQualityReportCallbackConsumer); } } /** /** Loading Loading @@ -3755,21 +3777,7 @@ public final class BluetoothAdapter { } } } } } } synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { mQualityCallbackWrapper.registerToNewService(mService); if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { try { mService.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } catch (RemoteException e) { Log.e( TAG, "onBluetoothServiceUp: Failed to register bluetooth" + "quality report callback", e); } } } } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } Loading Loading @@ -5255,25 +5263,18 @@ public final class BluetoothAdapter { int status); int status); } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final CallbackWrapper<BluetoothQualityReportReadyCallback, IBluetooth> mQualityCallbackWrapper; private final IBluetoothQualityReportReadyCallback mBluetoothQualityReportReadyCallback = private final IBluetoothQualityReportReadyCallback mBluetoothQualityReportReadyCallback = new IBluetoothQualityReportReadyCallback.Stub() { new IBluetoothQualityReportReadyCallback.Stub() { @Override @Override public void onBluetoothQualityReportReady( public void onBluetoothQualityReportReady( BluetoothDevice device, BluetoothDevice device, BluetoothQualityReport bluetoothQualityReport, BluetoothQualityReport report, int status) { int status) { for (Map.Entry<BluetoothQualityReportReadyCallback, Executor> mQualityCallbackWrapper.forEach( callbackExecutorEntry : (cb) -> cb.onBluetoothQualityReportReady(device, report, status)); mBluetoothQualityReportReadyCallbackExecutorMap.entrySet()) { BluetoothQualityReportReadyCallback callback = callbackExecutorEntry.getKey(); Executor executor = callbackExecutorEntry.getValue(); executor.execute( () -> callback.onBluetoothQualityReportReady( device, bluetoothQualityReport, status)); } } } }; }; Loading Loading @@ -5312,38 +5313,13 @@ public final class BluetoothAdapter { @NonNull @CallbackExecutor Executor executor, @NonNull @CallbackExecutor Executor executor, @NonNull BluetoothQualityReportReadyCallback callback) { @NonNull BluetoothQualityReportReadyCallback callback) { if (DBG) Log.d(TAG, "registerBluetoothQualityReportReadyCallback()"); if (DBG) Log.d(TAG, "registerBluetoothQualityReportReadyCallback()"); requireNonNull(executor, "executor cannot be null"); requireNonNull(callback, "callback cannot be null"); synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { // If the callback map is empty, we register the service-to-app callback if (mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { int serviceCallStatus = BluetoothStatusCodes.ERROR_UNKNOWN; mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); try { try { if (mService != null) { mQualityCallbackWrapper.registerCallback(mService, callback, executor); serviceCallStatus = mService.registerBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } if (serviceCallStatus != BluetoothStatusCodes.SUCCESS) { return serviceCallStatus; } } // Adds the passed in callback to our local mapping if (mBluetoothQualityReportReadyCallbackExecutorMap.containsKey(callback)) { throw new IllegalArgumentException("This callback has already been registered"); } else { mBluetoothQualityReportReadyCallbackExecutorMap.put(callback, executor); } } return BluetoothStatusCodes.SUCCESS; return BluetoothStatusCodes.SUCCESS; } } Loading Loading @@ -5380,32 +5356,15 @@ public final class BluetoothAdapter { public int unregisterBluetoothQualityReportReadyCallback( public int unregisterBluetoothQualityReportReadyCallback( @NonNull BluetoothQualityReportReadyCallback callback) { @NonNull BluetoothQualityReportReadyCallback callback) { if (DBG) Log.d(TAG, "unregisterBluetoothQualityReportReadyCallback()"); if (DBG) Log.d(TAG, "unregisterBluetoothQualityReportReadyCallback()"); requireNonNull(callback, "callback cannot be null"); synchronized (mBluetoothQualityReportReadyCallbackExecutorMap) { if (mBluetoothQualityReportReadyCallbackExecutorMap.remove(callback) == null) { throw new IllegalArgumentException("This callback has not been registered"); } } if (!mBluetoothQualityReportReadyCallbackExecutorMap.isEmpty()) { return BluetoothStatusCodes.SUCCESS; } // If the callback map is empty, we unregister the service-to-app callback mServiceLock.readLock().lock(); mServiceLock.readLock().lock(); try { try { if (mService != null) { mQualityCallbackWrapper.unregisterCallback(mService, callback); return mService.unregisterBluetoothQualityReportReadyCallback( mBluetoothQualityReportReadyCallback, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); } finally { } finally { mServiceLock.readLock().unlock(); mServiceLock.readLock().unlock(); } } return BluetoothStatusCodes.ERROR_UNKNOWN; return BluetoothStatusCodes.SUCCESS; } } /** /** Loading