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

Commit 9547ad93 authored by Marie Janssen's avatar Marie Janssen Committed by Gerrit Code Review
Browse files

Merge "AVRCP: synchronize with better granularity"

parents 9e6cef6f dc3c9e69
Loading
Loading
Loading
Loading
+208 −195
Original line number Diff line number Diff line
@@ -1449,23 +1449,24 @@ public final class Avrcp {
        return false;
    }

    private synchronized void removePackageFromBrowseList(String packageName) {
    private void removePackageFromBrowseList(String packageName) {
        if (DEBUG) Log.d(TAG, "removePackageFromBrowseList: " + packageName);
        synchronized (mBrowsePlayerInfoList) {
            int browseInfoID = getBrowseId(packageName);
            if (browseInfoID != -1) {
                mBrowsePlayerInfoList.remove(browseInfoID);
            }
        }
    }

    /*
     * utility function to get the browse player index from global browsable
     * list. It may return -1 if specified package name is not in the list.
     */
    private synchronized int getBrowseId(String packageName) {

    private int getBrowseId(String packageName) {
        boolean response = false;
        int browseInfoID = 0;

        synchronized (mBrowsePlayerInfoList) {
            for (BrowsePlayerInfo info : mBrowsePlayerInfoList) {
                if (info.packageName.equals(packageName)) {
                    response = true;
@@ -1473,6 +1474,7 @@ public final class Avrcp {
                }
                browseInfoID++;
            }
        }

        if (!response) {
            browseInfoID = -1;
@@ -1486,10 +1488,11 @@ public final class Avrcp {
    private void setAddressedPlayer(byte[] bdaddr, int selectedId) {
        int status = AvrcpConstants.RSP_NO_ERROR;

        if (isCurrentMediaPlayerListEmpty()) {
        synchronized (mMediaPlayerInfoList) {
            if (mMediaPlayerInfoList.isEmpty()) {
                status = AvrcpConstants.RSP_NO_AVBL_PLAY;
                Log.w(TAG, " No Available Players to set, sending response back ");
        } else if (!isIdValid(selectedId)) {
            } else if (!mMediaPlayerInfoList.containsKey(selectedId)) {
                status = AvrcpConstants.RSP_INV_PLAYER;
                Log.w(TAG, " Invalid Player id: " + selectedId + " to set, sending response back ");
            } else if (!isPlayerAlreadyAddressed(selectedId)) {
@@ -1502,6 +1505,7 @@ public final class Avrcp {
                MediaPlayerInfo info = getAddressedPlayerInfo();
                Log.i(TAG, "addressed player " + info + "is already focused");
            }
        }

        if (DEBUG) Log.d(TAG, "setAddressedPlayer for selectedId: " + selectedId +
                " , status: " + status);
@@ -1513,7 +1517,7 @@ public final class Avrcp {
        int status = AvrcpConstants.RSP_NO_ERROR;

        // checking for error cases
        if (isCurrentMediaPlayerListEmpty()) {
        if (mMediaPlayerInfoList.isEmpty()) {
            status = AvrcpConstants.RSP_NO_AVBL_PLAY;
            Log.w(TAG, " No Available Players to set, sending response back ");
        } else {
@@ -1589,18 +1593,18 @@ public final class Avrcp {
            addMediaPlayerPackage(packageName);
            mHandler.sendEmptyMessage(MSG_AVAILABLE_PLAYERS_CHANGED_RSP);
        }
        synchronized (mMediaPlayerInfoList) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
            if (DEBUG)
                Log.v(TAG, "Find player id: " + entry.getKey() + " is "
                                + entry.getValue().getPackageName());
                if (entry.getValue().getPackageName().equals(packageName)) {
                int newAddressedID = entry.getKey();
                updateCurrentController(newAddressedID, mCurrBrowsePlayerID);
                mHandler.obtainMessage(MSG_ADDRESSED_PLAYER_CHANGED_RSP, newAddressedID, 0)
                    int newAddrID = entry.getKey();
                    if (DEBUG) Log.v(TAG, "Set addressed #" + newAddrID + " " + entry.getValue());
                    updateCurrentController(newAddrID, mCurrBrowsePlayerID);
                    mHandler.obtainMessage(MSG_ADDRESSED_PLAYER_CHANGED_RSP, newAddrID, 0)
                            .sendToTarget();
                    return;
                }
            }
        }
        // We shouldn't ever get here.
        Log.e(TAG, "Player info for " + packageName + " doesn't exist!");
    }
@@ -1631,14 +1635,16 @@ public final class Avrcp {
        return status;
    }

    private synchronized String getBrowseServiceName(String packageName) {
    private String getBrowseServiceName(String packageName) {
        String browseServiceName = "";

        // getting the browse service name from browse player info
        synchronized (mBrowsePlayerInfoList) {
            int browseInfoID = getBrowseId(packageName);
            if (browseInfoID != -1) {
                browseServiceName = mBrowsePlayerInfoList.get(browseInfoID).serviceClass;
            }
        }

        if (DEBUG) Log.d(TAG, "getBrowseServiceName for packageName: " + packageName +
                ", browseServiceName = " + browseServiceName);
@@ -1724,7 +1730,8 @@ public final class Avrcp {
    }

    /* Initializes list of media players identified from session manager active sessions */
    private synchronized void initMediaPlayersList() {
    private void initMediaPlayersList() {
        synchronized (mMediaPlayerInfoList) {
            // Clearing old browsable player's list
            mMediaPlayerInfoList.clear();

@@ -1735,7 +1742,8 @@ public final class Avrcp {

            List<android.media.session.MediaController> controllers =
                    mMediaSessionManager.getActiveSessions(null);
        if (DEBUG) Log.v(TAG, "initMediaPlayerInfoList: " + controllers.size() + " controllers");
            if (DEBUG)
                Log.v(TAG, "initMediaPlayerInfoList: " + controllers.size() + " controllers");
            /* Initializing all media players */
            for (android.media.session.MediaController controller : controllers) {
                addMediaPlayerController(controller);
@@ -1749,20 +1757,23 @@ public final class Avrcp {
                updateCurrentController(mMediaPlayerInfoList.firstKey(), -1);
            }
        }
    }

    private List<android.media.session.MediaController> getMediaControllers() {
        List<android.media.session.MediaController> controllers =
                new ArrayList<android.media.session.MediaController>();
        synchronized (mMediaPlayerInfoList) {
            for (MediaPlayerInfo info : mMediaPlayerInfoList.values()) {
                if (info.getMediaController() != null) {
                    controllers.add(info.getMediaController().getWrappedInstance());
                }
            }
        }
        return controllers;
    }

    /** Add (or update) a player to the media player list without a controller */
    private synchronized boolean addMediaPlayerPackage(String packageName) {
    private boolean addMediaPlayerPackage(String packageName) {
        MediaPlayerInfo info = new MediaPlayerInfo(null, AvrcpConstants.PLAYER_TYPE_AUDIO,
                AvrcpConstants.PLAYER_SUBTYPE_NONE, getPlayStateBytes(null),
                getFeatureBitMask(packageName), packageName, getAppLabel(packageName));
@@ -1770,8 +1781,7 @@ public final class Avrcp {
    }

    /** Add (or update) a player to the media player list given an active controller */
    private synchronized boolean addMediaPlayerController(
            android.media.session.MediaController controller) {
    private boolean addMediaPlayerController(android.media.session.MediaController controller) {
        String packageName = controller.getPackageName();
        MediaPlayerInfo info = new MediaPlayerInfo(MediaController.wrap(controller),
                AvrcpConstants.PLAYER_TYPE_AUDIO, AvrcpConstants.PLAYER_SUBTYPE_NONE,
@@ -1783,10 +1793,11 @@ public final class Avrcp {
    /** Add or update a player to the media player list given the MediaPlayerInfo object.
     *  @return true if an item was updated, false if it was added instead
     */
    private synchronized boolean addMediaPlayerInfo(MediaPlayerInfo info) {
    private boolean addMediaPlayerInfo(MediaPlayerInfo info) {
        if (DEBUG) Log.d(TAG, "add " + info.toString());
        int updateId = -1;
        boolean updated = false;
        synchronized (mMediaPlayerInfoList) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
                if (info.getPackageName().equals(entry.getValue().getPackageName())) {
                    updateId = entry.getKey();
@@ -1802,11 +1813,13 @@ public final class Avrcp {
                updateCurrentController(mCurrAddrPlayerID, mCurrBrowsePlayerID);
            }
            mMediaPlayerInfoList.put(updateId, info);
        }
        return updated;
    }

    /** Remove all players related to |packageName| from the media player info list */
    private synchronized MediaPlayerInfo removeMediaPlayerInfo(String packageName) {
    private MediaPlayerInfo removeMediaPlayerInfo(String packageName) {
        synchronized (mMediaPlayerInfoList) {
            int removeKey = -1;
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
                if (entry.getValue().getPackageName().equals(packageName)) {
@@ -1820,6 +1833,7 @@ public final class Avrcp {

            return null;
        }
    }

    /*
     * utility function to get the playback state of any media player through
@@ -1913,7 +1927,8 @@ public final class Avrcp {
     * @param packageName - name of the package to get the Id.
     * @return true if it supports browsing, else false.
     */
    private synchronized boolean isBrowseSupported(String packageName) {
    private boolean isBrowseSupported(String packageName) {
        synchronized (mBrowsePlayerInfoList) {
            /* check if Browsable Player's list contains this package name */
            for (BrowsePlayerInfo info : mBrowsePlayerInfoList) {
                if (info.packageName.equals(packageName)) {
@@ -1921,13 +1936,17 @@ public final class Avrcp {
                    return true;
                }
            }
        }

        if (DEBUG) Log.v(TAG, "isBrowseSupported for " + packageName + ": false");
        return false;
    }

    private String getPackageName(int id) {
        MediaPlayerInfo player = mMediaPlayerInfoList.getOrDefault(id, null);
        MediaPlayerInfo player = null;
        synchronized (mMediaPlayerInfoList) {
            player = mMediaPlayerInfoList.getOrDefault(id, null);
        }

        if (player == null) {
            Log.w(TAG, "No package name for player (" + id + " not valid)");
@@ -1953,15 +1972,18 @@ public final class Avrcp {
    }

    /* Returns the MediaPlayerInfo for the currently addressed media player */
    private synchronized MediaPlayerInfo getAddressedPlayerInfo() {
    private MediaPlayerInfo getAddressedPlayerInfo() {
        synchronized (mMediaPlayerInfoList) {
            return mMediaPlayerInfoList.getOrDefault(mCurrAddrPlayerID, null);
        }
    }

    /*
     * Utility function to get the Media player info from package name returns
     * null if package name not found in media players list
     */
    private synchronized MediaPlayerInfo getMediaPlayerInfo(String packageName) {
    private MediaPlayerInfo getMediaPlayerInfo(String packageName) {
        synchronized (mMediaPlayerInfoList) {
            if (mMediaPlayerInfoList.isEmpty()) {
                if (DEBUG) Log.v(TAG, "getMediaPlayerInfo: Media players list empty");
                return null;
@@ -1976,11 +1998,11 @@ public final class Avrcp {
            if (DEBUG) Log.w(TAG, "getMediaPlayerInfo: " + packageName + " not found");
            return null;
        }
    }

    /* prepare media list & return the media player list response object */
    private synchronized MediaPlayerListRsp prepareMediaPlayerRspObj() {

        /* Forming player list -- */
    private MediaPlayerListRsp prepareMediaPlayerRspObj() {
        synchronized (mMediaPlayerInfoList) {
            int numPlayers = mMediaPlayerInfoList.size();

            int[] playerIds = new int[numPlayers];
@@ -1988,8 +2010,8 @@ public final class Avrcp {
            int[] playerSubTypes = new int[numPlayers];
            String[] displayableNameArray = new String[numPlayers];
            byte[] playStatusValues = new byte[numPlayers];
        short[] featureBitMaskValues = new short[numPlayers
                * AvrcpConstants.AVRC_FEATURE_MASK_SIZE];
            short[] featureBitMaskValues =
                    new short[numPlayers * AvrcpConstants.AVRC_FEATURE_MASK_SIZE];

            int players = 0;
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
@@ -2006,15 +2028,16 @@ public final class Avrcp {
                    byte octet = (byte) (featureBits[numBit] / 8);
                    /* gives the bit position within the octet */
                    byte bit = (byte) (featureBits[numBit] % 8);
                featureBitMaskValues[(players * AvrcpConstants.AVRC_FEATURE_MASK_SIZE) + octet] |=
                        (1 << bit);
                    featureBitMaskValues[(players * AvrcpConstants.AVRC_FEATURE_MASK_SIZE)
                            + octet] |= (1 << bit);
                }

                /* printLogs */
                if (DEBUG) {
                    Log.d(TAG, "Player " + playerIds[players] + ": " + displayableNameArray[players]
                                + " type: " + playerTypes[players] + ", " + playerSubTypes[players]
                                + " status: " + playStatusValues[players]);
                                    + " type: " + playerTypes[players] + ", "
                                    + playerSubTypes[players] + " status: "
                                    + playStatusValues[players]);
                }

                players++;
@@ -2026,23 +2049,28 @@ public final class Avrcp {
                    AvrcpConstants.BTRC_ITEM_PLAYER, playerIds, playerTypes, playerSubTypes,
                    playStatusValues, featureBitMaskValues, displayableNameArray);
        }
    }

     /* build media player list and send it to remote. */
    private void handleMediaPlayerListRsp(AvrcpCmd.FolderItemsCmd folderObj) {
        if (mMediaPlayerInfoList.size() == 0) {
            mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_NO_AVBL_PLAY, (short) 0,
                    (byte) 0, 0, null, null, null, null, null, null);
        MediaPlayerListRsp rspObj = null;
        synchronized (mMediaPlayerInfoList) {
            int numPlayers = mMediaPlayerInfoList.size();
            if (numPlayers == 0) {
                mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_NO_AVBL_PLAY,
                        (short) 0, (byte) 0, 0, null, null, null, null, null, null);
                return;
            }
        if (folderObj.mStartItem >= mMediaPlayerInfoList.size()) {
            Log.i(TAG, "handleMediaPlayerListRsp: start item = " + folderObj.mStartItem
                            + ", but available num of items = " + mMediaPlayerInfoList.size());
            mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_INV_RANGE, (short) 0,
                    (byte) 0, 0, null, null, null, null, null, null);
            if (folderObj.mStartItem >= numPlayers) {
                Log.i(TAG, "handleMediaPlayerListRsp: start = " + folderObj.mStartItem
                                + " > num of items = " + numPlayers);
                mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_INV_RANGE,
                        (short) 0, (byte) 0, 0, null, null, null, null, null, null);
                return;
            }
        MediaPlayerListRsp rspObj = prepareMediaPlayerRspObj();
        if (DEBUG) Log.d(TAG, "handleMediaPlayerListRsp: send " + rspObj.mNumItems + " players");
            rspObj = prepareMediaPlayerRspObj();
        }
        if (DEBUG) Log.d(TAG, "handleMediaPlayerListRsp: sending " + rspObj.mNumItems + " players");
        mediaPlayerListRspNative(folderObj.mAddress, rspObj.mStatus, rspObj.mUIDCounter,
                rspObj.itemType, rspObj.mNumItems, rspObj.mPlayerIds, rspObj.mPlayerTypes,
                rspObj.mPlayerSubTypes, rspObj.mPlayStatusValues, rspObj.mFeatureBitMaskValues,
@@ -2113,7 +2141,7 @@ public final class Avrcp {
    }

    /* utility function to update the global values of current Addressed and browsed player */
    private synchronized void updateNewIds(int addrId, int browseId) {
    private void updateNewIds(int addrId, int browseId) {
        mCurrAddrPlayerID = addrId;
        mCurrBrowsePlayerID = browseId;

@@ -2173,11 +2201,12 @@ public final class Avrcp {
    private void handleGetTotalNumOfItemsResponse(byte[] bdaddr, byte scope) {
        // for scope as media player list
        if (scope == AvrcpConstants.BTRC_SCOPE_PLAYER_LIST) {
            int numPlayers = getPlayerListSize();
            if (DEBUG) Log.d(TAG, "handleGetTotalNumOfItemsResponse: sending total " + numPlayers +
                    " media players.");
            getTotalNumOfItemsRspNative(bdaddr, AvrcpConstants.RSP_NO_ERROR, 0,
                    numPlayers);
            int numPlayers = 0;
            synchronized (mMediaPlayerInfoList) {
                numPlayers = mMediaPlayerInfoList.size();
            }
            if (DEBUG) Log.d(TAG, "handleGetTotalNumOfItemsResponse: " + numPlayers + " players.");
            getTotalNumOfItemsRspNative(bdaddr, AvrcpConstants.RSP_NO_ERROR, 0, numPlayers);
        } else if (scope == AvrcpConstants.BTRC_SCOPE_NOW_PLAYING) {
            mAddressedMediaPlayer.getTotalNumOfItems(bdaddr, mMediaController);
        } else {
@@ -2192,10 +2221,6 @@ public final class Avrcp {

    }

    private synchronized int getPlayerListSize() {
        return mMediaPlayerInfoList.size();
    }

    /* check if browsed player and addressed player are same */
    private boolean isAddrPlayerSameAsBrowsed(byte[] bdaddr) {
        String browsedPlayer = getCurrentBrowsedPlayer(bdaddr);
@@ -2214,20 +2239,6 @@ public final class Avrcp {
        return true;
    }

    /* checks if global object containing media player list is empty */
    private boolean isCurrentMediaPlayerListEmpty() {
        boolean isEmpty = mMediaPlayerInfoList.isEmpty();
        if (DEBUG) Log.d(TAG, "Current MediaPlayer List Empty.= " + isEmpty);
        return isEmpty;
    }

    /* checks if the id is within the range of global object containing media player list */
    private boolean isIdValid(int id) {
        boolean isValid = mMediaPlayerInfoList.containsKey(id);
        if (!isValid && DEBUG) Log.d(TAG, "Id " + id + " is not valid!");
        return isValid;
    }

    /* checks if package name is not null or empty */
    private boolean isPackageNameValid(String browsedPackage) {
        boolean isValid = (browsedPackage != null && browsedPackage.length() > 0);
@@ -2274,10 +2285,12 @@ public final class Avrcp {
            ProfileService.println(sb, "mMediaSession pkg: " + mMediaController.getPackageName());

        ProfileService.println(sb, "\nMedia Players:");
        synchronized (mMediaPlayerInfoList) {
            for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
                int key = entry.getKey();
            ProfileService.println(sb, ((mCurrAddrPlayerID == key) ? " *#" : "  #") + entry.getKey()
                            + ": " + entry.getValue());
                ProfileService.println(sb, ((mCurrAddrPlayerID == key) ? " *#" : "  #")
                                + entry.getKey() + ": " + entry.getValue());
            }
        }

        ProfileService.println(sb, "Passthrough operations: ");