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

Commit 7596e40c authored by Grzegorz Kolodziejczyk's avatar Grzegorz Kolodziejczyk Committed by Automerger Merge Worker
Browse files

Merge "Re-register callbacks when service is connected" am: ed7a08d1 am: 188455b9

parents 8c6d6ad5 188455b9
Loading
Loading
Loading
Loading
+38 −47
Original line number Diff line number Diff line
@@ -65,6 +65,43 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable

    private CloseGuard mCloseGuard;

    private final class HapClientServiceListener extends ForwardingServiceListener {
        HapClientServiceListener(ServiceListener listener) {
            super(listener);
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            try {
                if (profile == HAP_CLIENT) {
                    // re-register the service-to-app callback
                    synchronized (mCallbackExecutorMap) {
                        if (mCallbackExecutorMap.isEmpty()) {
                            return;
                        }

                        try {
                            final IBluetoothHapClient service = getService();
                            if (service != null) {
                                final SynchronousResultReceiver<Integer> recv =
                                        SynchronousResultReceiver.get();
                                service.registerCallback(mCallback, mAttributionSource, recv);
                                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                            }
                        } catch (TimeoutException e) {
                            Log.e(TAG, e.toString() + "\n"
                                    + Log.getStackTraceString(new Throwable()));
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            } finally {
                super.onServiceConnected(profile, proxy);
            }
        }
    }

    /**
     * This class provides callbacks mechanism for the BluetoothHapClient profile.
     *
@@ -470,34 +507,6 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
                }
            };

    @SuppressLint("AndroidFrameworkBluetoothPermission")
    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
            new IBluetoothStateChangeCallback.Stub() {
                public void onBluetoothStateChange(boolean up) {
                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                    if (up) {
                        // re-register the service-to-app callback
                        synchronized (mCallbackExecutorMap) {
                            if (mCallbackExecutorMap.isEmpty()) return;

                            try {
                                final IBluetoothHapClient service = getService();
                                if (service != null) {
                                    final SynchronousResultReceiver<Integer> recv =
                                            SynchronousResultReceiver.get();
                                    service.registerCallback(mCallback, mAttributionSource, recv);
                                    recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                                }
                            } catch (TimeoutException e) {
                                Log.e(TAG, e.toString() + "\n"
                                        + Log.getStackTraceString(new Throwable()));
                            } catch (RemoteException e) {
                                throw e.rethrowFromSystemServer();
                            }
                        }
                    }
                }
            };

    /**
     * Create a BluetoothHapClient proxy object for interacting with the local
@@ -506,16 +515,7 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
    /*package*/ BluetoothHapClient(Context context, ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAttributionSource = mAdapter.getAttributionSource();
        mProfileConnector.connect(context, listener);

        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        mProfileConnector.connect(context, new HapClientServiceListener(listener));

        mCloseGuard = new CloseGuard();
        mCloseGuard.open("close");
@@ -536,15 +536,6 @@ public final class BluetoothHapClient implements BluetoothProfile, AutoCloseable
    public void close() {
        if (VDBG) log("close()");

        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }

        mProfileConnector.disconnect();
    }

+36 −50
Original line number Diff line number Diff line
@@ -69,6 +69,41 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {

    private CloseGuard mCloseGuard;

    private final class LeAudioServiceListener extends ForwardingServiceListener {
        LeAudioServiceListener(ServiceListener listener) {
            super(listener);
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            try {
                if (profile == LE_AUDIO) {
                    // re-register the service-to-app callback
                    synchronized (mCallbackExecutorMap) {
                        if (mCallbackExecutorMap.isEmpty()) {
                            return;
                        }
                        try {
                            final IBluetoothLeAudio service = getService();
                            if (service != null) {
                                final SynchronousResultReceiver<Integer> recv =
                                        SynchronousResultReceiver.get();
                                service.registerCallback(mCallback, mAttributionSource, recv);
                                recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
                            }
                        } catch (TimeoutException e) {
                            Log.e(TAG, "Failed to register callback", e);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            } finally {
                super.onServiceConnected(profile, proxy);
            }
        }
    }

    /**
     * This class provides a callback that is invoked when audio codec config changes on
     * the remote device.
@@ -640,37 +675,6 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
                }
    };


    @SuppressLint("AndroidFrameworkBluetoothPermission")
    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
            new IBluetoothStateChangeCallback.Stub() {
                public void onBluetoothStateChange(boolean up) {
                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                    if (up) {
                        // re-register the service-to-app callback
                        synchronized (mCallbackExecutorMap) {
                            if (!mCallbackExecutorMap.isEmpty()) {
                                try {
                                    final IBluetoothLeAudio service = getService();
                                    if (service != null) {
                                        final SynchronousResultReceiver<Integer> recv =
                                                SynchronousResultReceiver.get();
                                        service.registerCallback(mCallback,
                                                mAttributionSource, recv);
                                        recv.awaitResultNoInterrupt(getSyncTimeout())
                                                .getValue(null);
                                    }
                                } catch (TimeoutException e) {
                                    Log.e(TAG, "Failed to register callback", e);
                                } catch (RemoteException e) {
                                    throw e.rethrowFromSystemServer();
                                }
                            }
                        }
                    }
                }
            };

    /**
     * Create a BluetoothLeAudio proxy object for interacting with the local
     * Bluetooth LeAudio service.
@@ -679,16 +683,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
            BluetoothAdapter adapter) {
        mAdapter = adapter;
        mAttributionSource = adapter.getAttributionSource();
        mProfileConnector.connect(context, listener);

        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        mProfileConnector.connect(context, new LeAudioServiceListener(listener));

        mCloseGuard = new CloseGuard();
        mCloseGuard.open("close");
@@ -697,15 +692,6 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
    /** @hide */
    @Override
    public void close() {
        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }

        mProfileConnector.disconnect();
    }

+34 −45
Original line number Diff line number Diff line
@@ -170,15 +170,20 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi
        }
    };

    @SuppressLint("AndroidFrameworkBluetoothPermission")
    private final IBluetoothStateChangeCallback mBluetoothStateChangeCallback =
            new IBluetoothStateChangeCallback.Stub() {
                public void onBluetoothStateChange(boolean up) {
                    if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up);
                    if (up) {
    private final class BluetoothLeBroadcastServiceListener extends ForwardingServiceListener {
        BluetoothLeBroadcastServiceListener(ServiceListener listener) {
            super(listener);
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            try {
                if (profile == LE_AUDIO_BROADCAST) {
                    // re-register the service-to-app callback
                    synchronized (mCallbackExecutorMap) {
                            if (!mCallbackExecutorMap.isEmpty()) {
                        if (mCallbackExecutorMap.isEmpty()) {
                            return;
                        }
                        try {
                            final IBluetoothLeAudio service = getService();
                            if (service != null) {
@@ -197,9 +202,11 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi
                        }
                    }
                }
            } finally {
                super.onServiceConnected(profile, proxy);
            }
        }
    }
            };

    /**
     * Interface for receiving events related to Broadcast Source
@@ -329,16 +336,7 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi
    /*package*/ BluetoothLeBroadcast(Context context, BluetoothProfile.ServiceListener listener) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAttributionSource = mAdapter.getAttributionSource();
        mProfileConnector.connect(context, listener);

        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.registerStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        mProfileConnector.connect(context, new BluetoothLeBroadcastServiceListener(listener));

        mCloseGuard = new CloseGuard();
        mCloseGuard.open("close");
@@ -878,15 +876,6 @@ public final class BluetoothLeBroadcast implements AutoCloseable, BluetoothProfi
    public void close() {
        if (VDBG) log("close()");

        IBluetoothManager mgr = mAdapter.getBluetoothManager();
        if (mgr != null) {
            try {
                mgr.unregisterStateChangeCallback(mBluetoothStateChangeCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }

        mProfileConnector.disconnect();
    }

+28 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.bluetooth;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresNoPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -415,6 +416,33 @@ public interface BluetoothProfile {
        void onServiceDisconnected(int profile);
    }

    /**
     * A service listener that forwards methods calls to the given listener.
     * This can be used to override specific method.
     * @hide
     */
    class ForwardingServiceListener implements ServiceListener {
        private final ServiceListener mListener;

        ForwardingServiceListener(@Nullable ServiceListener listener) {
            mListener = listener;
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (mListener != null) {
                mListener.onServiceConnected(profile, proxy);
            }
        }

        @Override
        public void onServiceDisconnected(int profile) {
            if (mListener != null) {
                mListener.onServiceDisconnected(profile);
            }
        }
    }

    /**
     * Convert an integer value of connection state into human readable string
     *