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

Commit c5daad2a authored by Jieru Shi's avatar Jieru Shi
Browse files

Populate additional fields for smartspace logging

1. Log package uid for media card
2. Log interacted subcard rank and cardinality for recommendation card
3. Log received event for reactived resume card
4. Log card type as int instead of enum

Test: https://paste.googleplex.com/4557927936425984
Bug: 181364757,196637550
Change-Id: I2297a8febcaa8e49cf61f1727bd11ffcf0a13bdf
parent 2747904e
Loading
Loading
Loading
Loading
+76 −27
Original line number Diff line number Diff line
@@ -212,14 +212,32 @@ class MediaCarouselController @Inject constructor(
                isSsReactivated: Boolean
            ) {
                if (addOrUpdatePlayer(key, oldKey, data)) {
                    // Log card received if a new resumable media card is added
                    MediaPlayerData.getMediaPlayer(key)?.let {
                        logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
                                it.mInstanceId,
                                it.mUid,
                                /* isRecommendationCard */ false,
                                it.surfaceForSmartspaceLogging,
                                rank = MediaPlayerData.getMediaPlayerIndex(key))
                    }
                }
                if (isSsReactivated) {
                    // If resumable media is reactivated by headphone connection, update instance
                    // id for each card and log a receive event.
                    MediaPlayerData.players().forEachIndexed { index, it ->
                        if (it.recommendationViewHolder == null) {
                            it.mInstanceId = SmallHash.hash(it.mUid +
                                    systemClock.currentTimeMillis().toInt())
                            logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
                                    it.mInstanceId,
                                    it.mUid,
                                    /* isRecommendationCard */ false,
                                    it.surfaceForSmartspaceLogging,
                                    rank = index)
                        }
                    }
                }
                if (mediaCarouselScrollHandler.visibleToUser &&
                        isSsReactivated && !mediaCarouselScrollHandler.qsExpanded) {
                    // It could happen that reactived media player isn't visible to user because
@@ -252,6 +270,7 @@ class MediaCarouselController @Inject constructor(
                    MediaPlayerData.getMediaPlayer(key)?.let {
                        logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
                                it.mInstanceId,
                                it.mUid,
                                /* isRecommendationCard */ true,
                                it.surfaceForSmartspaceLogging,
                                rank = MediaPlayerData.getMediaPlayerIndex(key))
@@ -261,6 +280,7 @@ class MediaCarouselController @Inject constructor(
                                MediaPlayerData.getMediaPlayerIndex(key)) {
                            logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
                                    it.mInstanceId,
                                    it.mUid,
                                    /* isRecommendationCard */ true,
                                    it.surfaceForSmartspaceLogging)
                        }
@@ -696,17 +716,37 @@ class MediaCarouselController @Inject constructor(
            }
            logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
                    mediaControlPanel.mInstanceId,
                    mediaControlPanel.mUid,
                    isRecommendationCard,
                    mediaControlPanel.surfaceForSmartspaceLogging)
        }
    }

    @JvmOverloads
    /**
     * Log Smartspace events
     *
     * @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN)
     * @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
     * instanceId
     * @param uid uid for the application that media comes from
     * @param isRecommendationCard whether the card is media recommendation
     * @param surface which display surface the media card is on (e.g. lockscreen, shade)
     * @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
     * for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
     * @param interactedSubcardCardinality how many media items were shown to the user when there
     * is user interaction
     * @param rank the rank for media card in the media carousel, starting from 0
     *
     */
    fun logSmartspaceCardReported(
        eventId: Int,
        instanceId: Int,
        uid: Int,
        isRecommendationCard: Boolean,
        surface: Int,
        interactedSubcardRank: Int = 0,
        interactedSubcardCardinality: Int = 0,
        rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
    ) {
        // Only log media resume card when Smartspace data is available
@@ -720,13 +760,20 @@ class MediaCarouselController @Inject constructor(
        SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
                eventId,
                instanceId,
                if (isRecommendationCard)
                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_MEDIA_RECOMMENDATIONS
                else
                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_RESUME_MEDIA,
                // Deprecated, replaced with AiAi feature type so we don't need to create logging
                // card type for each new feature.
                SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
                surface,
                rank,
                mediaContent.getChildCount())
                mediaContent.getChildCount(),
                if (isRecommendationCard)
                    15 // MEDIA_RECOMMENDATION
                else
                    31, // MEDIA_RESUME
                uid,
                interactedSubcardRank,
                interactedSubcardCardinality
        )
        /* ktlint-disable max-line-length */
    }

@@ -738,18 +785,20 @@ class MediaCarouselController @Inject constructor(
        if (!recommendation.isEmpty()) {
            logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
                    recommendation.get(0).mInstanceId,
                    recommendation.get(0).mUid,
                    true,
                    recommendation.get(0).surfaceForSmartspaceLogging,
            /* rank */-1)
                    rank = -1)
        } else {
            val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
            if (MediaPlayerData.players().size > visibleMediaIndex) {
                val player = MediaPlayerData.players().elementAt(visibleMediaIndex)
                logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
                        player.mInstanceId,
                        player.mUid,
                        false,
                        player.surfaceForSmartspaceLogging,
                /* rank */-1)
                        rank = -1)
            }
        }
        mediaManager.onSwipeToDismiss()
