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

Commit 3cae7eb7 authored by Sungsoo Lim's avatar Sungsoo Lim Committed by Gerrit Code Review
Browse files

Merge "Stop using broadcast intent of BluetoothAdapter.ACTION_STATE_CHANGED" into main

parents f2a88e6e b589c7ed
Loading
Loading
Loading
Loading
+7 −35
Original line number Diff line number Diff line
@@ -26,10 +26,6 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothSinkAudioPolicy;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
@@ -101,7 +97,7 @@ import java.util.Set;
 *      will have no impact. E.g., music will continue streaming over the
 *      active Bluetooth device.
 */
public class ActiveDeviceManager {
public class ActiveDeviceManager implements AdapterService.BluetoothStateCallback {
    private static final String TAG = "ActiveDeviceManager";
    private static final boolean DBG = true;
    @VisibleForTesting
@@ -144,25 +140,10 @@ public class ActiveDeviceManager {
    private BluetoothDevice mClassicDeviceToBeActivated = null;
    private BluetoothDevice mClassicDeviceNotToBeActivated = null;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
        public void onReceive(Context context, Intent intent) {
            if (DBG) {
                Log.d(TAG, "Received intent: action=" + intent.getAction() + ", extras="
                        + intent.getExtras());
            }
            String action = intent.getAction();
            if (action == null) {
                Log.e(TAG, "Received intent with null action");
                return;
            }

            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                int currentState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                mHandler.post(() -> handleAdapterStateChanged(currentState));
    public void onBluetoothStateChange(int prevState, int newState) {
        mHandler.post(() -> handleAdapterStateChanged(newState));
    }
        }
    };

    /**
     * Called when A2DP connection state changed by A2dpService
@@ -835,12 +816,8 @@ public class ActiveDeviceManager {
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());

        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        mAdapterService.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED);

        mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
        mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this);
    }

    void cleanup() {
@@ -849,7 +826,7 @@ public class ActiveDeviceManager {
        }

        mAudioManager.unregisterAudioDeviceCallback(mAudioManagerAudioDeviceCallback);
        mAdapterService.unregisterReceiver(mReceiver);
        mAdapterService.unregisterBluetoothStateCallback(this);
        if (mHandlerThread != null) {
            mHandlerThread.quit();
            mHandlerThread = null;
@@ -1191,11 +1168,6 @@ public class ActiveDeviceManager {
        }
    }

    @VisibleForTesting
    BroadcastReceiver getBroadcastReceiver() {
        return mReceiver;
    }

    @VisibleForTesting
    BluetoothDevice getA2dpActiveDevice() {
        return mA2dpActiveDevice;
+47 −15
Original line number Diff line number Diff line
@@ -327,7 +327,8 @@ public class AdapterService extends Service {
    private final Map<Integer, PendingAudioProfilePreferenceRequest>
            mCsipGroupsPendingAudioProfileChanges = new HashMap<>();
    // Only BluetoothManagerService should be registered
    private RemoteCallbackList<IBluetoothCallback> mCallbacks;
    private RemoteCallbackList<IBluetoothCallback> mRemoteCallbacks;
    private final Map<BluetoothStateCallback, Executor> mLocalCallbacks = new ConcurrentHashMap<>();
    private int mCurrentRequestId;
    private boolean mQuietmode = false;
    private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>();
@@ -641,7 +642,7 @@ public class AdapterService extends Service {
                new RemoteCallbackList<IBluetoothPreferredAudioProfilesCallback>();
        mBluetoothQualityReportReadyCallbacks =
                new RemoteCallbackList<IBluetoothQualityReportReadyCallback>();
        mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
        mRemoteCallbacks = new RemoteCallbackList<IBluetoothCallback>();
        // Load the name and address
        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
@@ -1035,8 +1036,9 @@ public class AdapterService extends Service {
    void updateAdapterState(int prevState, int newState) {
        mAdapterProperties.setState(newState);
        invalidateBluetoothGetStateCache();
        if (mCallbacks != null) {
            int n = mCallbacks.beginBroadcast();

        if (mRemoteCallbacks != null) {
            int n = mRemoteCallbacks.beginBroadcast();
            debugLog(
                    "updateAdapterState() - Broadcasting state "
                            + BluetoothAdapter.nameForState(newState)
@@ -1045,12 +1047,18 @@ public class AdapterService extends Service {
                            + " receivers.");
            for (int i = 0; i < n; i++) {
                try {
                    mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState);
                    mRemoteCallbacks
                            .getBroadcastItem(i)
                            .onBluetoothStateChange(prevState, newState);
                } catch (RemoteException e) {
                    debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");
                }
            }
            mCallbacks.finishBroadcast();
            mRemoteCallbacks.finishBroadcast();
        }

        for (Map.Entry<BluetoothStateCallback, Executor> e : mLocalCallbacks.entrySet()) {
            e.getValue().execute(() -> e.getKey().onBluetoothStateChange(prevState, newState));
        }

        // Turn the Adapter all the way off if we are disabling and the snoop log setting changed.
@@ -1339,8 +1347,8 @@ public class AdapterService extends Service {
            mBluetoothQualityReportReadyCallbacks.kill();
        }

        if (mCallbacks != null) {
            mCallbacks.kill();
        if (mRemoteCallbacks != null) {
            mRemoteCallbacks.kill();
        }
    }

@@ -4062,7 +4070,7 @@ public class AdapterService extends Service {

            enforceBluetoothPrivilegedPermission(service);

            service.registerCallback(callback);
            service.registerRemoteCallback(callback);
        }

        @Override
@@ -4087,7 +4095,7 @@ public class AdapterService extends Service {
        private void unregisterCallback(IBluetoothCallback callback, AttributionSource source) {
            AdapterService service = getService();
            if (service == null
                    || service.mCallbacks == null
                    || service.mRemoteCallbacks == null
                    || !callerIsSystemOrActiveOrManagedUser(service, TAG, "unregisterCallback")
                    || !Utils.checkConnectPermissionForDataDelivery(service, source, TAG)) {
                return;
@@ -4095,7 +4103,7 @@ public class AdapterService extends Service {

            enforceBluetoothPrivilegedPermission(service);

            service.unregisterCallback(callback);
            service.unregisterRemoteCallback(callback);
        }

        @Override
@@ -6689,14 +6697,24 @@ public class AdapterService extends Service {
        return mAdapterProperties.isA2dpOffloadEnabled();
    }

    /** Register a bluetooth state callback */
    public void registerBluetoothStateCallback(Executor executor, BluetoothStateCallback callback) {
        mLocalCallbacks.put(callback, executor);
    }

