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

Commit bc8c6790 authored by Caitlin Cassidy's avatar Caitlin Cassidy
Browse files

[Media SASS] Display about-to-connect device names in the media player

device chip.

Bug: 206614671
Test: atest MediaMuteAwaitConnectionManagerTest
Test: manual: `adb shell am broadcast -a
com.android.systemui.action.SET_FLAG --ei id 904 --ez value 1` to flip
the flag then `adb shell cmd statusbar media-mute-await MuteAwaitDevice
start` and verify that the media player updates to show
"MuteAwaitDevice" as the device with a headphone icon. Video uploaded to
bug showing this interaction.

Change-Id: I4b3dde002904026334f03068dc3574d4b3c5fede
parent 2ccaf53c
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.Notification;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.RoutingSessionInfo;
import android.os.Build;
import android.text.TextUtils;
@@ -226,6 +227,18 @@ public class LocalMediaManager implements BluetoothCallback {
        }
    }

    /**
     * Dispatch a change in the about-to-connect device. See
     * {@link DeviceCallback#onAboutToConnectDeviceChanged} for more information.
     */
    public void dispatchAboutToConnectDeviceChanged(
            @Nullable String deviceName,
            @Nullable Drawable deviceIcon) {
        for (DeviceCallback callback : getCallbacks()) {
            callback.onAboutToConnectDeviceChanged(deviceName, deviceIcon);
        }
    }

    /**
     * Stop scan MediaDevice
     */
@@ -674,6 +687,21 @@ public class LocalMediaManager implements BluetoothCallback {
         * {@link android.media.MediaRoute2ProviderService#REASON_INVALID_COMMAND},
         */
        default void onRequestFailed(int reason){};

        /**
         * Callback for notifying that we have a new about-to-connect device.
         *
         * An about-to-connect device is a device that is not yet connected but is expected to
         * connect imminently and should be displayed as the current device in the media player.
         * See [AudioManager.muteAwaitConnection] for more details.
         *
         * @param deviceName the name of the device (displayed to the user).
         * @param deviceIcon the icon that should be used with the device.
         */
        default void onAboutToConnectDeviceChanged(
                @Nullable String deviceName,
                @Nullable Drawable deviceIcon
        ) {}
    }

    /**
+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionCli;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
@@ -144,6 +145,7 @@ public interface SysUIComponent {
        getMediaTttChipControllerSender();
        getMediaTttChipControllerReceiver();
        getMediaTttCommandLineHelper();
        getMediaMuteAwaitConnectionCli();
        getUnfoldLatencyTracker().init();
        getFoldStateLoggingProvider().ifPresent(FoldStateLoggingProvider::init);
        getFoldStateLogger().ifPresent(FoldStateLogger::init);
@@ -220,6 +222,9 @@ public interface SysUIComponent {
    /** */
    Optional<MediaTttCommandLineHelper> getMediaTttCommandLineHelper();

    /** */
    Optional<MediaMuteAwaitConnectionCli> getMediaMuteAwaitConnectionCli();

    /**
     * Member injection into the supplied argument.
     */
+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public class Flags {
    public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, false);
    public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, true);
    public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, false);
    public static final BooleanFlag MEDIA_MUTE_AWAIT = new BooleanFlag(904, true);

    // Pay no attention to the reflection behind the curtain.
    // ========================== Curtain ==========================
+29 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.media

import android.graphics.drawable.Drawable
import android.media.MediaRouter2Manager
import android.media.session.MediaController
import androidx.annotation.AnyThread
@@ -27,6 +28,7 @@ import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.muteawait.MediaMuteAwaitConnectionManagerFactory
import java.io.FileDescriptor
import java.io.PrintWriter
import java.util.concurrent.Executor
@@ -41,6 +43,7 @@ class MediaDeviceManager @Inject constructor(
    private val controllerFactory: MediaControllerFactory,
    private val localMediaManagerFactory: LocalMediaManagerFactory,
    private val mr2manager: MediaRouter2Manager,
    private val muteAwaitConnectionManagerFactory: MediaMuteAwaitConnectionManagerFactory,
    @Main private val fgExecutor: Executor,
    @Background private val bgExecutor: Executor,
    dumpManager: DumpManager
@@ -80,8 +83,16 @@ class MediaDeviceManager @Inject constructor(
            val controller = data.token?.let {
                controllerFactory.create(it)
            }
            entry = Entry(key, oldKey, controller,
                    localMediaManagerFactory.create(data.packageName))
            val localMediaManager = localMediaManagerFactory.create(data.packageName)
            // We don't need to set this muteAwaitConnectionManager anywhere; it will just notify
            // [localMediaManager] on the appropriate events.
            muteAwaitConnectionManagerFactory.create(localMediaManager)
            entry = Entry(
                key,
                oldKey,
                controller,
                localMediaManager
            )
            entries[key] = entry
            entry.start()
        }
@@ -142,6 +153,9 @@ class MediaDeviceManager @Inject constructor(
                    }
                }
            }
        // A device that is not yet connected but is expected to connect imminently. Because it's
        // expected to connect imminently, it should be displayed as the current device.
        private var aboutToConnectDeviceOverride: MediaDeviceData? = null

        @AnyThread
        fun start() = bgExecutor.execute {
@@ -197,8 +211,21 @@ class MediaDeviceManager @Inject constructor(
            }
        }

        override fun onAboutToConnectDeviceChanged(deviceName: String?, deviceIcon: Drawable?) {
            aboutToConnectDeviceOverride = if (deviceName == null || deviceIcon == null) {
                null
            } else {
                MediaDeviceData(enabled = true, deviceIcon, deviceName)
            }
            updateCurrent()
        }

        @WorkerThread
        private fun updateCurrent() {
            if (aboutToConnectDeviceOverride != null) {
                current = aboutToConnectDeviceOverride
                return
            }
            val device = localMediaManager.currentConnectedDevice
            val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) }

+6 −1
Original line number Diff line number Diff line
@@ -37,4 +37,9 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlags) {
        return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS) &&
            featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT)
    }

    /**
     * Check whether we support displaying information about mute await connections.
     */
    fun areMuteAwaitConnectionsEnabled() = featureFlags.isEnabled(Flags.MEDIA_MUTE_AWAIT)
}
Loading