Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f25c480f authored by William Escande's avatar William Escande
Browse files

Add missing lock and null check

Bug: 274037299
Test: TH + manual boot and connect a device
Change-Id: I185129bbf57ad5b1849c495131f5738d00e43d12
parent 724e86a0
Loading
Loading
Loading
Loading
+129 −105
Original line number Diff line number Diff line
@@ -86,7 +86,6 @@ import java.util.UUID;
import java.util.WeakHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
@@ -1062,12 +1061,11 @@ public final class BluetoothAdapter {
    BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) {
        mManagerService = Objects.requireNonNull(managerService);
        mAttributionSource = Objects.requireNonNull(attributionSource);
        Lock l = mServiceLock.writeLock();
        l.lock();
        mServiceLock.writeLock().lock();
        try {
            mService = getBluetoothService(mManagerCallback);
        } finally {
            l.unlock();
            mServiceLock.writeLock().unlock();
        }
        mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
        mToken = new Binder(DESCRIPTOR);
@@ -1660,12 +1658,17 @@ public final class BluetoothAdapter {
    @RequiresBluetoothAdvertisePermission
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE)
    public int getNameLengthForAdvertise() {
        mServiceLock.readLock().lock();
        try {
            if (mService != null) {
                final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get();
                mService.getNameLengthForAdvertise(mAttributionSource, recv);
                return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(-1);
            }
        } catch (RemoteException | TimeoutException e) {
            Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
        } finally {
            mServiceLock.readLock().unlock();
        }
        return -1;
    }
@@ -1745,15 +1748,17 @@ public final class BluetoothAdapter {
    @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
    public @NonNull List<ParcelUuid> getUuidsList() {
        List<ParcelUuid> defaultValue = new ArrayList<>();
        if (getState() != STATE_ON || mService == null) {
        if (getState() != STATE_ON) {
            return defaultValue;
        }
        mServiceLock.readLock().lock();
        try {
            if (mService != null) {
                final SynchronousResultReceiver<List<ParcelUuid>> recv =
                        SynchronousResultReceiver.get();
                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 {
@@ -3923,14 +3928,17 @@ public final class BluetoothAdapter {

    private final IBluetoothManagerCallback mManagerCallback =
            new IBluetoothManagerCallback.Stub() {
                public void onBluetoothServiceUp(IBluetooth bluetoothService) {
                    Lock l = mServiceLock.writeLock();
                    l.lock();
                public void onBluetoothServiceUp(@NonNull IBluetooth bluetoothService) {
                    requireNonNull(bluetoothService, "bluetoothService cannot be null");
                    mServiceLock.writeLock().lock();
                    try {
                        mService = bluetoothService;
                    } finally {
                        l.unlock();
                        // lock downgrade is possible in ReentrantReadWriteLock
                        mServiceLock.readLock().lock();
                        mServiceLock.writeLock().unlock();
                    }
                    try {
                        synchronized (mMetadataListeners) {
                            mMetadataListeners.forEach((device, pair) -> {
                                try {
@@ -3952,8 +3960,8 @@ public final class BluetoothAdapter {
                                    final SynchronousResultReceiver recv =
                                        SynchronousResultReceiver.get();
                                    mService.registerPreferredAudioProfilesChangedCallback(
                                        mPreferredAudioProfilesChangedCallback, mAttributionSource,
                                        recv);
                                            mPreferredAudioProfilesChangedCallback,
                                            mAttributionSource, recv);
                                    recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(
                                            BluetoothStatusCodes.ERROR_UNKNOWN);
                                } catch (RemoteException | TimeoutException e) {
@@ -3968,8 +3976,8 @@ public final class BluetoothAdapter {
                                    final SynchronousResultReceiver recv =
                                        SynchronousResultReceiver.get();
                                    mService.registerBluetoothQualityReportReadyCallback(
                                        mBluetoothQualityReportReadyCallback, mAttributionSource,
                                        recv);
                                            mBluetoothQualityReportReadyCallback,
                                            mAttributionSource, recv);
                                    recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(
                                            BluetoothStatusCodes.ERROR_UNKNOWN);
                                } catch (RemoteException | TimeoutException e) {
@@ -3978,11 +3986,13 @@ public final class BluetoothAdapter {
                                }
                            }
                        }
                    } finally {
                        mServiceLock.readLock().unlock();
                    }
                }

                public void onBluetoothServiceDown() {
                    Lock l = mServiceLock.writeLock();
                    l.lock();
                    mServiceLock.writeLock().lock();
                    try {
                        mService = null;
                        if (mLeScanClients != null) {
@@ -3995,7 +4005,7 @@ public final class BluetoothAdapter {
                            mBluetoothLeScanner.cleanup();
                        }
                    } finally {
                        l.unlock();
                        mServiceLock.writeLock().unlock();
                    }
                }

@@ -4156,13 +4166,18 @@ public final class BluetoothAdapter {
            Log.w(TAG, "generateLocalOobData(): Adapter isn't enabled!");
            callback.onError(BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED);
        } else {
            mServiceLock.readLock().lock();
            try {
                if (mService != null) {
                    final SynchronousResultReceiver recv = SynchronousResultReceiver.get();
                    mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback,
                            executor), mAttributionSource, recv);
                    recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                }
            } catch (RemoteException | TimeoutException e) {
                Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
            } finally {
                mServiceLock.readLock().unlock();
            }
        }
    }
@@ -4729,11 +4744,6 @@ public final class BluetoothAdapter {
            @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) {
        if (DBG) Log.d(TAG, "addOnMetadataChangedListener()");

        final IBluetooth service = mService;
        if (service == null) {
            Log.e(TAG, "Bluetooth is not enabled. Cannot register metadata listener");
            return false;
        }
        if (listener == null) {
            throw new NullPointerException("listener is null");
        }
@@ -4744,6 +4754,14 @@ public final class BluetoothAdapter {
            throw new NullPointerException("executor is null");
        }

        mServiceLock.readLock().lock();
        try {
            if (mService == null) {
                Log.e(TAG, "Bluetooth is not enabled. Cannot register metadata listener");
                return false;
            }


            synchronized (mMetadataListeners) {
                List<Pair<OnMetadataChangedListener, Executor>> listenerList =
                    mMetadataListeners.get(device);
@@ -4759,13 +4777,14 @@ public final class BluetoothAdapter {
                    }
                }

            Pair<OnMetadataChangedListener, Executor> listenerPair = new Pair(listener, executor);
                Pair<OnMetadataChangedListener, Executor> listenerPair =
                        new Pair(listener, executor);
                listenerList.add(listenerPair);

                boolean ret = false;
                try {
                    final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get();
                service.registerMetadataListener(mBluetoothMetadataListener, device,
                    mService.registerMetadataListener(mBluetoothMetadataListener, device,
                            mAttributionSource, recv);
                    ret = recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(false);
                } catch (RemoteException | TimeoutException e) {
@@ -4782,6 +4801,9 @@ public final class BluetoothAdapter {
                }
                return ret;
            }
        } finally {
            mServiceLock.readLock().unlock();
        }
    }

    /**
@@ -4826,19 +4848,21 @@ public final class BluetoothAdapter {
                // Unregister to Bluetooth service if all listeners are removed from
                // the registered device
                mMetadataListeners.remove(device);
                final IBluetooth service = mService;
                if (service == null) {
                    // Bluetooth is OFF, do nothing to Bluetooth service.
                    return true;
                }
                mServiceLock.readLock().lock();
                try {
                    final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get();
                    service.unregisterMetadataListener(device, mAttributionSource, recv);
                    if (mService != null) {
                        final SynchronousResultReceiver<Boolean> recv =
                                SynchronousResultReceiver.get();
                        mService.unregisterMetadataListener(device, mAttributionSource, recv);
                        return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(false);
                    }
                } catch (RemoteException | TimeoutException e) {
                    Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
                    return false;
                } finally {
                    mServiceLock.readLock().unlock();
                }

            }
        }
        return true;