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

Commit abe93957 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Introduce a BluetoothConnectionCallback that will fire off events when...

Merge "Introduce a BluetoothConnectionCallback that will fire off events when a device is connected or disconnected."
parents ac6c1a40 6a221b5f
Loading
Loading
Loading
Loading
+130 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
package android.bluetooth;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -686,6 +687,8 @@ public final class BluetoothAdapter {
    private final Map<LeScanCallback, ScanCallback> mLeScanClients;
    private static final Map<BluetoothDevice, List<Pair<OnMetadataChangedListener, Executor>>>
                sMetadataListeners = new HashMap<>();
    private final Map<BluetoothConnectionCallback, Executor>
            mBluetoothConnectionCallbackExecutorMap = new HashMap<>();

    /**
     * Bluetooth metadata listener. Overrides the default BluetoothMetadataListener
@@ -3538,6 +3541,133 @@ public final class BluetoothAdapter {
                @Nullable byte[] value);
    }

    private final IBluetoothConnectionCallback mConnectionCallback =
            new IBluetoothConnectionCallback.Stub() {
        @Override
        public void onDeviceConnected(BluetoothDevice device) {
            for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
                    mBluetoothConnectionCallbackExecutorMap.entrySet()) {
                BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
                Executor executor = callbackExecutorEntry.getValue();
                executor.execute(() -> callback.onDeviceConnected(device));
            }
        }

        @Override
        public void onDeviceDisconnected(BluetoothDevice device) {
            for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
                    mBluetoothConnectionCallbackExecutorMap.entrySet()) {
                BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
                Executor executor = callbackExecutorEntry.getValue();
                executor.execute(() -> callback.onDeviceDisconnected(device));
            }
        }
    };

    /**
     * Registers the BluetoothConnectionCallback to receive callback events when a bluetooth device
     * (classic or low energy) is connected or disconnected.
     *
     * @param executor is the callback executor
     * @param callback is the connection callback you wish to register
     * @return true if the callback was registered successfully, false otherwise
     * @throws IllegalArgumentException if the callback is already registered
     * @hide
     */
    public boolean registerBluetoothConnectionCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull BluetoothConnectionCallback callback) {
        if (DBG) Log.d(TAG, "registerBluetoothConnectionCallback()");
        if (callback == null) {
            return false;
        }

        // If the callback map is empty, we register the service-to-app callback
        if (mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
            try {
                mServiceLock.readLock().lock();
                if (mService != null) {
                    if (!mService.registerBluetoothConnectionCallback(mConnectionCallback)) {
                        return false;
                    }
                }
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
                mBluetoothConnectionCallbackExecutorMap.remove(callback);
            } finally {
                mServiceLock.readLock().unlock();
            }
        }

        // Adds the passed in callback to our map of callbacks to executors
        synchronized (mBluetoothConnectionCallbackExecutorMap) {
            if (mBluetoothConnectionCallbackExecutorMap.containsKey(callback)) {
                throw new IllegalArgumentException("This callback has already been registered");
            }
            mBluetoothConnectionCallbackExecutorMap.put(callback, executor);
        }

        return true;
    }

    /**
     * Unregisters the BluetoothConnectionCallback that was previously registered by the application
     *
     * @param callback is the connection callback you wish to unregister
     * @return true if the callback was unregistered successfully, false otherwise
     * @hide
     */
    public boolean unregisterBluetoothConnectionCallback(
            @NonNull BluetoothConnectionCallback callback) {
        if (DBG) Log.d(TAG, "unregisterBluetoothConnectionCallback()");
        if (callback == null) {
            return false;
        }

        synchronized (mBluetoothConnectionCallbackExecutorMap) {
            if (mBluetoothConnectionCallbackExecutorMap.remove(callback) != null) {
                return false;
            }
        }

        if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) {
            return true;
        }

        // If the callback map is empty, we unregister the service-to-app callback
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                return mService.unregisterBluetoothConnectionCallback(mConnectionCallback);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.readLock().unlock();
        }

        return false;
    }

    /**
     * This abstract class is used to implement callbacks for when a bluetooth classic or Bluetooth
     * Low Energy (BLE) device is either connected or disconnected.
     *
     * @hide
     */
    public abstract class BluetoothConnectionCallback {
        /**
         * Callback triggered when a bluetooth device (classic or BLE) is connected
         * @param device is the connected bluetooth device
         */
        public void onDeviceConnected(BluetoothDevice device) {}

        /**
         * Callback triggered when a bluetooth device (classic or BLE) is disconnected
         * @param device is the disconnected bluetooth device
         */
        public void onDeviceDisconnected(BluetoothDevice device) {}
    }

    /**
     * Converts old constant of priority to the new for connection policy
     *