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

Commit 4b7d8df2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add suggestion provider to route transfer metrics" into main

parents 3ea468e3 eda918a0
Loading
Loading
Loading
Loading
+72 −3
Original line number Diff line number Diff line
@@ -38,6 +38,9 @@ public final class RoutingChangeInfo implements Parcelable {
    // Indicates that the route was a suggested route.
    private final boolean mIsSuggested;

    // Indicates the suggestion providers for a route.
    private final @SuggestionProviderFlags int mSuggestionProviderFlags;

    /**
     * Indicates that a routing session started as the result of selecting a route from the output
     * switcher.
@@ -97,6 +100,40 @@ public final class RoutingChangeInfo implements Parcelable {
    @Retention(RetentionPolicy.SOURCE)
    public @interface EntryPoint {}

    /**
     * Flag indicating that the route was suggested by {@link RouteListingPreference}.
     *
     * @hide
     */
    public static final int SUGGESTION_PROVIDER_RLP = 1;

    /**
     * Flag indicating that the route was suggested by the app as a device suggestion.
     *
     * @hide
     */
    public static final int SUGGESTION_PROVIDER_DEVICE_SUGGESTION_APP = 1 << 1;

    /**
     * Flag indicating that the route was suggested as a device suggestion by an app not playing the
     * media.
     *
     * @hide
     */
    public static final int SUGGESTION_PROVIDER_DEVICE_SUGGESTION_OTHER = 1 << 2;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            prefix = "SUGGESTION_PROVIDER",
            flag = true,
            value = {
                SUGGESTION_PROVIDER_RLP,
                SUGGESTION_PROVIDER_DEVICE_SUGGESTION_APP,
                SUGGESTION_PROVIDER_DEVICE_SUGGESTION_OTHER
            })
    public @interface SuggestionProviderFlags {}

    @NonNull
    public static final Creator<RoutingChangeInfo> CREATOR =
            new Creator<>() {
@@ -112,13 +149,22 @@ public final class RoutingChangeInfo implements Parcelable {
            };

    public RoutingChangeInfo(@EntryPoint int entryPoint, boolean isSuggested) {
        this(entryPoint, isSuggested, /* suggestionProviderFlags= */ 0);
    }

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

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

    @Override
@@ -130,6 +176,7 @@ public final class RoutingChangeInfo implements Parcelable {
    public void writeToParcel(@androidx.annotation.NonNull Parcel dest, int flags) {
        dest.writeInt(mEntryPoint);
        dest.writeBoolean(mIsSuggested);
        dest.writeInt(mSuggestionProviderFlags);
    }

    @Override
@@ -146,13 +193,14 @@ public final class RoutingChangeInfo implements Parcelable {
            return true;
        }

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

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

    public @EntryPoint int getEntryPoint() {
@@ -162,4 +210,25 @@ public final class RoutingChangeInfo implements Parcelable {
    public boolean isSuggested() {
        return mIsSuggested;
    }

    public @SuggestionProviderFlags int getSuggestionProviderFlags() {
        return mSuggestionProviderFlags;
    }

    /**
     * Returns whether the route had an active suggestion from the active route listing preference.
     */
    public boolean isSuggestedByRlp() {
        return (mSuggestionProviderFlags & SUGGESTION_PROVIDER_RLP) != 0;
    }

    /** Returns whether the route had an active device suggestion from the media app. */
    public boolean isSuggestedByMediaApp() {
        return (mSuggestionProviderFlags & SUGGESTION_PROVIDER_DEVICE_SUGGESTION_APP) != 0;
    }

    /** Whether the route had an active device suggestion from an app other than the media app. */
    public boolean isSuggestedByAnotherApp() {
        return (mSuggestionProviderFlags & SUGGESTION_PROVIDER_DEVICE_SUGGESTION_OTHER) != 0;
    }
}
+53 −2
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ import static android.media.MediaRouter2.SCANNING_STATE_SCANNING_FULL;
import static android.media.MediaRouter2.SCANNING_STATE_WHILE_INTERACTIVE;
import static android.media.MediaRouter2Utils.getOriginalId;
import static android.media.MediaRouter2Utils.getProviderId;
import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED;
import static android.media.RoutingChangeInfo.SUGGESTION_PROVIDER_DEVICE_SUGGESTION_APP;
import static android.media.RoutingChangeInfo.SUGGESTION_PROVIDER_DEVICE_SUGGESTION_OTHER;
import static android.media.RoutingChangeInfo.SUGGESTION_PROVIDER_RLP;
import static android.media.RoutingChangeInfo.SuggestionProviderFlags;

import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.media.MediaRouterMetricLogger.EVENT_TYPE_CREATE_SESSION;
@@ -1629,9 +1634,16 @@ class MediaRouter2ServiceImpl {
        }

        long uniqueRequestId = toUniqueRequestId(routerRecord.mRouterId, requestId);
        @SuggestionProviderFlags
        int suggestionProviderFlags = getSuggestionProviderFlags(routerRecord, route);
        RoutingChangeInfo updatedInfo =
                new RoutingChangeInfo(
                        routingChangeInfo.getEntryPoint(),
                        routingChangeInfo.isSuggested(),
                        suggestionProviderFlags);
        mMediaRouterMetricLogger.addRequestInfo(
                uniqueRequestId, EVENT_TYPE_CREATE_SESSION, routingChangeInfo);
        mMediaRouterMetricLogger.notifyRoutingChangeRequested(uniqueRequestId, routingChangeInfo);
                uniqueRequestId, EVENT_TYPE_CREATE_SESSION, updatedInfo);
        mMediaRouterMetricLogger.notifyRoutingChangeRequested(uniqueRequestId, updatedInfo);
        userHandler.sendMessage(
                obtainMessage(
                        UserHandler::requestCreateSessionWithRouter2OnHandler,
@@ -2465,6 +2477,45 @@ class MediaRouter2ServiceImpl {
        }
    }

    private static @SuggestionProviderFlags int getSuggestionProviderFlags(
            RouterRecord routerRecord, MediaRoute2Info mediaRoute2Info) {
        String routeId = mediaRoute2Info.getId();
        int result = 0;
        if (routerRecord.mRouteListingPreference != null) {
            List<RouteListingPreference.Item> routeListingPreferenceItems =
                    routerRecord.mRouteListingPreference.getItems();
            if (routeListingPreferenceItems.stream()
                    .anyMatch(
                            item ->
                                    (item.getRouteId().equals(routeId))
                                            && (item.getFlags() & FLAG_SUGGESTED) != 0)) {
                result |= SUGGESTION_PROVIDER_RLP;
            }
        }
        Map<String, List<SuggestedDeviceInfo>> suggestionsMap = routerRecord.mDeviceSuggestions;
        List<SuggestedDeviceInfo> suggestionsByApp = suggestionsMap.get(routerRecord.mPackageName);
        if (suggestionsByApp != null
                && suggestionsByApp.stream()
                        .anyMatch(
                                suggestedDeviceInfo ->
                                        suggestedDeviceInfo.getRouteId().equals(routeId))) {
            result |= SUGGESTION_PROVIDER_DEVICE_SUGGESTION_APP;
        }
        if (suggestionsMap.entrySet().stream()
                .filter(entry -> !entry.getKey().equals(routerRecord.mPackageName))
                .anyMatch(
                        entry ->
                                entry.getValue().stream()
                                        .anyMatch(
                                                suggestedDeviceInfo ->
                                                        suggestedDeviceInfo
                                                                .getRouteId()
                                                                .equals(routeId)))) {
            result |= SUGGESTION_PROVIDER_DEVICE_SUGGESTION_OTHER;
        }
        return result;
    }

    /** Invoked when {@link MediaRouterService#systemRunning()} is invoked. */
    /* package */ void systemRunning() {
        sInstance.set(this);
+36 −3
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Map;

/**
@@ -314,6 +315,9 @@ final class MediaRouterMetricLogger {
                        routingSessionInfo.isSystemSession(),
                        routingSessionInfo.getTransferReason(),
                        routingChangeInfo.isSuggested(),
                        routingChangeInfo.isSuggestedByRlp(),
                        routingChangeInfo.isSuggestedByMediaApp(),
                        routingChangeInfo.isSuggestedByAnotherApp(),
                        getElapsedRealTime());
        mOngoingRoutingChangeCache.put(routingSessionInfo.getOriginalId(), ongoingRoutingChange);
        mRoutingChangeInfoCache.remove(uniqueRequestId);
@@ -338,12 +342,13 @@ final class MediaRouterMetricLogger {
                    TextUtils.formatSimple(
                            "notifySessionEnd | EntryPoint: %d, ClientPackageUid: %d,"
                                    + " IsSystemSession: %b, TransferReason: %d, IsSuggested: %b,"
                                    + " SessionLengthInMillis: %d",
                                    + " SuggestionProviders: %s, SessionLengthInMillis: %d",
                            ongoingRoutingChange.entryPoint,
                            ongoingRoutingChange.clientPackageUid,
                            ongoingRoutingChange.isSystemSession,
                            ongoingRoutingChange.transferReason,
                            ongoingRoutingChange.isSuggested,
                            ongoingRoutingChange.getSuggestionProvidersDebugString(),
                            sessionLengthInMillis));
        }

@@ -354,7 +359,10 @@ final class MediaRouterMetricLogger {
                ongoingRoutingChange.isSystemSession,
                convertTransferReasonForLogging(ongoingRoutingChange.transferReason),
                ongoingRoutingChange.isSuggested,
                sessionLengthInMillis);
                sessionLengthInMillis,
                ongoingRoutingChange.isSuggestedByRlp,
                ongoingRoutingChange.isSuggestedByMediaApp,
                ongoingRoutingChange.isSuggestedByAnotherApp);

        mOngoingRoutingChangeCache.remove(sessionId);
    }
@@ -745,7 +753,32 @@ final class MediaRouterMetricLogger {
            boolean isSystemSession,
            @TransferReason int transferReason,
            boolean isSuggested,
            long startTimeInMillis) {}
            boolean isSuggestedByRlp,
            boolean isSuggestedByMediaApp,
            boolean isSuggestedByAnotherApp,
            long startTimeInMillis) {

        /**
         * Returns a human-readable representation of the suggestion provider for logging purposes.
         */
        public String getSuggestionProvidersDebugString() {
            var providerStrings = new ArrayList<String>();
            if (isSuggestedByRlp) {
                providerStrings.add("RLP");
            }
            if (isSuggestedByMediaApp) {
                providerStrings.add("MEDIA_APP");
            }
            if (isSuggestedByAnotherApp) {
                providerStrings.add("ANOTHER_APP");
            }
            if (providerStrings.isEmpty()) {
                return "NONE";
            } else {
                return String.join("|", providerStrings);
            }
        }
    }

    /** Tracks the count of changes in route listing preference */
    private record RlpCount(long rlpTotalCount, long rlpWithSuggestionCount) {}
+8 −2
Original line number Diff line number Diff line
@@ -402,7 +402,10 @@ public class MediaRouterMetricLoggerTest {
                                anyBoolean(),
                                anyInt(),
                                anyBoolean(),
                                anyLong()),
                                anyLong(),
                                anyBoolean(),
                                anyBoolean(),
                                anyBoolean()),
                never());
    }

@@ -449,7 +452,10 @@ public class MediaRouterMetricLoggerTest {
                                eq(
                                        ROUTING_CHANGE_REPORTED__TRANSFER_REASON__TRANSFER_REASON_SYSTEM_REQUEST),
                                eq(/* isSuggested= */ false),
                                sessionLengthCaptor.capture()));
                                sessionLengthCaptor.capture(),
                                eq(/* isSuggestedByRlp= */ false),
                                eq(/* isSuggestedByMediaApp= */ false),
                                eq(/* isSuggestedByOtherApp= */ false)));
        assertThat(sessionLengthCaptor.getValue()).isEqualTo(sessionTimeInMillis);
    }