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

Commit c7273ac9 authored by Tanay Khemani's avatar Tanay Khemani Committed by Android (Google) Code Review
Browse files

Merge "Add entry point info for MR2 transfer calls" into main

parents c837dfb1 81ac077e
Loading
Loading
Loading
Loading
+18 −59
Original line number Diff line number Diff line
@@ -127,65 +127,6 @@ public final class MediaRouter2 {
    @Retention(RetentionPolicy.SOURCE)
    public @interface ScanningState {}

    /**
     * Indicates that a routing session started as the result of selecting a route from the output
     * switcher where the route is not amongst the suggested routes.
     *
     * @hide
     */
    public static final int ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER_NOT_SUGGESTED = 0;

    /**
     * Indicates that a routing session started as the result of selecting a route from the output
     * switcher where the route is amongst the suggested routes.
     *
     * @hide
     */
    public static final int ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER_SUGGESTED_DEVICE = 1;

    /**
     * Indicates that a routing session started as the result of selecting the device suggestion
     * pill in the UMO notification.
     *
     * @hide
     */
    public static final int ENTRY_POINT_SYSTEM_UMO_SUGGESTED_DEVICE = 2;

    /**
     * Indicates that a routing session was started from a local media router instance where the
     * entry point was not specified.
     *
     * <p>This entry point is marked when {@link MediaRouter2#transferTo(MediaRoute2Info)} is called
     * on a local media router instance.
     *
     * @hide
     */
    public static final int ENTRY_POINT_LOCAL_ROUTER_UNSPECIFIED = 3;

    /**
     * Indicates that a routing session was started from a proxy media router instance where the
     * entry point was not specified.
     *
     * <p>This entry point is marked when {@link MediaRouter2#transferTo(MediaRoute2Info)} is called
     * on a proxy media router instance.
     *
     * @hide
     */
    public static final int ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED = 4;

    /** @hide */
    @IntDef(
            prefix = "ENTRY_POINT",
            value = {
                ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER_NOT_SUGGESTED,
                ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER_SUGGESTED_DEVICE,
                ENTRY_POINT_SYSTEM_UMO_SUGGESTED_DEVICE,
                ENTRY_POINT_LOCAL_ROUTER_UNSPECIFIED,
                ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EntryPoint {}

    private static final String TAG = "MR2";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final Object sSystemRouterLock = new Object();
@@ -1161,6 +1102,24 @@ public final class MediaRouter2 {
        mImpl.transferTo(route);
    }

    /**
     * Transfers the current media to the given route. If it's necessary a new {@link
     * RoutingController} is created or it is handled within the current routing controller.
     *
     * @param route the route you want to transfer the current media to. Pass {@code null} to stop
     *     routing of the current media.
     * @param routingChangeInfo information about the start of the media routing session. See {@link
     *     RoutingChangeInfo}
     * @see TransferCallback#onTransfer
     * @see TransferCallback#onTransferFailure
     * @hide
     */
    public void transferTo(
            @NonNull MediaRoute2Info route, @NonNull RoutingChangeInfo routingChangeInfo) {
        // TODO: b/427964326 - Pass the entry point of media routing session to MediaRouterService
        mImpl.transferTo(route);
    }

    /**
     * Stops the current media routing. If the {@link #getSystemController() system controller}
     * controls the media routing, this method is a no-op.
+173 −0
Original line number Diff line number Diff line
/*
 * Copyright 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Captures information about the change in media routing for logging purposes.
 *
 * @hide
 */
public final class RoutingChangeInfo implements Parcelable {

    // Indicates the start point of a media session.
    private final @EntryPoint int mEntryPoint;

    // Indicates that the route was a suggested route.
    private final boolean mIsSuggested;

    /**
     * Unspecified default value.
     *
     * @hide
     */
    public static final int ENTRY_POINT_UNSPECIFIED = 0;

    /**
     * Indicates that a routing session started as the result of selecting a route from the output
     * switcher.
     *
     * @hide
     */
    public static final int ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER = 1;

    /**
     * Indicates that a routing session started as the result of selecting the device suggestion
     * pill in the system media controls.
     *
     * @hide
     */
    public static final int ENTRY_POINT_SYSTEM_MEDIA_CONTROLS = 2;

    /**
     * Indicates that a routing session was started from a local media router instance where the
     * entry point was not specified.
     *
     * <p>This entry point is marked when {@link MediaRouter2#transferTo(MediaRoute2Info)} is called
     * on a local media router instance.
     *
     * @hide
     */
    public static final int ENTRY_POINT_LOCAL_ROUTER_UNSPECIFIED = 3;

    /**
     * Indicates that a routing session was started from a proxy media router instance where the
     * entry point was not specified.
     *
     * <p>This entry point is marked when {@link MediaRouter2#transferTo(MediaRoute2Info)} is called
     * on a proxy media router instance.
     *
     * @hide
     */
    public static final int ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED = 4;

    /**
     * Indicates that a routing session started as the result of selecting a route from the output
     * switcher in TV.
     *
     * @hide
     */
    public static final int ENTRY_POINT_TV_OUTPUT_SWITCHER = 5;

    /** @hide */
    @IntDef(
            prefix = "ENTRY_POINT",
            value = {
                ENTRY_POINT_UNSPECIFIED,
                ENTRY_POINT_SYSTEM_OUTPUT_SWITCHER,
                ENTRY_POINT_SYSTEM_MEDIA_CONTROLS,
                ENTRY_POINT_LOCAL_ROUTER_UNSPECIFIED,
                ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED,
                ENTRY_POINT_TV_OUTPUT_SWITCHER
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EntryPoint {}

    @NonNull
    public static final Creator<RoutingChangeInfo> CREATOR =
            new Creator<>() {
                @Override
                public RoutingChangeInfo createFromParcel(Parcel in) {
                    return new RoutingChangeInfo(in);
                }

                @Override
                public RoutingChangeInfo[] newArray(int size) {
                    return new RoutingChangeInfo[size];
                }
            };

    public RoutingChangeInfo(@EntryPoint int entryPoint, boolean isSuggested) {
        mEntryPoint = entryPoint;
        mIsSuggested = isSuggested;
    }

    private RoutingChangeInfo(Parcel in) {
        mEntryPoint = in.readInt();
        mIsSuggested = in.readBoolean();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@androidx.annotation.NonNull Parcel dest, int flags) {
        dest.writeInt(mEntryPoint);
        dest.writeBoolean(mIsSuggested);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (!(obj instanceof RoutingChangeInfo other)) {
            return false;
        }

        if (obj == this) {
            return true;
        }

        return other.getEntryPoint() == this.getEntryPoint()
                && other.isSuggested() == this.mIsSuggested;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mEntryPoint, mIsSuggested);
    }

    public @EntryPoint int getEntryPoint() {
        return mEntryPoint;
    }

    public boolean isSuggested() {
        return mIsSuggested;
    }
}
+5 −3
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.media.MediaRoute2Info;
import android.media.RouteListingPreference;
import android.media.RoutingChangeInfo;
import android.media.RoutingSessionInfo;
import android.media.SuggestedDeviceInfo;
import android.media.session.MediaController;
@@ -315,7 +316,8 @@ public abstract class InfoMediaManager {

    protected abstract void unregisterRouter();

    protected abstract void transferToRoute(@NonNull MediaRoute2Info route);
    protected abstract void transferToRoute(
            @NonNull MediaRoute2Info route, @NonNull RoutingChangeInfo routingChangeInfo);

    protected abstract void selectRoute(
            @NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo info);
@@ -475,7 +477,7 @@ public abstract class InfoMediaManager {
        return mCurrentConnectedDevice;
    }

    /* package */ void connectToDevice(MediaDevice device) {
    /* package */ void connectToDevice(MediaDevice device, RoutingChangeInfo routingChangeInfo) {
        Log.i(TAG, "connectToDevice(), device = " + device.getName() + "/" + device.getId());
        if (device.mRouteInfo == null) {
            Log.w(TAG, "Unable to connect. RouteInfo is empty");
@@ -483,7 +485,7 @@ public abstract class InfoMediaManager {
        }

        device.setConnectedRecord();
        transferToRoute(device.mRouteInfo);
        transferToRoute(device.mRouteInfo, routingChangeInfo);
    }

    /**
+41 −8
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.settingslib.media;

import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;
import static android.media.RoutingChangeInfo.ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -25,6 +26,8 @@ import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.media.AudioDeviceAttributes;
import android.media.AudioManager;
import android.media.RoutingChangeInfo;
import android.media.RoutingChangeInfo.EntryPoint;
import android.media.RoutingSessionInfo;
import android.os.Build;
import android.os.Handler;
@@ -189,10 +192,29 @@ public class LocalMediaManager implements BluetoothCallback {

    /**
     * Connect the MediaDevice to transfer media
     *
     * @param connectDevice the MediaDevice
     * @return {@code true} if successfully call, otherwise return {@code false}
     * @deprecated Use {@link #connectDevice(MediaDevice, RoutingChangeInfo)} instead.
     */
    @Deprecated
    public boolean connectDevice(MediaDevice connectDevice) {
        return connectDevice(
                connectDevice,
                new RoutingChangeInfo(
                        ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED, /* isSuggested= */ false));
    }

    /**
     * Connect the MediaDevice to transfer media
     *
     * @param connectDevice the MediaDevice
     * @param routingChangeInfo the invocation details of the connect device request. See {@link
     *     RoutingChangeInfo}
     * @return {@code true} if successfully call, otherwise return {@code false}
     */
    public boolean connectDevice(
            @NonNull MediaDevice connectDevice, @NonNull RoutingChangeInfo routingChangeInfo) {
        MediaDevice device = getMediaDeviceById(connectDevice.getId());
        if (device == null) {
            Log.w(TAG, "connectDevice() connectDevice not in the list!");
@@ -215,7 +237,7 @@ public class LocalMediaManager implements BluetoothCallback {
        }

        mInfoMediaManager.setDeviceState(device, MediaDeviceState.STATE_CONNECTING);
        mInfoMediaManager.connectToDevice(device);
        mInfoMediaManager.connectToDevice(device, routingChangeInfo);
        return true;
    }

@@ -224,10 +246,14 @@ public class LocalMediaManager implements BluetoothCallback {
     * to attempt to discover the device.
     *
     * @param suggestion the suggested device to connect to.
     * @param routingChangeInfo the invocation details of the connect device request. See {@link
     *     RoutingChangeInfo}
     */
    public void connectSuggestedDevice(SuggestedDeviceState suggestion) {
    public void connectSuggestedDevice(
            @NonNull SuggestedDeviceState suggestion,
            @NonNull RoutingChangeInfo routingChangeInfo) {
        synchronized (mMediaDevicesLock) {
            if (suggestion == null || mConnectingSuggestedDeviceState != null) {
            if (mConnectingSuggestedDeviceState != null) {
                return;
            }
            SuggestedDeviceState currentSuggestion = mInfoMediaManager.getSuggestedDevice();
@@ -239,11 +265,13 @@ public class LocalMediaManager implements BluetoothCallback {
                if (suggestion.getSuggestedDeviceInfo().getRouteId().equals(device.getId())) {
                    Log.i(TAG, "Suggestion: device is available, connecting. deviceId = "
                            + device.getId());
                    connectDevice(device);
                    connectDevice(device, routingChangeInfo);
                    return;
                }
            }
            mConnectingSuggestedDeviceState = new ConnectingSuggestedDeviceState(currentSuggestion);
            mConnectingSuggestedDeviceState =
                    new ConnectingSuggestedDeviceState(
                            currentSuggestion, routingChangeInfo.getEntryPoint());
            mConnectingSuggestedDeviceState.tryConnect();
        }
    }
@@ -860,7 +888,8 @@ public class LocalMediaManager implements BluetoothCallback {
        boolean mIsConnectionAttemptActive = false;
        boolean mDidAttemptCompleteSuccessfully = false;

        ConnectingSuggestedDeviceState(@NonNull SuggestedDeviceState suggestedDeviceState) {
        ConnectingSuggestedDeviceState(
                @NonNull SuggestedDeviceState suggestedDeviceState, @EntryPoint int entryPoint) {
            mSuggestedDeviceState = suggestedDeviceState;
            mDeviceCallback =
                    new DeviceCallback() {
@@ -869,11 +898,15 @@ public class LocalMediaManager implements BluetoothCallback {
                            synchronized (mMediaDevicesLock) {
                                for (MediaDevice mediaDevice : mediaDevices) {
                                    if (isSuggestedDevice(mediaDevice)) {
                                        Log.i(TAG,
                                        Log.i(
                                                TAG,
                                                "Suggestion: scan found matched device, "
                                                        + "connecting. deviceId = "
                                                        + mediaDevice.getId());
                                        connectDevice(mediaDevice);
                                        connectDevice(
                                                mediaDevice,
                                                new RoutingChangeInfo(
                                                        entryPoint, /* isSuggested= */ true));
                                        mIsConnectionAttemptActive = true;
                                        break;
                                    }
+3 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settingslib.media;
import android.content.Context;
import android.media.MediaRoute2Info;
import android.media.RouteListingPreference;
import android.media.RoutingChangeInfo;
import android.media.RoutingSessionInfo;
import android.media.session.MediaController;
import android.os.UserHandle;
@@ -87,7 +88,8 @@ import java.util.List;
    }

    @Override
    protected void transferToRoute(@NonNull MediaRoute2Info route) {
    protected void transferToRoute(
            @NonNull MediaRoute2Info route, @NonNull RoutingChangeInfo routingChangeInfo) {
        // Do nothing.
    }

Loading