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

Commit 64a7f09f authored by Adrian Roos's avatar Adrian Roos Committed by Gerrit Code Review
Browse files

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

parents ad67bb6f f0fe6aad
Loading
Loading
Loading
Loading
+35 −7
Original line number Diff line number Diff line
@@ -26,6 +26,10 @@ 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;
@@ -97,7 +101,7 @@ import java.util.Set;
 *      will have no impact. E.g., music will continue streaming over the
 *      active Bluetooth device.
 */
public class ActiveDeviceManager implements AdapterService.BluetoothStateCallback {
public class ActiveDeviceManager {
    private static final String TAG = "ActiveDeviceManager";
    private static final boolean DBG = true;
    @VisibleForTesting
@@ -140,10 +144,25 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
    private BluetoothDevice mClassicDeviceToBeActivated = null;
    private BluetoothDevice mClassicDeviceNotToBeActivated = null;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
    public void onBluetoothStateChange(int prevState, int newState) {
        mHandler.post(() -> handleAdapterStateChanged(newState));
        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));
            }
        }
    };

    /**
     * Called when A2DP connection state changed by A2dpService
@@ -816,8 +835,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
        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() {
@@ -826,7 +849,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
        }

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

    @VisibleForTesting
    BroadcastReceiver getBroadcastReceiver() {
        return mReceiver;
    }

    @VisibleForTesting
    BluetoothDevice getA2dpActiveDevice() {
        return mA2dpActiveDevice;
+15 −51
Original line number Diff line number Diff line
@@ -105,7 +105,6 @@ import android.provider.DeviceConfig;
import android.provider.Settings;
import android.sysprop.BluetoothProperties;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;
import android.util.SparseArray;
@@ -334,8 +333,7 @@ public class AdapterService extends Service {
    private final Map<Integer, PendingAudioProfilePreferenceRequest>
            mCsipGroupsPendingAudioProfileChanges = new HashMap<>();
    // Only BluetoothManagerService should be registered
    private RemoteCallbackList<IBluetoothCallback> mRemoteCallbacks;
    private final Map<BluetoothStateCallback, Executor> mLocalCallbacks = new ArrayMap<>();
    private RemoteCallbackList<IBluetoothCallback> mCallbacks;
    private int mCurrentRequestId;
    private boolean mQuietmode = false;
    private HashMap<String, CallerInfo> mBondAttemptCallerInfo = new HashMap<>();
@@ -652,7 +650,7 @@ public class AdapterService extends Service {
                new RemoteCallbackList<IBluetoothPreferredAudioProfilesCallback>();
        mBluetoothQualityReportReadyCallbacks =
                new RemoteCallbackList<IBluetoothQualityReportReadyCallback>();
        mRemoteCallbacks = new RemoteCallbackList<IBluetoothCallback>();
        mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
        // Load the name and address
        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
        getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
@@ -1049,15 +1047,8 @@ public class AdapterService extends Service {
    void updateAdapterState(int prevState, int newState) {
        mAdapterProperties.setState(newState);
        invalidateBluetoothGetStateCache();

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

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

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

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

@@ -4092,7 +4081,7 @@ public class AdapterService extends Service {

            enforceBluetoothPrivilegedPermission(service);

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

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

            enforceBluetoothPrivilegedPermission(service);

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

        @Override
@@ -6719,28 +6708,14 @@ public class AdapterService extends Service {
        return mAdapterProperties.isA2dpOffloadEnabled();
    }

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

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

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

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

    @VisibleForTesting
@@ -7467,17 +7442,6 @@ 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
         *
         * @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
     *
+56 −45
Original line number Diff line number Diff line
@@ -36,10 +36,12 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevicePicker;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.CharArrayBuffer;
import android.database.ContentObserver;
import android.database.Cursor;
@@ -70,11 +72,11 @@ import java.util.Date;
import java.util.Locale;

/**
 * Performs the background Bluetooth OPP transfer. It also starts thread to accept incoming OPP
 * connection.
 * Performs the background Bluetooth OPP transfer. It also starts thread to
 * accept incoming OPP connection.
 */
public class BluetoothOppService extends ProfileService
        implements IObexConnectionHandler, AdapterService.BluetoothStateCallback {

public class BluetoothOppService extends ProfileService implements IObexConnectionHandler {
    private static final boolean D = Constants.DEBUG;
    private static final boolean V = Constants.VERBOSE;

@@ -227,6 +229,10 @@ public class BluetoothOppService extends ProfileService
        mBatches = new ArrayList();
        mBatchId = 1;

        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        registerReceiver(mBluetoothReceiver, filter);

        if (V) {
            BluetoothOppPreference preference = BluetoothOppPreference.getInstance(this);
            if (preference != null) {
@@ -259,7 +265,6 @@ public class BluetoothOppService extends ProfileService
        }.start();

        mAdapterService = AdapterService.getAdapterService();
        mAdapterService.registerBluetoothStateCallback((command) -> mHandler.post(command), this);
        mObserver = new BluetoothShareContentObserver();
        getContentResolver().registerContentObserver(BluetoothShare.CONTENT_URI, true, mObserver);
        mNotifier = new BluetoothOppNotification(this);
@@ -278,7 +283,6 @@ public class BluetoothOppService extends ProfileService
            Log.w(TAG, "stop() called before start()");
            return true;
        }
        mAdapterService.unregisterBluetoothStateCallback(this);
        mAdapterService.notifyActivityAttributionInfo(
                getAttributionSource(),
                AdapterService.ACTIVITY_ATTRIBUTION_NO_ACTIVE_DEVICE_ADDRESS);
@@ -541,9 +545,35 @@ public class BluetoothOppService extends ProfileService
        }
    }

    private void unregisterReceivers() {
        try {
            if (mObserver != null) {
                getContentResolver().unregisterContentObserver(mObserver);
                mObserver = null;
            }
            unregisterReceiver(mBluetoothReceiver);
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "unregisterReceivers " + e.toString());
        }
    }

    /* suppose we auto accept an incoming OPUSH connection */
    private void createServerSession(ObexTransport transport) {
        mServerSession = new BluetoothOppObexServerSession(this, transport, this);
        mServerSession.preStart();
        if (D) {
            Log.d(TAG, "Get ServerSession " + mServerSession.toString() + " for incoming connection"
                    + transport.toString());
        }
    }

    private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
        @Override
    public void onBluetoothStateChange(int prevState, int newState) {
        switch (newState) {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) {
                    case BluetoothAdapter.STATE_ON:
                        if (V) {
                            Log.v(TAG, "Bluetooth state changed: STATE_ON");
@@ -552,24 +582,24 @@ public class BluetoothOppService extends ProfileService
                        // If this is within a sending process, continue the handle
                        // logic to display device picker dialog.
                        synchronized (this) {
                    if (BluetoothOppManager.getInstance(this).mSendingFlag) {
                            if (BluetoothOppManager.getInstance(context).mSendingFlag) {
                                // reset the flags
                        BluetoothOppManager.getInstance(this).mSendingFlag = false;
                                BluetoothOppManager.getInstance(context).mSendingFlag = false;

                                Intent in1 = new Intent(BluetoothDevicePicker.ACTION_LAUNCH);
                                in1.putExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
                        in1.putExtra(
                                BluetoothDevicePicker.EXTRA_FILTER_TYPE,
                                in1.putExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
                                        BluetoothDevicePicker.FILTER_TYPE_TRANSFER);
                        in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE, getPackageName());
                        in1.putExtra(
                                BluetoothDevicePicker.EXTRA_LAUNCH_CLASS,
                                in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE,
                                        getPackageName());
                                in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS,
                                        BluetoothOppReceiver.class.getName());

                                in1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(in1);
                                context.startActivity(in1);
                            }
                        }

                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        if (V) {
@@ -579,27 +609,8 @@ public class BluetoothOppService extends ProfileService
                        break;
                }
            }

    private void unregisterReceivers() {
        try {
            if (mObserver != null) {
                getContentResolver().unregisterContentObserver(mObserver);
                mObserver = null;
            }
        } catch (IllegalArgumentException e) {
            Log.w(TAG, "unregisterReceivers " + e.toString());
        }
    }

    /* suppose we auto accept an incoming OPUSH connection */
    private void createServerSession(ObexTransport transport) {
        mServerSession = new BluetoothOppObexServerSession(this, transport, this);
        mServerSession.preStart();
        if (D) {
            Log.d(TAG, "Get ServerSession " + mServerSession.toString() + " for incoming connection"
                    + transport.toString());
        }
        }
    };

    private void updateFromProvider() {
        synchronized (BluetoothOppService.this) {
+23 −19
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ 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;
@@ -18,6 +19,7 @@ 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;
@@ -41,7 +43,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

    private static final String SDP_SAP_SERVICE_NAME = "SIM Access";
    private static final int SDP_SAP_VERSION = 0x0102;
@@ -678,6 +680,7 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        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);

@@ -689,7 +692,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        }
        mInterrupted = false;
        mAdapterService = AdapterService.getAdapterService();
        mAdapterService.registerBluetoothStateCallback(getMainExecutor(), this);
        // start RFCOMM listener
        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(START_LISTENER));
        setSapService(this);
@@ -710,7 +712,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        } 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;
@@ -725,22 +726,6 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
        }
    }

    @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}
     *
@@ -842,6 +827,25 @@ public class SapService extends ProfileService implements AdapterService.Bluetoo
                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
@@ -232,7 +232,7 @@ public class AdapterServiceRestartTest {

        mLooper.dispatchAll();

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

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

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

Loading