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

Commit 30be970a authored by Insun Kang's avatar Insun Kang
Browse files

MediaSession: Improve MediaSessionStack logic

There was an issue that media button events (play / pause) didn’t go
to the expected media session. If an app creates a media session during
all media sessions are paused, the next coming media play event is
consumed by the newly created media session. It makes sense in general,
but if the media session is created in a background process without any
visible UI, it causes unexpected results.

This patch resolves the issue by checking if a newly added session comes
from the most recent user-facing app.

Bug: 24990104
Change-Id: Ic9632bced37bffd28260afe3523d9a20ea4d3c21
parent 10373488
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ import java.util.ArrayList;
 */
public class MediaSessionRecord implements IBinder.DeathRecipient {
    private static final String TAG = "MediaSessionRecord";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /**
     * The length of time a session will still be considered active after
+3 −0
Original line number Diff line number Diff line
@@ -287,6 +287,9 @@ public class MediaSessionService extends SystemService implements Monitor {
     * 6. We need to tell the session to do any final cleanup (onDestroy)
     */
    private void destroySessionLocked(MediaSessionRecord session) {
        if (DEBUG) {
            Log.d(TAG, "Destroying session : " + session.toString());
        }
        int userId = session.getUserId();
        UserRecord user = mUserRecords.get(userId);
        if (user != null) {
+37 −1
Original line number Diff line number Diff line
@@ -16,13 +16,17 @@

package com.android.server.media;

import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.PlaybackState;
import android.media.session.MediaSession;
import android.os.RemoteException;
import android.os.UserHandle;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Keeps track of media sessions and their priority for notifications, media
@@ -60,6 +64,36 @@ public class MediaSessionStack {
    private ArrayList<MediaSessionRecord> mCachedActiveList;
    private ArrayList<MediaSessionRecord> mCachedTransportControlList;

    /**
     * Checks if a media session is created from the most recent app.
     *
     * @param record A media session record to be examined.
     * @return true if the media session's package name equals to the most recent app, false
     * otherwise.
     */
    private static boolean isFromMostRecentApp(MediaSessionRecord record) {
        if (ActivityManager.getCurrentUser() != record.getUserId()) {
            return false;
        }
        try {
            List<ActivityManager.RecentTaskInfo> tasks =
                    ActivityManagerNative.getDefault().getRecentTasks(1,
                            ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
                            ActivityManager.RECENT_IGNORE_UNAVAILABLE |
                            ActivityManager.RECENT_INCLUDE_PROFILES |
                            ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId());
            if (tasks != null && !tasks.isEmpty()) {
                ActivityManager.RecentTaskInfo recentTask = tasks.get(0);
                if (recentTask.baseIntent != null)
                    return recentTask.baseIntent.getComponent().getPackageName()
                            .equals(record.getPackageName());
            }
        } catch (RemoteException e) {
            return false;
        }
        return false;
    }

    /**
     * Add a record to the priority tracker.
     *
@@ -68,8 +102,10 @@ public class MediaSessionStack {
    public void addSession(MediaSessionRecord record) {
        mSessions.add(record);
        clearCache();
        if (isFromMostRecentApp(record)) {
            mLastInterestingRecord = record;
        }
    }

    /**
     * Remove a record from the priority tracker.