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

Commit c3b3752b authored by Marie Janssen's avatar Marie Janssen
Browse files

AVRCP: set addressed player on key dispatch

MediaSessionManager.Callback.onAddressedPlayerChanged isn't being called
consistently when the package that receives media keys changes.

This affects media metadata showing up because the addressed player
controls the mMediaController.

Update the addressed player for every media key press as a workaround.

Adjust logging to reduce logspam.

Test: connect to carkit, play from GPM then switch to Youtube.
Bug: 37789858
Bug: 34471252
Bug: 37998705
Bug: 37865298
Change-Id: Ic94bb97d51f48f9799edfca0d5f9a9b2872b0132
parent 6a7d87ea
Loading
Loading
Loading
Loading
+26 −19
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.bluetooth.avrcp;
package com.android.bluetooth.avrcp;


import android.annotation.Nullable;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAvrcp;
import android.bluetooth.BluetoothAvrcp;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
@@ -52,8 +53,8 @@ import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.R;
import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.Utils;


import java.util.concurrent.CountDownLatch;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Iterator;
import java.util.List;
import java.util.List;
@@ -190,7 +191,7 @@ public final class Avrcp {
    /* Recording passthrough key dispatches */
    /* Recording passthrough key dispatches */
    static private final int PASSTHROUGH_LOG_MAX_SIZE = DEBUG ? 50 : 10;
    static private final int PASSTHROUGH_LOG_MAX_SIZE = DEBUG ? 50 : 10;
    private EvictingQueue<MediaKeyLog> mPassthroughLogs; // Passthorugh keys dispatched
    private EvictingQueue<MediaKeyLog> mPassthroughLogs; // Passthorugh keys dispatched
    private ArrayList<MediaKeyLog> mPassthroughPending; // Passthrough keys sent not dispatched yet
    private List<MediaKeyLog> mPassthroughPending; // Passthrough keys sent not dispatched yet
    private int mPassthroughDispatched; // Number of keys dispatched
    private int mPassthroughDispatched; // Number of keys dispatched


    private class MediaKeyLog {
    private class MediaKeyLog {
@@ -205,8 +206,6 @@ public final class Avrcp {
        }
        }


        public boolean addDispatch(long time, KeyEvent event, String packageName) {
        public boolean addDispatch(long time, KeyEvent event, String packageName) {
            if (DEBUG)
                Log.v(TAG, "addDispatch: Trying to match " + mEvent + " and record " + packageName);
            if (mPackage != null) return false;
            if (mPackage != null) return false;
            if (event.getAction() != mEvent.getAction()) return false;
            if (event.getAction() != mEvent.getAction()) return false;
            if (event.getKeyCode() != mEvent.getKeyCode()) return false;
            if (event.getKeyCode() != mEvent.getKeyCode()) return false;
@@ -302,7 +301,7 @@ public final class Avrcp {
        mBrowsePlayerInfoList = new ArrayList<BrowsePlayerInfo>();
        mBrowsePlayerInfoList = new ArrayList<BrowsePlayerInfo>();
        mPassthroughDispatched = 0;
        mPassthroughDispatched = 0;
        mPassthroughLogs = new EvictingQueue<MediaKeyLog>(PASSTHROUGH_LOG_MAX_SIZE);
        mPassthroughLogs = new EvictingQueue<MediaKeyLog>(PASSTHROUGH_LOG_MAX_SIZE);
        mPassthroughPending = new ArrayList<MediaKeyLog>();
        mPassthroughPending = Collections.synchronizedList(new ArrayList<MediaKeyLog>());
        if (mMediaSessionManager != null) {
        if (mMediaSessionManager != null) {
            mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveSessionListener, null,
            mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveSessionListener, null,
                    mHandler);
                    mHandler);
@@ -1598,8 +1597,7 @@ public final class Avrcp {
                }
                }
            };
            };


    private void setAddressedMediaSessionPackage(String packageName) {
    private void setAddressedMediaSessionPackage(@Nullable String packageName) {
        if (DEBUG) Log.v(TAG, "Setting addressed media session to " + packageName);
        if (packageName == null) {
        if (packageName == null) {
            // Should only happen when there's no media players, reset to no available player.
            // Should only happen when there's no media players, reset to no available player.
            updateCurrentController(0, mCurrBrowsePlayerID);
            updateCurrentController(0, mCurrBrowsePlayerID);
@@ -1607,6 +1605,7 @@ public final class Avrcp {
        }
        }
        // No change.
        // No change.
        if (getPackageName(mCurrAddrPlayerID).equals(packageName)) return;
        if (getPackageName(mCurrAddrPlayerID).equals(packageName)) return;
        if (DEBUG) Log.v(TAG, "Changing addressed media session to " + packageName);
        // If the player doesn't exist, we need to add it.
        // If the player doesn't exist, we need to add it.
        if (getMediaPlayerInfo(packageName) == null) {
        if (getMediaPlayerInfo(packageName) == null) {
            addMediaPlayerPackage(packageName);
            addMediaPlayerPackage(packageName);
@@ -2105,6 +2104,7 @@ public final class Avrcp {


        MediaController newController = null;
        MediaController newController = null;
        MediaPlayerInfo info = getAddressedPlayerInfo();
        MediaPlayerInfo info = getAddressedPlayerInfo();
        if (info != null) newController = info.getMediaController();


        if (DEBUG)
        if (DEBUG)
            Log.d(TAG, "updateCurrentController: " + mMediaController + " to " + newController);
            Log.d(TAG, "updateCurrentController: " + mMediaController + " to " + newController);
@@ -2152,11 +2152,11 @@ public final class Avrcp {


    /* utility function to update the global values of current Addressed and browsed player */
    /* utility function to update the global values of current Addressed and browsed player */
    private void updateNewIds(int addrId, int browseId) {
    private void updateNewIds(int addrId, int browseId) {
        if (DEBUG)
            Log.v(TAG, "updateNewIds: Addressed:" + mCurrAddrPlayerID + " to " + addrId
                            + ", Browse:" + mCurrBrowsePlayerID + " to " + browseId);
        mCurrAddrPlayerID = addrId;
        mCurrAddrPlayerID = addrId;
        mCurrBrowsePlayerID = browseId;
        mCurrBrowsePlayerID = browseId;

        if (DEBUG) Log.v(TAG, "Updated CurrentIds: AddrPlayerID:" + mCurrAddrPlayerID + " to "
                + addrId + ", BrowsePlayerID:" + mCurrBrowsePlayerID + " to " + browseId);
    }
    }


    /* Getting the application's displayable name from package name */
    /* Getting the application's displayable name from package name */
@@ -2297,7 +2297,8 @@ public final class Avrcp {
            ProfileService.println(sb, "mMediaController: " + mMediaController.getWrappedInstance()
            ProfileService.println(sb, "mMediaController: " + mMediaController.getWrappedInstance()
                            + " pkg " + mMediaController.getPackageName());
                            + " pkg " + mMediaController.getPackageName());


        ProfileService.println(sb, "\nMedia Players:");
        ProfileService.println(sb, "");
        ProfileService.println(sb, "Media Players:");
        synchronized (mMediaPlayerInfoList) {
        synchronized (mMediaPlayerInfoList) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
                int key = entry.getKey();
                int key = entry.getKey();
@@ -2306,14 +2307,20 @@ public final class Avrcp {
            }
            }
        }
        }


        ProfileService.println(sb, "Passthrough operations: ");
        ProfileService.println(sb, mPassthroughDispatched + " passthrough operations: ");
        if (mPassthroughDispatched > mPassthroughLogs.size())
            ProfileService.println(sb, "  (last " + mPassthroughLogs.size() + ")");
        synchronized (mPassthroughLogs) {
            for (MediaKeyLog log : mPassthroughLogs) {
            for (MediaKeyLog log : mPassthroughLogs) {
                ProfileService.println(sb, "  " + log);
                ProfileService.println(sb, "  " + log);
            }
            }
        }
        synchronized (mPassthroughPending) {
            for (MediaKeyLog log : mPassthroughPending) {
            for (MediaKeyLog log : mPassthroughPending) {
                ProfileService.println(sb, "  " + log);
                ProfileService.println(sb, "  " + log);
            }
            }
        }
        }
    }


    public class AvrcpBrowseManager {
    public class AvrcpBrowseManager {
        Map<String, BrowsedMediaPlayer> connList = new HashMap<String, BrowsedMediaPlayer>();
        Map<String, BrowsedMediaPlayer> connList = new HashMap<String, BrowsedMediaPlayer>();
@@ -2627,14 +2634,13 @@ public final class Avrcp {
    }
    }


    private void addKeyPending(KeyEvent event) {
    private void addKeyPending(KeyEvent event) {
        synchronized (mPassthroughPending) {
        mPassthroughPending.add(new MediaKeyLog(System.currentTimeMillis(), event));
        mPassthroughPending.add(new MediaKeyLog(System.currentTimeMillis(), event));
    }
    }
    }


    private void recordKeyDispatched(KeyEvent event, String packageName) {
    private void recordKeyDispatched(KeyEvent event, String packageName) {
        long time = System.currentTimeMillis();
        long time = System.currentTimeMillis();
        Log.v(TAG, "recordKeyDispatched: " + event + " dispatched to " + packageName);
        Log.v(TAG, "recordKeyDispatched: " + event + " dispatched to " + packageName);
        setAddressedMediaSessionPackage(packageName);
        synchronized (mPassthroughPending) {
        synchronized (mPassthroughPending) {
            Iterator<MediaKeyLog> pending = mPassthroughPending.iterator();
            Iterator<MediaKeyLog> pending = mPassthroughPending.iterator();
            while (pending.hasNext()) {
            while (pending.hasNext()) {
@@ -2646,6 +2652,7 @@ public final class Avrcp {
                    return;
                    return;
                }
                }
            }
            }
            Log.w(TAG, "recordKeyDispatch: can't find matching log!");
        }
        }
    }
    }