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

Commit 2df07852 authored by Santiago Seifert's avatar Santiago Seifert
Browse files

Move MediaRouterService work out of main thread

Bug: b/310145678
Test: atest CtsMediaHostTestCases CtsMediaBetterTogetherTestCases AudioManagerRouteControllerTest
Change-Id: I0a73bcfd7c0c5a7780dd587dbd45fe6ba6e286e9
parent 5071b8bd
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -107,6 +107,16 @@ flag {
    bug: "263520343"
}

flag {
    name: "enable_mr2_service_non_main_bg_thread"
    namespace: "media_solutions"
    description: "Enables the use of a background thread in the media routing framework, instead of using the main thread."
    bug: "310145678"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "enable_screen_off_scanning"
    is_exported: true
+1 −1
Original line number Diff line number Diff line
@@ -136,7 +136,7 @@ import java.util.Objects;

        mBluetoothRouteController =
                new BluetoothDeviceRoutesManager(
                        mContext, btAdapter, this::rebuildAvailableRoutesAndNotify);
                        mContext, mHandler, btAdapter, this::rebuildAvailableRoutesAndNotify);
        // Just build routes but don't notify. The caller may not expect the listener to be invoked
        // before this constructor has finished executing.
        rebuildAvailableRoutes();
+50 −25
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaRoute2Info;
import android.os.Handler;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
@@ -77,26 +78,35 @@ import java.util.stream.Collectors;

    @NonNull
    private final Context mContext;
    @NonNull
    private final BluetoothAdapter mBluetoothAdapter;
    @NonNull private final Handler mHandler;
    @NonNull private final BluetoothAdapter mBluetoothAdapter;
    @NonNull
    private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
    @NonNull
    private final BluetoothProfileMonitor mBluetoothProfileMonitor;

    BluetoothDeviceRoutesManager(@NonNull Context context,
    BluetoothDeviceRoutesManager(
            @NonNull Context context,
            @NonNull Handler handler,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
        this(context, bluetoothAdapter,
                new BluetoothProfileMonitor(context, bluetoothAdapter), listener);
        this(
                context,
                handler,
                bluetoothAdapter,
                new BluetoothProfileMonitor(context, bluetoothAdapter),
                listener);
    }

    @VisibleForTesting
    BluetoothDeviceRoutesManager(@NonNull Context context,
    BluetoothDeviceRoutesManager(
            @NonNull Context context,
            @NonNull Handler handler,
            @NonNull BluetoothAdapter bluetoothAdapter,
            @NonNull BluetoothProfileMonitor bluetoothProfileMonitor,
            @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
        mContext = Objects.requireNonNull(context);
        mHandler = handler;
        mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
        mBluetoothProfileMonitor = Objects.requireNonNull(bluetoothProfileMonitor);
        mListener = Objects.requireNonNull(listener);
@@ -298,18 +308,8 @@ import java.util.stream.Collectors;
        };
    }

    private static class BluetoothRouteInfo {
        private BluetoothDevice mBtDevice;
        private MediaRoute2Info mRoute;
        private SparseBooleanArray mConnectedProfiles;
    }

    private class AdapterStateChangedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (state == BluetoothAdapter.STATE_OFF
                    || state == BluetoothAdapter.STATE_TURNING_OFF) {
    private void handleBluetoothAdapterStateChange(int state) {
        if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF) {
            synchronized (BluetoothDeviceRoutesManager.this) {
                mBluetoothRoutes.clear();
            }
@@ -327,6 +327,23 @@ import java.util.stream.Collectors;
            }
        }
    }

    private static class BluetoothRouteInfo {
        private BluetoothDevice mBtDevice;
        private MediaRoute2Info mRoute;
        private SparseBooleanArray mConnectedProfiles;
    }

    private class AdapterStateChangedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            if (Flags.enableMr2ServiceNonMainBgThread()) {
                mHandler.post(() -> handleBluetoothAdapterStateChange(state));
            } else {
                handleBluetoothAdapterStateChange(state);
            }
        }
    }

    private class DeviceStateChangedReceiver extends BroadcastReceiver {
@@ -337,8 +354,16 @@ import java.util.stream.Collectors;
                case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
                case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
                case BluetoothDevice.ACTION_ALIAS_CHANGED:
                    if (Flags.enableMr2ServiceNonMainBgThread()) {
                        mHandler.post(
                                () -> {
                                    updateBluetoothRoutes();
                                    notifyBluetoothRoutesUpdated();
                                });
                    } else {
                        updateBluetoothRoutes();
                        notifyBluetoothRoutesUpdated();
                    }
            }
        }
    }
+12 −2
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.media.RoutingSessionInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -70,6 +71,7 @@ import android.util.TimeUtils;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
import com.android.media.flags.Flags;
import com.android.server.LocalServices;
import com.android.server.Watchdog;
import com.android.server.pm.UserManagerInternal;
@@ -94,6 +96,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
        implements Watchdog.Monitor {
    private static final String TAG = "MediaRouterService";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final String WORKER_THREAD_NAME = "MediaRouterServiceThread";

    /**
     * Timeout in milliseconds for a selected route to transition from a disconnected state to a
@@ -126,7 +129,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub

    private final IAudioService mAudioService;
    private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
    private final Handler mHandler = new Handler();
    private final Handler mHandler;
    private final IntArray mActivePlayerMinPriorityQueue = new IntArray();
    private final IntArray mActivePlayerUidMinPriorityQueue = new IntArray();

@@ -142,7 +145,14 @@ public final class MediaRouterService extends IMediaRouterService.Stub

    @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
    public MediaRouterService(Context context) {
        mLooper = Looper.getMainLooper();
        if (Flags.enableMr2ServiceNonMainBgThread()) {
            HandlerThread handlerThread = new HandlerThread(WORKER_THREAD_NAME);
            handlerThread.start();
            mLooper = handlerThread.getLooper();
        } else {
            mLooper = Looper.myLooper();
        }
        mHandler = new Handler(mLooper);
        mService2 = new MediaRouter2ServiceImpl(context, mLooper);
        mContext = context;
        Watchdog.getInstance().addMonitor(this);
+5 −3
Original line number Diff line number Diff line
@@ -653,9 +653,11 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider {
                return;
            }

            // TODO: b/310145678 - Post this to mHandler once mHandler does not run on the main
            // thread.
            if (Flags.enableMr2ServiceNonMainBgThread()) {
                mHandler.post(SystemMediaRoute2Provider.this::updateVolume);
            } else {
                updateVolume();
            }
        }
    }
}