    /** Unregister a bluetooth state callback */
    public void unregisterBluetoothStateCallback(BluetoothStateCallback callback) {
        mLocalCallbacks.remove(callback);
    }

    @VisibleForTesting
    void registerCallback(IBluetoothCallback callback) {
        mCallbacks.register(callback);
    void registerRemoteCallback(IBluetoothCallback callback) {
        mRemoteCallbacks.register(callback);
    }

    @VisibleForTesting
    void unregisterCallback(IBluetoothCallback callback) {
        mCallbacks.unregister(callback);
    void unregisterRemoteCallback(IBluetoothCallback callback) {
        mRemoteCallbacks.unregister(callback);
    }

    @VisibleForTesting
@@ -7384,6 +7402,20 @@ public class AdapterService extends Service {
        }
    }

    /** A callback that will be called when AdapterState is changed */
    public interface BluetoothStateCallback {
        /**
         * Called when the status of bluetooth adapter is changing. {@code prevState} and {@code
         * newState} takes one of following values defined in BluetoothAdapter.java: STATE_OFF,
         * STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, STATE_BLE_TURNING_ON, STATE_BLE_ON,
         * STATE_BLE_TURNING_OFF
         *
         * @param prevState the previous Bluetooth state.
         * @param newState the new Bluetooth state.
         */
        void onBluetoothStateChange(int prevState, int newState);
    }

    /**
     * Obfuscate Bluetooth MAC address into a PII free ID string
     *
+19 −23
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@ package com.android.bluetooth.sap;
import static android.Manifest.permission.BLUETOOTH_CONNECT;

import android.annotation.RequiresPermission;
import android.annotation.TargetApi;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
@@ -19,7 +18,6 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
@@ -43,7 +41,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class SapService extends ProfileService {
public class SapService extends ProfileService implements AdapterService.BluetoothStateCallback {

    private static final String SDP_SAP_SERVICE_NAME = "SIM Access";
    private static final int SDP_SAP_VERSION = 0x0102;
@@ -680,7 +678,6 @@ public class SapService extends ProfileService {
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        filter.addAction(USER_CONFIRM_TIMEOUT_ACTION);

@@ -692,6 +689,7 @@ public class SapService extends ProfileService {
        }
        mInterrupted = false;
        mAdapterService = AdapterService.getAdapterService();
        mAdapterService.registerBluetoothStateCallback(getMainExecutor(), this);
        // start RFCOMM listener
        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        setSapService(this);
@@ -712,6 +710,7 @@ public class SapService extends ProfileService {
        } catch (Exception e) {
            Log.w(TAG, "Unable to unregister sap receiver", e);
        }
        mAdapterService.unregisterBluetoothStateCallback(this);
        setState(BluetoothSap.STATE_DISCONNECTED, BluetoothSap.RESULT_CANCELED);
        sendShutdownMessage();
        return true;
@@ -726,6 +725,22 @@ public class SapService extends ProfileService {
        }
    }

    @Override
    public void onBluetoothStateChange(int prevState, int newState) {
        if (newState == BluetoothAdapter.STATE_TURNING_OFF) {
            if (DEBUG) {
                Log.d(TAG, "STATE_TURNING_OFF");
            }
            sendShutdownMessage();
        } else if (newState == BluetoothAdapter.STATE_ON) {
            if (DEBUG) {
                Log.d(TAG, "STATE_ON");
            }
            // start RFCOMM listener
            mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        }
    }

    /**
     * Get the current instance of {@link SapService}
     *
@@ -827,25 +842,6 @@ public class SapService extends ProfileService {
                Log.v(TAG, "onReceive");
            }
            String action = intent.getAction();
            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                int state =
                        intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                if (state == BluetoothAdapter.STATE_TURNING_OFF) {
                    if (DEBUG) {
                        Log.d(TAG, "STATE_TURNING_OFF");
                    }
                    sendShutdownMessage();
                } else if (state == BluetoothAdapter.STATE_ON) {
                    if (DEBUG) {
                        Log.d(TAG, "STATE_ON");
                    }
                    // start RFCOMM listener
                    mSessionStatusHandler.sendMessage(
                            mSessionStatusHandler.obtainMessage(START_LISTENER));
                }
                return;
            }

            if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
                Log.v(TAG, " - Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY");

+2 −2
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ public class AdapterServiceRestartTest {

        mLooper.dispatchAll();

        mAdapterService.registerCallback(mIBluetoothCallback);
        mAdapterService.registerRemoteCallback(mIBluetoothCallback);

        mAdapterConfig = TestUtils.readAdapterConfig();
        assertThat(mAdapterConfig).isNotNull();
@@ -243,7 +243,7 @@ public class AdapterServiceRestartTest {
        // Restores the foregroundUserId to the ID prior to the test setup
        Utils.setForegroundUserId(mForegroundUserId);

        mAdapterService.unregisterCallback(mIBluetoothCallback);
        mAdapterService.unregisterRemoteCallback(mIBluetoothCallback);
        mAdapterService.cleanup();
    }

+6 −6
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ public class AdapterServiceTest {

        mLooper.dispatchAll();

        mAdapterService.registerCallback(mIBluetoothCallback);
        mAdapterService.registerRemoteCallback(mIBluetoothCallback);

        mAdapterConfig = TestUtils.readAdapterConfig();
        assertThat(mAdapterConfig).isNotNull();
@@ -351,7 +351,7 @@ public class AdapterServiceTest {
        Utils.setForegroundUserId(mForegroundUserId);

        mAdapterService.cleanup();
        mAdapterService.unregisterCallback(mIBluetoothCallback);
        mAdapterService.unregisterRemoteCallback(mIBluetoothCallback);
    }

    /**
@@ -489,7 +489,7 @@ public class AdapterServiceTest {
        IBluetoothCallback callback = mock(IBluetoothCallback.class);
        Binder binder = mock(Binder.class);
        doReturn(binder).when(callback).asBinder();
        adapter.registerCallback(callback);
        adapter.registerRemoteCallback(callback);

        assertThat(adapter.getState()).isEqualTo(STATE_OFF);

@@ -518,7 +518,7 @@ public class AdapterServiceTest {
        verifyStateChange(callback, STATE_TURNING_ON, STATE_ON);

        assertThat(adapter.getState()).isEqualTo(STATE_ON);
        adapter.unregisterCallback(callback);
        adapter.unregisterRemoteCallback(callback);
        Log.e(TAG, "doEnable() complete success");
    }

@@ -543,7 +543,7 @@ public class AdapterServiceTest {
        IBluetoothCallback callback = mock(IBluetoothCallback.class);
        Binder binder = mock(Binder.class);
        doReturn(binder).when(callback).asBinder();
        adapter.registerCallback(callback);
        adapter.registerRemoteCallback(callback);

        assertThat(adapter.getState()).isEqualTo(STATE_ON);

@@ -561,7 +561,7 @@ public class AdapterServiceTest {
        looper.stopAutoDispatch(); // stop autoDispatch ASAP

        assertThat(adapter.getState()).isEqualTo(STATE_OFF);
        adapter.unregisterCallback(callback);
        adapter.unregisterRemoteCallback(callback);
        Log.e(TAG, "doDisable() complete success");
    }