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

Commit 15eb7da7 authored by Sungsoo Lim's avatar Sungsoo Lim
Browse files

Get bluetooth A2DP status directly from BT

MediaRourter uses main thread for internal operations, and ANR could
happens if AudioService is not running when MediaRouter tried to get
BT A2DP status. This CL avoids such ANR by getting the info using
BroadcastReceiver insteead of AudioService.

Bug: 170327593
Test: manually
Change-Id: If9eba19481fceb0c86ff0117e8a604b64d7ebc49
parent 69f35b55
Loading
Loading
Loading
Loading
+31 −20
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.app.ActivityThread;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -99,6 +102,7 @@ public class MediaRouter {

        RouteInfo mDefaultAudioVideo;
        RouteInfo mBluetoothA2dpRoute;
        volatile boolean mHasActiveBluetoothDevices;

        RouteInfo mSelectedRoute;

@@ -172,14 +176,20 @@ public class MediaRouter {
                    new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
            appContext.registerReceiver(new VolumeChangeReceiver(),
                    new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
            intentFilter.addAction(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED);
            appContext.registerReceiver(new BluetoothStateChangedReceiver(), intentFilter);

            mDisplayService.registerDisplayListener(this, mHandler);

            AudioRoutesInfo newAudioRoutes = null;
            try {
                newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
                mHasActiveBluetoothDevices = mAudioService.isBluetoothA2dpOn();
            } catch (RemoteException e) {
            }

            if (newAudioRoutes != null) {
                // This will select the active BT route if there is one and the current
                // selected route is the default system route, or if there is no selected
@@ -253,7 +263,8 @@ public class MediaRouter {
            }

            if (audioRoutesChanged) {
                Log.v(TAG, "Audio routes updated: " + newRoutes + ", a2dp=" + isBluetoothA2dpOn());
                Log.v(TAG, "Audio routes updated: " + newRoutes + ", hasActiveBTDevices="
                        + mHasActiveBluetoothDevices);
                if (mSelectedRoute == null || mSelectedRoute == mDefaultAudioVideo
                        || mSelectedRoute == mBluetoothA2dpRoute) {
                    if (forceUseDefaultRoute || mBluetoothA2dpRoute == null) {
@@ -277,15 +288,6 @@ public class MediaRouter {
            return mStreamVolume.get(streamType);
        }

        boolean isBluetoothA2dpOn() {
            try {
                return mBluetoothA2dpRoute != null && mAudioService.isBluetoothA2dpOn();
            } catch (RemoteException e) {
                Log.e(TAG, "Error querying Bluetooth A2DP state", e);
                return false;
            }
        }

        void updateDiscoveryRequest() {
            // What are we looking for today?
            int routeTypes = 0;
@@ -394,7 +396,7 @@ public class MediaRouter {
        }

        void updateSelectedRouteForId(String routeId) {
            RouteInfo selectedRoute = isBluetoothA2dpOn()
            RouteInfo selectedRoute = sStatic.mHasActiveBluetoothDevices
                    ? mBluetoothA2dpRoute : mDefaultAudioVideo;
            final int count = mRoutes.size();
            for (int i = 0; i < count; i++) {
@@ -1043,7 +1045,7 @@ public class MediaRouter {
        Log.v(TAG, "Selecting route: " + route);
        assert(route != null);
        final RouteInfo oldRoute = sStatic.mSelectedRoute;
        final RouteInfo currentSystemRoute = sStatic.isBluetoothA2dpOn()
        final RouteInfo currentSystemRoute = sStatic.mHasActiveBluetoothDevices
                ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo;
        boolean wasDefaultOrBluetoothRoute = (oldRoute == sStatic.mDefaultAudioVideo
                || oldRoute == sStatic.mBluetoothA2dpRoute);
@@ -1106,7 +1108,8 @@ public class MediaRouter {

    static void selectDefaultRouteStatic() {
        // TODO: Be smarter about the route types here; this selects for all valid.
        if (sStatic.mSelectedRoute != sStatic.mBluetoothA2dpRoute && sStatic.isBluetoothA2dpOn()) {
        if (sStatic.mSelectedRoute != sStatic.mBluetoothA2dpRoute
                && sStatic.mHasActiveBluetoothDevices) {
            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mBluetoothA2dpRoute, false);
        } else {
            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mDefaultAudioVideo, false);
@@ -1443,13 +1446,8 @@ public class MediaRouter {
        if (selectedRoute == sStatic.mBluetoothA2dpRoute ||
                selectedRoute == sStatic.mDefaultAudioVideo) {
            dispatchRouteVolumeChanged(selectedRoute);
        } else if (sStatic.mBluetoothA2dpRoute != null) {
            try {
                dispatchRouteVolumeChanged(sStatic.mAudioService.isBluetoothA2dpOn() ?
                        sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo);
            } catch (RemoteException e) {
                Log.e(TAG, "Error checking Bluetooth A2DP state to report volume change", e);
            }
        } else if (sStatic.mHasActiveBluetoothDevices) {
            dispatchRouteVolumeChanged(sStatic.mBluetoothA2dpRoute);
        } else {
            dispatchRouteVolumeChanged(sStatic.mDefaultAudioVideo);
        }
@@ -3172,4 +3170,17 @@ public class MediaRouter {
            }
        }
    }

    static class BluetoothStateChangedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED:
                case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED:
                    sStatic.mHasActiveBluetoothDevices =
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) != null;
                    break;
            }
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -439,6 +439,7 @@ class BluetoothRouteProvider {
            }
        }
    }

    private class BluetoothBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {