Loading android/app/aidl/android/bluetooth/IBluetooth.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ interface IBluetooth @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean registerMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean unregisterMetadataListener(in BluetoothDevice device, in AttributionSource attributionSource); boolean unregisterMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean setMetadata(in BluetoothDevice device, in int key, in byte[] value, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +39 −21 Original line number Diff line number Diff line Loading @@ -240,8 +240,8 @@ public class AdapterService extends Service { private final AdapterNativeInterface mNativeInterface = AdapterNativeInterface.getInstance(); private final Map<BluetoothDevice, List<IBluetoothMetadataListener>> mMetadataListeners = new HashMap<>(); private final Map<BluetoothDevice, RemoteCallbackList<IBluetoothMetadataListener>> mMetadataListeners = new HashMap<>(); // Map<groupId, PendingAudioProfilePreferenceRequest> @GuardedBy("mCsipGroupsPendingAudioProfileChanges") Loading Loading @@ -1488,6 +1488,8 @@ public class AdapterService extends Service { mBluetoothConnectionCallbacks.kill(); mRemoteCallbacks.kill(); mMetadataListeners.values().forEach(v -> v.kill()); } private void invalidateBluetoothCaches() { Loading Loading @@ -3690,6 +3692,8 @@ public class AdapterService extends Service { IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) { requireNonNull(device); requireNonNull(listener); AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( Loading @@ -3700,21 +3704,22 @@ public class AdapterService extends Service { service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); List<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device); if (list == null) { list = new ArrayList<>(); } else if (list.contains(listener)) { // The device is already registered with this listener return true; } list.add(listener); service.mMetadataListeners.put(device, list); service.mHandler.post( () -> service.mMetadataListeners .computeIfAbsent(device, k -> new RemoteCallbackList()) .register(listener)); return true; } @Override public boolean unregisterMetadataListener( BluetoothDevice device, AttributionSource source) { IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) { requireNonNull(device); requireNonNull(listener); AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( Loading @@ -3725,7 +3730,17 @@ public class AdapterService extends Service { service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); service.mMetadataListeners.remove(device); service.mHandler.post( () -> service.mMetadataListeners.computeIfPresent( device, (k, v) -> { v.unregister(listener); if (v.getRegisteredCallbackCount() == 0) { return null; } return v; })); return true; } Loading Loading @@ -6231,16 +6246,19 @@ public class AdapterService extends Service { mNativeInterface.metadataChanged(Utils.getBytesFromAddress(address), key, value); } if (mMetadataListeners.containsKey(device)) { List<IBluetoothMetadataListener> list = mMetadataListeners.get(device); for (IBluetoothMetadataListener listener : list) { RemoteCallbackList<IBluetoothMetadataListener> list = mMetadataListeners.get(device); if (list == null) { return; } int n = list.beginBroadcast(); for (int i = 0; i < n; i++) { try { listener.onMetadataChanged(device, key, value); list.getBroadcastItem(i).onMetadataChanged(device, key, value); } catch (RemoteException e) { Log.w(TAG, "RemoteException when onMetadataChanged"); } Log.d(TAG, "metadataChanged() - Callback #" + i + " failed (" + e + ")"); } } list.finishBroadcast(); } private int getIdleCurrentMa() { Loading framework/java/android/bluetooth/BluetoothAdapter.java +11 −29 Original line number Diff line number Diff line Loading @@ -916,10 +916,10 @@ public final class BluetoothAdapter { /** * Bluetooth metadata listener. Overrides the default BluetoothMetadataListener implementation. */ @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothMetadataListener mBluetoothMetadataListener = new IBluetoothMetadataListener.Stub() { @Override @RequiresNoPermission public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) { Attributable.setAttributionSource(device, mAttributionSource); synchronized (mMetadataListeners) { Loading Loading @@ -4560,26 +4560,15 @@ public final class BluetoothAdapter { */ @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED, }) @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener( @NonNull BluetoothDevice device, @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "addOnMetadataChangedListener()"); if (listener == null) { throw new NullPointerException("listener is null"); } if (device == null) { throw new NullPointerException("device is null"); } if (executor == null) { throw new NullPointerException("executor is null"); } requireNonNull(device); requireNonNull(executor); requireNonNull(listener); mServiceLock.readLock().lock(); try { Loading @@ -4599,7 +4588,7 @@ public final class BluetoothAdapter { // Check whether this device is already registered by the listener if (listenerList.stream().anyMatch((pair) -> (pair.first.equals(listener)))) { throw new IllegalArgumentException( "listener was already registered" + " for the device"); "listener already registered for " + device); } } Loading Loading @@ -4648,20 +4637,12 @@ public final class BluetoothAdapter { */ @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED, }) @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener( @NonNull BluetoothDevice device, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "removeOnMetadataChangedListener()"); if (device == null) { throw new NullPointerException("device is null"); } if (listener == null) { throw new NullPointerException("listener is null"); } requireNonNull(device); requireNonNull(listener); synchronized (mMetadataListeners) { if (!mMetadataListeners.containsKey(device)) { Loading @@ -4677,7 +4658,8 @@ public final class BluetoothAdapter { mServiceLock.readLock().lock(); try { if (mService != null) { return mService.unregisterMetadataListener(device, mAttributionSource); return mService.unregisterMetadataListener( mBluetoothMetadataListener, device, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); Loading Loading
android/app/aidl/android/bluetooth/IBluetooth.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -208,7 +208,7 @@ interface IBluetooth @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean registerMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean unregisterMetadataListener(in BluetoothDevice device, in AttributionSource attributionSource); boolean unregisterMetadataListener(in IBluetoothMetadataListener listener, in BluetoothDevice device, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") boolean setMetadata(in BluetoothDevice device, in int key, in byte[] value, in AttributionSource attributionSource); @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})") Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +39 −21 Original line number Diff line number Diff line Loading @@ -240,8 +240,8 @@ public class AdapterService extends Service { private final AdapterNativeInterface mNativeInterface = AdapterNativeInterface.getInstance(); private final Map<BluetoothDevice, List<IBluetoothMetadataListener>> mMetadataListeners = new HashMap<>(); private final Map<BluetoothDevice, RemoteCallbackList<IBluetoothMetadataListener>> mMetadataListeners = new HashMap<>(); // Map<groupId, PendingAudioProfilePreferenceRequest> @GuardedBy("mCsipGroupsPendingAudioProfileChanges") Loading Loading @@ -1488,6 +1488,8 @@ public class AdapterService extends Service { mBluetoothConnectionCallbacks.kill(); mRemoteCallbacks.kill(); mMetadataListeners.values().forEach(v -> v.kill()); } private void invalidateBluetoothCaches() { Loading Loading @@ -3690,6 +3692,8 @@ public class AdapterService extends Service { IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) { requireNonNull(device); requireNonNull(listener); AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( Loading @@ -3700,21 +3704,22 @@ public class AdapterService extends Service { service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); List<IBluetoothMetadataListener> list = service.mMetadataListeners.get(device); if (list == null) { list = new ArrayList<>(); } else if (list.contains(listener)) { // The device is already registered with this listener return true; } list.add(listener); service.mMetadataListeners.put(device, list); service.mHandler.post( () -> service.mMetadataListeners .computeIfAbsent(device, k -> new RemoteCallbackList()) .register(listener)); return true; } @Override public boolean unregisterMetadataListener( BluetoothDevice device, AttributionSource source) { IBluetoothMetadataListener listener, BluetoothDevice device, AttributionSource source) { requireNonNull(device); requireNonNull(listener); AdapterService service = getService(); if (service == null || !callerIsSystemOrActiveOrManagedUser( Loading @@ -3725,7 +3730,17 @@ public class AdapterService extends Service { service.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, null); service.mMetadataListeners.remove(device); service.mHandler.post( () -> service.mMetadataListeners.computeIfPresent( device, (k, v) -> { v.unregister(listener); if (v.getRegisteredCallbackCount() == 0) { return null; } return v; })); return true; } Loading Loading @@ -6231,16 +6246,19 @@ public class AdapterService extends Service { mNativeInterface.metadataChanged(Utils.getBytesFromAddress(address), key, value); } if (mMetadataListeners.containsKey(device)) { List<IBluetoothMetadataListener> list = mMetadataListeners.get(device); for (IBluetoothMetadataListener listener : list) { RemoteCallbackList<IBluetoothMetadataListener> list = mMetadataListeners.get(device); if (list == null) { return; } int n = list.beginBroadcast(); for (int i = 0; i < n; i++) { try { listener.onMetadataChanged(device, key, value); list.getBroadcastItem(i).onMetadataChanged(device, key, value); } catch (RemoteException e) { Log.w(TAG, "RemoteException when onMetadataChanged"); } Log.d(TAG, "metadataChanged() - Callback #" + i + " failed (" + e + ")"); } } list.finishBroadcast(); } private int getIdleCurrentMa() { Loading
framework/java/android/bluetooth/BluetoothAdapter.java +11 −29 Original line number Diff line number Diff line Loading @@ -916,10 +916,10 @@ public final class BluetoothAdapter { /** * Bluetooth metadata listener. Overrides the default BluetoothMetadataListener implementation. */ @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothMetadataListener mBluetoothMetadataListener = new IBluetoothMetadataListener.Stub() { @Override @RequiresNoPermission public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) { Attributable.setAttributionSource(device, mAttributionSource); synchronized (mMetadataListeners) { Loading Loading @@ -4560,26 +4560,15 @@ public final class BluetoothAdapter { */ @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED, }) @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener( @NonNull BluetoothDevice device, @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "addOnMetadataChangedListener()"); if (listener == null) { throw new NullPointerException("listener is null"); } if (device == null) { throw new NullPointerException("device is null"); } if (executor == null) { throw new NullPointerException("executor is null"); } requireNonNull(device); requireNonNull(executor); requireNonNull(listener); mServiceLock.readLock().lock(); try { Loading @@ -4599,7 +4588,7 @@ public final class BluetoothAdapter { // Check whether this device is already registered by the listener if (listenerList.stream().anyMatch((pair) -> (pair.first.equals(listener)))) { throw new IllegalArgumentException( "listener was already registered" + " for the device"); "listener already registered for " + device); } } Loading Loading @@ -4648,20 +4637,12 @@ public final class BluetoothAdapter { */ @SystemApi @RequiresBluetoothConnectPermission @RequiresPermission( allOf = { BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED, }) @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener( @NonNull BluetoothDevice device, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "removeOnMetadataChangedListener()"); if (device == null) { throw new NullPointerException("device is null"); } if (listener == null) { throw new NullPointerException("listener is null"); } requireNonNull(device); requireNonNull(listener); synchronized (mMetadataListeners) { if (!mMetadataListeners.containsKey(device)) { Loading @@ -4677,7 +4658,8 @@ public final class BluetoothAdapter { mServiceLock.readLock().lock(); try { if (mService != null) { return mService.unregisterMetadataListener(device, mAttributionSource); return mService.unregisterMetadataListener( mBluetoothMetadataListener, device, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable())); Loading