Loading core/java/android/bluetooth/BluetoothAdapter.java +124 −60 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ import android.os.SystemProperties; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -78,6 +80,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -715,10 +718,21 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private final AttributionSource mAttributionSource; // Yeah, keeping both mService and sService isn't pretty, but it's too late // in the current release for a major refactoring, so we leave them both // intact until this can be cleaned up in a future release @UnsupportedAppUsage @GuardedBy("mServiceLock") private IBluetooth mService; private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); @GuardedBy("sServiceLock") private static boolean sServiceRegistered; @GuardedBy("sServiceLock") private static IBluetooth sService; private static final Object sServiceLock = new Object(); private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>> Loading Loading @@ -792,19 +806,11 @@ public final class BluetoothAdapter { * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance. */ BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); } finally { mServiceLock.writeLock().unlock(); } mManagerService = Objects.requireNonNull(managerService); mAttributionSource = Objects.requireNonNull(attributionSource); synchronized (mServiceLock.writeLock()) { mService = getBluetoothService(mManagerCallback); } mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(DESCRIPTOR); } Loading Loading @@ -3154,21 +3160,16 @@ public final class BluetoothAdapter { } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothManagerCallback mManagerCallback = private static final IBluetoothManagerCallback sManagerCallback = new IBluetoothManagerCallback.Stub() { @SuppressLint("AndroidFrameworkRequiresPermission") public void onBluetoothServiceUp(IBluetooth bluetoothService) { if (DBG) { Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); } mServiceLock.writeLock().lock(); mService = bluetoothService; mServiceLock.writeLock().unlock(); synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { synchronized (sServiceLock) { sService = bluetoothService; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceUp(bluetoothService); Loading @@ -3180,6 +3181,56 @@ public final class BluetoothAdapter { } } } } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown"); } synchronized (sServiceLock) { sService = null; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown"); } synchronized (sServiceLock) { for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBrEdrDown(); } else { Log.d(TAG, "onBrEdrDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } }; private final IBluetoothManagerCallback mManagerCallback = new IBluetoothManagerCallback.Stub() { public void onBluetoothServiceUp(IBluetooth bluetoothService) { synchronized (mServiceLock.writeLock()) { mService = bluetoothService; } synchronized (mMetadataListeners) { mMetadataListeners.forEach((device, pair) -> { try { Loading @@ -3204,12 +3255,7 @@ public final class BluetoothAdapter { } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown: " + mService); } try { mServiceLock.writeLock().lock(); synchronized (mServiceLock.writeLock()) { mService = null; if (mLeScanClients != null) { mLeScanClients.clear(); Loading @@ -3220,29 +3266,10 @@ public final class BluetoothAdapter { if (mBluetoothLeScanner != null) { mBluetoothLeScanner.cleanup(); } } finally { mServiceLock.writeLock().unlock(); } synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown: " + mService); } } }; Loading Loading @@ -3477,15 +3504,12 @@ public final class BluetoothAdapter { protected void finalize() throws Throwable { try { mManagerService.unregisterAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); removeServiceStateCallback(mManagerCallback); } finally { super.finalize(); } } /** * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0" * <p>Alphabetic characters must be uppercase to be valid. Loading Loading @@ -3549,24 +3573,64 @@ public final class BluetoothAdapter { return mAttributionSource; } private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>(); @GuardedBy("sServiceLock") private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks = new WeakHashMap<>(); /*package*/ IBluetooth getBluetoothService() { synchronized (sServiceLock) { if (sProxyServiceStateCallbacks.isEmpty()) { throw new IllegalStateException( "Anonymous service access requires at least one lifecycle in process"); } return sService; } } @UnsupportedAppUsage /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { if (cb == null) { Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback"); } else if (!mProxyServiceStateCallbacks.contains(cb)) { mProxyServiceStateCallbacks.add(cb); } Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.put(cb, null); registerOrUnregisterAdapterLocked(); return sService; } return mService; } /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { mProxyServiceStateCallbacks.remove(cb); Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.remove(cb); registerOrUnregisterAdapterLocked(); } } /** * Handle registering (or unregistering) a single process-wide * {@link IBluetoothManagerCallback} based on the presence of local * {@link #sProxyServiceStateCallbacks} clients. */ @GuardedBy("sServiceLock") private void registerOrUnregisterAdapterLocked() { final boolean isRegistered = sServiceRegistered; final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty(); if (isRegistered != wantRegistered) { if (wantRegistered) { try { sService = mManagerService.registerAdapter(sManagerCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { try { mManagerService.unregisterAdapter(sManagerCallback); sService = null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } sServiceRegistered = wantRegistered; } } Loading core/java/android/bluetooth/BluetoothSocket.java +3 −3 Original line number Diff line number Diff line Loading @@ -399,7 +399,7 @@ public final class BluetoothSocket implements Closeable { try { if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed"); IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) throw new IOException("Bluetooth is off"); mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags()); Loading Loading @@ -438,7 +438,7 @@ public final class BluetoothSocket implements Closeable { /*package*/ int bindListen() { int ret; if (mSocketState == SocketState.CLOSED) return EBADFD; IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { Log.e(TAG, "bindListen fail, reason: bluetooth is off"); return -1; Loading Loading @@ -706,7 +706,7 @@ public final class BluetoothSocket implements Closeable { throw new IOException("socket closed"); } IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { throw new IOException("Bluetooth is off"); } Loading Loading
core/java/android/bluetooth/BluetoothAdapter.java +124 −60 Original line number Diff line number Diff line Loading @@ -64,6 +64,8 @@ import android.os.SystemProperties; import android.util.Log; import android.util.Pair; import com.android.internal.annotations.GuardedBy; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; Loading @@ -78,6 +80,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; Loading Loading @@ -715,10 +718,21 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; private final AttributionSource mAttributionSource; // Yeah, keeping both mService and sService isn't pretty, but it's too late // in the current release for a major refactoring, so we leave them both // intact until this can be cleaned up in a future release @UnsupportedAppUsage @GuardedBy("mServiceLock") private IBluetooth mService; private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); @GuardedBy("sServiceLock") private static boolean sServiceRegistered; @GuardedBy("sServiceLock") private static IBluetooth sService; private static final Object sServiceLock = new Object(); private final Object mLock = new Object(); private final Map<LeScanCallback, ScanCallback> mLeScanClients; private final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>> Loading Loading @@ -792,19 +806,11 @@ public final class BluetoothAdapter { * Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance. */ BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) { if (managerService == null) { throw new IllegalArgumentException("bluetooth manager service is null"); } try { mServiceLock.writeLock().lock(); mService = managerService.registerAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); } finally { mServiceLock.writeLock().unlock(); } mManagerService = Objects.requireNonNull(managerService); mAttributionSource = Objects.requireNonNull(attributionSource); synchronized (mServiceLock.writeLock()) { mService = getBluetoothService(mManagerCallback); } mLeScanClients = new HashMap<LeScanCallback, ScanCallback>(); mToken = new Binder(DESCRIPTOR); } Loading Loading @@ -3154,21 +3160,16 @@ public final class BluetoothAdapter { } } @SuppressLint("AndroidFrameworkBluetoothPermission") private final IBluetoothManagerCallback mManagerCallback = private static final IBluetoothManagerCallback sManagerCallback = new IBluetoothManagerCallback.Stub() { @SuppressLint("AndroidFrameworkRequiresPermission") public void onBluetoothServiceUp(IBluetooth bluetoothService) { if (DBG) { Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService); } mServiceLock.writeLock().lock(); mService = bluetoothService; mServiceLock.writeLock().unlock(); synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { synchronized (sServiceLock) { sService = bluetoothService; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceUp(bluetoothService); Loading @@ -3180,6 +3181,56 @@ public final class BluetoothAdapter { } } } } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown"); } synchronized (sServiceLock) { sService = null; for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown"); } synchronized (sServiceLock) { for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) { try { if (cb != null) { cb.onBrEdrDown(); } else { Log.d(TAG, "onBrEdrDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } }; private final IBluetoothManagerCallback mManagerCallback = new IBluetoothManagerCallback.Stub() { public void onBluetoothServiceUp(IBluetooth bluetoothService) { synchronized (mServiceLock.writeLock()) { mService = bluetoothService; } synchronized (mMetadataListeners) { mMetadataListeners.forEach((device, pair) -> { try { Loading @@ -3204,12 +3255,7 @@ public final class BluetoothAdapter { } public void onBluetoothServiceDown() { if (DBG) { Log.d(TAG, "onBluetoothServiceDown: " + mService); } try { mServiceLock.writeLock().lock(); synchronized (mServiceLock.writeLock()) { mService = null; if (mLeScanClients != null) { mLeScanClients.clear(); Loading @@ -3220,29 +3266,10 @@ public final class BluetoothAdapter { if (mBluetoothLeScanner != null) { mBluetoothLeScanner.cleanup(); } } finally { mServiceLock.writeLock().unlock(); } synchronized (mProxyServiceStateCallbacks) { for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) { try { if (cb != null) { cb.onBluetoothServiceDown(); } else { Log.d(TAG, "onBluetoothServiceDown: cb is null!"); } } catch (Exception e) { Log.e(TAG, "", e); } } } } public void onBrEdrDown() { if (VDBG) { Log.i(TAG, "onBrEdrDown: " + mService); } } }; Loading Loading @@ -3477,15 +3504,12 @@ public final class BluetoothAdapter { protected void finalize() throws Throwable { try { mManagerService.unregisterAdapter(mManagerCallback); } catch (RemoteException e) { Log.e(TAG, "", e); removeServiceStateCallback(mManagerCallback); } finally { super.finalize(); } } /** * Validate a String Bluetooth address, such as "00:43:A8:23:10:F0" * <p>Alphabetic characters must be uppercase to be valid. Loading Loading @@ -3549,24 +3573,64 @@ public final class BluetoothAdapter { return mAttributionSource; } private final ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>(); @GuardedBy("sServiceLock") private static final WeakHashMap<IBluetoothManagerCallback, Void> sProxyServiceStateCallbacks = new WeakHashMap<>(); /*package*/ IBluetooth getBluetoothService() { synchronized (sServiceLock) { if (sProxyServiceStateCallbacks.isEmpty()) { throw new IllegalStateException( "Anonymous service access requires at least one lifecycle in process"); } return sService; } } @UnsupportedAppUsage /*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { if (cb == null) { Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback"); } else if (!mProxyServiceStateCallbacks.contains(cb)) { mProxyServiceStateCallbacks.add(cb); } Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.put(cb, null); registerOrUnregisterAdapterLocked(); return sService; } return mService; } /*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) { synchronized (mProxyServiceStateCallbacks) { mProxyServiceStateCallbacks.remove(cb); Objects.requireNonNull(cb); synchronized (sServiceLock) { sProxyServiceStateCallbacks.remove(cb); registerOrUnregisterAdapterLocked(); } } /** * Handle registering (or unregistering) a single process-wide * {@link IBluetoothManagerCallback} based on the presence of local * {@link #sProxyServiceStateCallbacks} clients. */ @GuardedBy("sServiceLock") private void registerOrUnregisterAdapterLocked() { final boolean isRegistered = sServiceRegistered; final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty(); if (isRegistered != wantRegistered) { if (wantRegistered) { try { sService = mManagerService.registerAdapter(sManagerCallback); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { try { mManagerService.unregisterAdapter(sManagerCallback); sService = null; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } sServiceRegistered = wantRegistered; } } Loading
core/java/android/bluetooth/BluetoothSocket.java +3 −3 Original line number Diff line number Diff line Loading @@ -399,7 +399,7 @@ public final class BluetoothSocket implements Closeable { try { if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed"); IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) throw new IOException("Bluetooth is off"); mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType, mUuid, mPort, getSecurityFlags()); Loading Loading @@ -438,7 +438,7 @@ public final class BluetoothSocket implements Closeable { /*package*/ int bindListen() { int ret; if (mSocketState == SocketState.CLOSED) return EBADFD; IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { Log.e(TAG, "bindListen fail, reason: bluetooth is off"); return -1; Loading Loading @@ -706,7 +706,7 @@ public final class BluetoothSocket implements Closeable { throw new IOException("socket closed"); } IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null); BluetoothAdapter.getDefaultAdapter().getBluetoothService(); if (bluetoothProxy == null) { throw new IOException("Bluetooth is off"); } Loading