+46 −11
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.graphics.drawable.Icon;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.os.Process;
import android.text.Layout;
import android.util.Log;
import android.view.View;
@@ -111,6 +112,9 @@ public class MediaControlPanel {
    private int mAlbumArtSize;
    // Instance id for logging purpose.
    protected int mInstanceId = -1;
    // Uid for the media app.
    protected int mUid = Process.INVALID_UID;
    private int mSmartspaceMediaItemsCount;
    private MediaCarouselController mMediaCarouselController;
    private final MediaOutputDialogFactory mMediaOutputDialogFactory;

@@ -266,7 +270,13 @@ public class MediaControlPanel {
        }
        mKey = key;
        MediaSession.Token token = data.getToken();
        mInstanceId = SmallHash.hash(data.getPackageName());
        PackageManager packageManager = mContext.getPackageManager();
        try {
            mUid = packageManager.getApplicationInfo(data.getPackageName(), 0 /* flags */).uid;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Unable to look up package name", e);
        }
        mInstanceId = SmallHash.hash(mUid);

        mBackgroundColor = data.getBackgroundColor();
        if (mToken == null || !mToken.equals(token)) {
@@ -531,10 +541,11 @@ public class MediaControlPanel {
        }

        // Set up recommendation card's header.
        ApplicationInfo applicationInfo = null;
        ApplicationInfo applicationInfo;
        try {
            applicationInfo = mContext.getPackageManager()
                    .getApplicationInfo(data.getPackageName(), 0 /* flags */);
            mUid = applicationInfo.uid;
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Fail to get media recommendation's app info", e);
            return;
@@ -553,7 +564,8 @@ public class MediaControlPanel {
            headerTitleText.setText(appLabel);
        }
        // Set up media rec card's tap action if applicable.
        setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction());
        setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
                /* interactedSubcardRank */ -1);
        // Set up media rec card's accessibility label.
        recommendationCard.setContentDescription(
                mContext.getString(R.string.controls_media_smartspace_rec_description, appLabel));
@@ -567,7 +579,8 @@ public class MediaControlPanel {
        ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
        int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
                MEDIA_RECOMMENDATION_MAX_NUM);
        for (int itemIndex = 0, uiComponentIndex = 0;
        int uiComponentIndex = 0;
        for (int itemIndex = 0;
                itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
                itemIndex++) {
            SmartspaceAction recommendation = mediaRecommendationList.get(itemIndex);
@@ -582,7 +595,8 @@ public class MediaControlPanel {

            // Set up the media item's click listener if applicable.
            ViewGroup mediaCoverContainer = mediaCoverContainers.get(uiComponentIndex);
            setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation);
            setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation,
                    uiComponentIndex);

            // Set up the accessibility label for the media item.
            String artistName = recommendation.getExtras()
@@ -614,10 +628,10 @@ public class MediaControlPanel {
                    mediaCoverItemsResIds.get(uiComponentIndex), true);
            setVisibleAndAlpha(expandedSet,
                    mediaCoverContainersResIds.get(uiComponentIndex), true);

            uiComponentIndex++;
        }

        mSmartspaceMediaItemsCount = uiComponentIndex;
        // Set up long press to show guts setting panel.
        mRecommendationViewHolder.getDismiss().setOnClickListener(v -> {
            logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
@@ -750,7 +764,8 @@ public class MediaControlPanel {

    private void setSmartspaceRecItemOnClickListener(
            @NonNull View view,
            @NonNull SmartspaceAction action) {
            @NonNull SmartspaceAction action,
            int interactedSubcardRank) {
        if (view == null || action == null || action.getIntent() == null
                || action.getIntent().getExtras() == null) {
            Log.e(TAG, "No tap action can be set up");
@@ -758,9 +773,10 @@ public class MediaControlPanel {
        }

        view.setOnClickListener(v -> {
            // When media recommendation card is shown, it will always be the top card.
            logSmartspaceCardReported(760, // SMARTSPACE_CARD_CLICK
                    /* isRecommendationCard */ true);
                    /* isRecommendationCard */ true,
                    interactedSubcardRank,
                    getSmartspaceSubCardCardinality());

            if (shouldSmartspaceRecItemOpenInForeground(action)) {
                // Request to unlock the device if the activity needs to be opened in foreground.
@@ -818,9 +834,28 @@ public class MediaControlPanel {
    }

    private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard) {
        logSmartspaceCardReported(eventId, isRecommendationCard,
                /* interactedSubcardRank */ 0,
                /* interactedSubcardCardinality */ 0);
    }

    private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard,
            int interactedSubcardRank, int interactedSubcardCardinality) {
        mMediaCarouselController.logSmartspaceCardReported(eventId,
                mInstanceId,
                mUid,
                isRecommendationCard,
                getSurfaceForSmartspaceLogging());
                getSurfaceForSmartspaceLogging(),
                interactedSubcardRank,
                interactedSubcardCardinality);
    }

    private int getSmartspaceSubCardCardinality() {
        if (!mMediaCarouselController.getMediaCarouselScrollHandler().getQsExpanded()
                && mSmartspaceMediaItemsCount > 3) {
            return 3;
        }

        return mSmartspaceMediaItemsCount;
    }
}
 No newline at end of file