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

Commit ea1b322f authored by tanaykhemani's avatar tanaykhemani
Browse files

Log metric for RLP suggestion API calls

Test: atest CtsMediaRouterTestCases
Test: Logging in MediaRouter2ServiceImpl and MediaRouterMetricLogger
Flag: EXEMPT adding new metric for logging
Bug: 436842084
Change-Id: Ic4f2767238e2088e44cb6c6108b6662b2c3c54fb
parent d914b146
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -466,6 +466,8 @@ class MediaRouter2ServiceImpl {
                    return;
                }
                setRouteListingPreferenceLocked(routerRecord, routeListingPreference);
                mMediaRouterMetricLogger.notifyRouteListingPreferenceChanged(
                        routerRecord.mUid, routeListingPreference);
            }
        } finally {
            Binder.restoreCallingIdentity(token);
@@ -1365,6 +1367,7 @@ class MediaRouter2ServiceImpl {
        userRecord.mHandler.sendMessage(
                obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
                        userRecord.mHandler));
        mMediaRouterMetricLogger.notifyRouterUnregistered(routerRecord.mUid);
        routerRecord.dispose();
        disposeUserIfNeededLocked(userRecord); // since router removed from user
    }
+76 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.media;

import static android.media.RouteListingPreference.Item.FLAG_SUGGESTED;
import static android.media.RoutingChangeInfo.ENTRY_POINT_LOCAL_ROUTER_UNSPECIFIED;
import static android.media.RoutingChangeInfo.ENTRY_POINT_PROXY_ROUTER_UNSPECIFIED;
import static android.media.RoutingChangeInfo.ENTRY_POINT_SYSTEM_MEDIA_CONTROLS;
@@ -46,7 +47,9 @@ import static com.android.server.media.MediaRouterStatsLog.ROUTING_CHANGE_REPORT
import static com.android.server.media.MediaRouterStatsLog.ROUTING_CHANGE_REPORTED__TRANSFER_REASON__TRANSFER_REASON_UNSPECIFIED;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.MediaRoute2ProviderService;
import android.media.RouteListingPreference;
import android.media.RoutingChangeInfo;
import android.media.RoutingChangeInfo.EntryPoint;
import android.media.RoutingSessionInfo;
@@ -70,6 +73,7 @@ final class MediaRouterMetricLogger {
    private static final String TAG = "MediaRouterMetricLogger";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final int REQUEST_INFO_CACHE_CAPACITY = 100;
    private static final int API_COUNT_CACHE_CAPACITY = 20;

    /** LRU cache to store request info. */
    private final EvictionCallbackLruCache<Long, RequestInfo> mRequestInfoCache;
@@ -80,6 +84,12 @@ final class MediaRouterMetricLogger {
    /** LRU cache to store information for an ongoing routing change. */
    private final EvictionCallbackLruCache<String, OngoingRoutingChange> mOngoingRoutingChangeCache;

    /**
     * LRU cache to store the count of RLP API calls per package uid. The key is the package uid and
     * the value is {@link RlpCount}
     */
    private final EvictionCallbackLruCache<Integer, RlpCount> mRlpCountCache;

    /** Constructor for {@link MediaRouterMetricLogger}. */
    public MediaRouterMetricLogger() {
        mRequestInfoCache =
@@ -91,6 +101,9 @@ final class MediaRouterMetricLogger {
        mOngoingRoutingChangeCache =
                new EvictionCallbackLruCache<>(
                        REQUEST_INFO_CACHE_CAPACITY, new OnOngoingRoutingChangeEvictedListener());
        mRlpCountCache =
                new EvictionCallbackLruCache<>(
                        API_COUNT_CACHE_CAPACITY, new OnRlpSuggestionCountEvictedListener());
    }

    /**
@@ -277,6 +290,49 @@ final class MediaRouterMetricLogger {
        mOngoingRoutingChangeCache.remove(sessionId);
    }

    /**
     * Increments the count of RLP calls and if any of the {@link RouteListingPreference.Item} have
     * {@link FLAG_SUGGESTED} set, increments the count of RLP suggestion calls.
     *
     * @param setterPackageUid Uid of the package which called the API.
     * @param routeListingPreference the route listing preference with which the API was called.
     */
    public void notifyRouteListingPreferenceChanged(
            int setterPackageUid, @Nullable RouteListingPreference routeListingPreference) {
        boolean hasFlagSuggested =
                routeListingPreference != null
                        && (routeListingPreference.getItems().stream()
                                .anyMatch(item -> (item.getFlags() & FLAG_SUGGESTED) != 0));

        long rlpTotalCount = 0, rlpWithSuggestedCount = 0;
        long suggestedCountIncrement = hasFlagSuggested ? 1 : 0;
        RlpCount existingRlpCount = mRlpCountCache.get(setterPackageUid);
        if (existingRlpCount != null) {
            rlpTotalCount = existingRlpCount.rlpTotalCount;
            rlpWithSuggestedCount = existingRlpCount.rlpWithSuggestionCount;
        }
        mRlpCountCache.put(
                setterPackageUid,
                new RlpCount(rlpTotalCount + 1, rlpWithSuggestedCount + suggestedCountIncrement));
    }

    /**
     * This is called when a {@link android.media.MediaRouter2} instance is unregistered. It takes
     * care of logging metrics aggregated over the lifecycle of the {@link
     * android.media.MediaRouter2} instance.
     *
     * @param routerPackageUid the Uid of the package associated with the {@link
     *     android.media.MediaRouter2} instance.
     */
    public void notifyRouterUnregistered(int routerPackageUid) {
        RlpCount rlpCount = mRlpCountCache.remove(routerPackageUid);
        if (rlpCount == null) {
            // This helps track scenarios where MediaRouter2 is used but not RLP.
            rlpCount = new RlpCount(0, 0);
        }
        logRlpCountForRouter(routerPackageUid, rlpCount);
    }

    /**
     * Converts {@link TransferReason} from {@link RoutingSessionInfo} to the transfer reason enum
     * defined for logging.
@@ -376,6 +432,14 @@ final class MediaRouterMetricLogger {
                MEDIA_ROUTER_EVENT_REPORTED__RESULT__RESULT_UNSPECIFIED);
    }

    private void logRlpCountForRouter(int routerPackageId, RlpCount rlpCount) {
        MediaRouterStatsLog.write(
                MediaRouterStatsLog.ROUTE_LISTING_PREFERENCE_UPDATED,
                routerPackageId,
                rlpCount.rlpTotalCount,
                rlpCount.rlpWithSuggestionCount);
    }

    /** Class to store request info. */
    static class RequestInfo {
        public final long mUniqueRequestId;
@@ -455,6 +519,15 @@ final class MediaRouterMetricLogger {
        }
    }

    private class OnRlpSuggestionCountEvictedListener
            implements OnEntryEvictedListener<Integer, RlpCount> {
        @Override
        public void onEntryEvicted(Integer key, RlpCount value) {
            Slog.w(TAG, "Rlp suggestion count evicted from cache");
            logRlpCountForRouter(key, value);
        }
    }

    private interface OnEntryEvictedListener<K, V> {
        void onEntryEvicted(K key, V value);
    }
@@ -467,4 +540,7 @@ final class MediaRouterMetricLogger {
            @TransferReason int transferReason,
            boolean isSuggested,
            long startTimeInMillis) {}

    /** Tracks the count of changes in route listing preference */
    private record RlpCount(long rlpTotalCount, long rlpWithSuggestionCount) {}
}