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

Commit c1db133f authored by Ayan Ghosh's avatar Ayan Ghosh Committed by rakesh reddy
Browse files

Properly handle NowPlayingList Browsing commands

Properly handle NowPlayingList Browsing commands
by ensuring the following:
  - Change data type to store Max value of End index.
  - Change implementation to properly handle request
    for any un-supported attribute.
  - Properly store and use start index offset while
    responding with items in NowPlayingList.

CRs-Fixed: 753306 753307 753310

Change-Id: Iccce0ab0577277ebc5107c4e52ef1013eaeaeab3
parent 63728236
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -304,8 +304,8 @@ static void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype) {

static void btavrcp_get_folder_items_callback(btrc_browse_folderitem_t scope ,
                                                        btrc_getfolderitem_t *param) {
    jint start = param->start_item;
    jint end = param->end_item;
    jlong start = param->start_item;
    jlong end = param->end_item;
    jint size = param->size;
    jint num_attr = param->attr_count;
    jintArray attrs;
@@ -516,7 +516,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
        env->GetMethodID(clazz, "setAddressedPlayer", "(I)V");
    //getFolderItems: attributes to pass: Scope, Start, End, Attr Cnt
    method_getFolderItems =
        env->GetMethodID(clazz, "getFolderItems", "(BIIII[I)V");
        env->GetMethodID(clazz, "getFolderItems", "(BJJII[I)V");
    method_setBrowsedPlayer =
        env->GetMethodID(clazz, "setBrowsedPlayer", "(I)V");
    method_changePath =
@@ -1081,7 +1081,7 @@ static jboolean registerNotificationRspNowPlayingContentChangedNative(JNIEnv *en
}

static jboolean getFolderItemsRspNative(JNIEnv *env, jobject object, jbyte statusCode,
                            jint numItems, jintArray itemType, jlongArray uid, jintArray type,
                            jlong numItems, jintArray itemType, jlongArray uid, jintArray type,
                            jbyteArray playable, jobjectArray displayName, jbyteArray numAtt,
                                                    jobjectArray attValues, jintArray attIds) {
    bt_status_t status = BT_STATUS_SUCCESS;
@@ -1158,6 +1158,10 @@ static jboolean getFolderItemsRspNative(JNIEnv *env, jobject object, jbyte statu
            param.p_item_list[count].u.folder.playable = playableElements[count];

            text = (jstring) env->GetObjectArrayElement(displayName, count);
            if (text == NULL) {
                ALOGE("getFolderItemsRspNative: App string is NULL, bail out");
                break;
            }
            utfStringLength = env->GetStringUTFLength(text);
            if (!utfStringLength) {
                ALOGE("getFolderItemsRspNative: GetStringUTFLength return NULL");
@@ -1186,6 +1190,10 @@ static jboolean getFolderItemsRspNative(JNIEnv *env, jobject object, jbyte statu
            param.p_item_list[count].u.media.type = (uint8_t)typeElements[count];
            ALOGI("getFolderItemsRspNative: type: %d", param.p_item_list[count].u.folder.type);
            text = (jstring) env->GetObjectArrayElement(displayName, count);
            if (text == NULL) {
                ALOGE("getFolderItemsRspNative: App string is NULL, bail out");
                break;
            }
            utfStringLength = env->GetStringUTFLength(text);
            if (!utfStringLength) {
                ALOGE("getFolderItemsRspNative: GetStringUTFLength return NULL");
@@ -1213,6 +1221,10 @@ static jboolean getFolderItemsRspNative(JNIEnv *env, jobject object, jbyte statu

            for (int i = 0; i < numAttElements[count]; i++) {
                text = (jstring) env->GetObjectArrayElement(attValues, (7 * count) + i);
                if (text == NULL) {
                    ALOGE("getFolderItemsRspNative: Attribute string is NULL, continue to next");
                    continue;
                }
                utfStringLength = env->GetStringUTFLength(text);
                if (!utfStringLength) {
                    ALOGE("getFolderItemsRspNative: GetStringUTFLength return NULL");
@@ -1594,7 +1606,7 @@ static JNINativeMethod sMethods[] = {
    {"changePathRspNative", "(IJ)Z", (void *) changePathRspNative},
    {"playItemRspNative", "(I)Z", (void *) playItemRspNative},
    {"getItemAttrRspNative", "(B[I[Ljava/lang/String;)Z", (void *) getItemAttrRspNative},
    {"getFolderItemsRspNative", "(BI[I[J[I[B[Ljava/lang/String;[B[Ljava/lang/String;[I)Z",
    {"getFolderItemsRspNative", "(BJ[I[J[I[B[Ljava/lang/String;[B[Ljava/lang/String;[I)Z",
                                                            (void *) getFolderItemsRspNative},
};

+83 −49
Original line number Diff line number Diff line
@@ -1254,8 +1254,8 @@ public final class Avrcp {
    void updateNowPlayingEntriesReceived(long[] playList) {
        int status = OPERATION_SUCCESSFUL;
        int numItems = 0;
        int reqItems = (mCachedRequest.mEnd - mCachedRequest.mStart) + 1;
        int availableItems = 0;
        long reqItems = (mCachedRequest.mEnd - mCachedRequest.mStart) + 1;
        long availableItems = 0;
        Cursor cursor = null;
        int[] itemType = new int[MAX_BROWSE_ITEM_TO_SEND];
        long[] uid = new long[MAX_BROWSE_ITEM_TO_SEND];
@@ -1292,18 +1292,23 @@ public final class Avrcp {
        }

        availableItems = availableItems - mCachedRequest.mStart;
        Log.i(TAG, "start Index: " + mCachedRequest.mStart);
        Log.i(TAG, "end Index: " + mCachedRequest.mEnd);
        Log.i(TAG, "availableItems: " + availableItems);
        if (availableItems > MAX_BROWSE_ITEM_TO_SEND)
            availableItems = MAX_BROWSE_ITEM_TO_SEND;
        if (reqItems > availableItems)
            reqItems = availableItems;
        Log.i(TAG, "reqItems: " + reqItems);

        for (index = 0; index < reqItems; index++) {
            try {
                cursor = mContext.getContentResolver().query(
                     mMediaUri, mCursorCols,
                     MediaStore.Audio.Media.IS_MUSIC + "=1 AND _id=" +
                                                playList[index], null, null);
                         playList[index + (int)mCachedRequest.mStart], null, null);
                if (cursor != null) {
                    int validAttrib = 0;
                    cursor.moveToFirst();
                    itemType[index] = TYPE_MEDIA_ELEMENT_ITEM;
                    uid[index] = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
@@ -1311,16 +1316,19 @@ public final class Avrcp {
                    playable[index] = 0;
                    displayName[index] = cursor.getString(cursor.getColumnIndexOrThrow(
                                                            MediaStore.Audio.Media.TITLE));
                    numAtt[index] = mCachedRequest.mAttrCnt;
                    for (int attIndex = 0; attIndex < mCachedRequest.mAttrCnt; attIndex++) {
                        int attr = mCachedRequest.mAttrList.get(attIndex).intValue();
                        attValues[(7 * index) + attIndex] = getAttributeStringFromCursor(
                                                    cursor, attr);
                        if ((attr <= MEDIA_ATTR_MAX) && (attr >= MEDIA_ATTR_MIN)) {
                            attValues[(7 * index) + attIndex] =
                                getAttributeStringFromCursor(cursor, attr);
                            attIds[(7 * index) + attIndex] = attr;
                            validAttrib ++;
                        }
                    }
                    numAtt[index] = (byte)validAttrib;
                }
            } catch(Exception e) {
                Log.i(TAG, "Exception e"+ e);
                Log.i(TAG, "Exception "+ e);
                getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType,
                            uid, type, playable, displayName, numAtt, attValues, attIds);
            } finally {
@@ -1335,11 +1343,11 @@ public final class Avrcp {
    }

    class CachedRequest {
        int mStart;
        int mEnd;
        long mStart;
        long mEnd;
        byte mAttrCnt;
        ArrayList<Integer> mAttrList;
        public CachedRequest(int start, int end, byte attrCnt, int[] attrs) {
        public CachedRequest(long start, long end, byte attrCnt, int[] attrs) {
            mStart = start;
            mEnd = end;
            mAttrCnt = attrCnt;
@@ -1352,12 +1360,12 @@ public final class Avrcp {

    class FolderListEntries {
        byte mScope;
        int mStart;
        int mEnd;
        long mStart;
        long mEnd;
        int mAttrCnt;
        int mNumAttr;
        ArrayList<Integer> mAttrList;
        public FolderListEntries(byte scope, int start, int end, int attrCnt, int numAttr,
        public FolderListEntries(byte scope, long start, long end, int attrCnt, int numAttr,
                                                                                int[] attrs) {
            mScope = scope;
            mStart = start;
@@ -2103,11 +2111,15 @@ public final class Avrcp {
                    Log.i(TAG, "Invalid track UID");
                    getItemAttrRspNative((byte)0, attrs, textArray);
                } else {
                    int validAttrib = 0;
                    cursor.moveToFirst();
                    for (int i = 0; i < numAttr; ++i) {
                        if ((attrs[i] <= MEDIA_ATTR_MAX) && (attrs[i] >= MEDIA_ATTR_MIN)) {
                            textArray[i] = getAttributeStringFromCursor(cursor, attrs[i]);
                            validAttrib ++;
                        }
                    }
                    getItemAttrRspNative(numAttr, attrs, textArray);
                    getItemAttrRspNative((byte)validAttrib, attrs, textArray);
                }
            } catch (Exception e) {
                Log.e(TAG, "Exception " + e);
@@ -2176,7 +2188,7 @@ public final class Avrcp {
        }
    }

    private void getFolderItems(byte scope, int start, int end, int attrCnt,
    private void getFolderItems(byte scope, long start, long end, int attrCnt,
                                                        int numAttr, int[] attrs) {
        if (DEBUG) Log.v(TAG, "getFolderItems");
        if (DEBUG) Log.v(TAG, "scope: " + scope + " attrCnt: " + attrCnt);
@@ -2191,7 +2203,7 @@ public final class Avrcp {
        mHandler.sendMessage(msg);
    }

    private void processGetFolderItems(byte scope, int start, int end, int size,
    private void processGetFolderItems(byte scope, long start, long end, int size,
                                                                int numAttr, int[] attrs) {
        if (DEBUG) Log.v(TAG, "processGetFolderItems");
        if (DEBUG) Log.v(TAG, "scope: " + scope + " size: " + size);
@@ -2206,7 +2218,7 @@ public final class Avrcp {
        }
    }

    private void processGetMediaPlayerItems(byte scope, int start, int end, int size,
    private void processGetMediaPlayerItems(byte scope, long start, long end, int size,
                                                                int numAttr, int[] attrs) {
        byte[] folderItems = new byte[size];
        int[] folderItemLengths = new int[32];
@@ -2246,12 +2258,12 @@ public final class Avrcp {
        return false;
    }

    private void processGetFolderItemsInternal(byte scope, int start, int end, int size,
    private void processGetFolderItemsInternal(byte scope, long start, long end, long size,
                                                                    byte numAttr, int[] attrs) {

        int status = OPERATION_SUCCESSFUL;
        int numItems = 0;
        int reqItems = (end - start) + 1;
        long numItems = 0;
        long reqItems = (end - start) + 1;
        int[] itemType = new int[MAX_BROWSE_ITEM_TO_SEND];
        long[] uid = new long[MAX_BROWSE_ITEM_TO_SEND];
        int[] type = new int[MAX_BROWSE_ITEM_TO_SEND];
@@ -2292,7 +2304,7 @@ public final class Avrcp {
            }

            if (mCurrentPath.equals(PATH_ROOT)) {
                int availableItems = NUM_ROOT_ELEMENTS;
                long availableItems = NUM_ROOT_ELEMENTS;
                if (start >= availableItems) {
                    Log.i(TAG, "startIteam exceeds the available item index");
                    getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid,
@@ -2311,8 +2323,8 @@ public final class Avrcp {
                numItems = reqItems;

                for (int count = 0; count < reqItems; count ++) {
                    int index = start + count;
                    switch (index) {
                    long index = start + count;
                    switch ((int)index) {
                        case ALBUMS_ITEM_INDEX:
                            itemType[count] = TYPE_FOLDER_ITEM;
                            uid[count] = UID_ALBUM;
@@ -2359,7 +2371,7 @@ public final class Avrcp {
                getFolderItemsRspNative((byte)status, numItems, itemType, uid, type,
                                    playable, displayName, numAtt, attValues, attIds);
            } else if (mCurrentPath.equals(PATH_TITLES)) {
                int availableItems = 0;
                long availableItems = 0;
                Cursor cursor = null;
                try {
                    cursor = mContext.getContentResolver().query(
@@ -2404,12 +2416,17 @@ public final class Avrcp {
                        displayName[index] =
                            cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.
                                                                    Audio.Media.TITLE));
                        numAtt[index] = numAttr;
                        int validAttrib = 0;
                        for (attIndex = 0; attIndex < numAttr; attIndex++) {
                            attValues[(7 * index) + attIndex] = getAttributeStringFromCursor(
                                                                    cursor, attrs[attIndex]);
                            if ((attrs[attIndex] <= MEDIA_ATTR_MAX) &&
                                        (attrs[attIndex] >= MEDIA_ATTR_MIN)) {
                                attValues[(7 * index) + attIndex] =
                                    getAttributeStringFromCursor(cursor, attrs[attIndex]);
                                attIds[(7 * index) + attIndex] = attrs[attIndex];
                                validAttrib ++;
                            }
                        }
                        numAtt[index] = (byte)validAttrib;
                        cursor.moveToNext();
                    }
                    numItems = index;
@@ -2512,7 +2529,7 @@ public final class Avrcp {
                    }
                } else {
                    long folderUid = Long.valueOf(mCurrentPathUid);
                    int availableItems = 0;
                    long availableItems = 0;
                    Cursor cursor = null;
                    try {
                        cursor = mContext.getContentResolver().query(
@@ -2561,12 +2578,17 @@ public final class Avrcp {
                            displayName[index] =
                                cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.
                                                                        Audio.Media.TITLE));                            
                            numAtt[index] = numAttr;
                            int validAttrib = 0;
                            for (attIndex = 0; attIndex < numAttr; attIndex++) {
                                attValues[(7 * index) + attIndex] = getAttributeStringFromCursor(
                                                                            cursor, attrs[attIndex]);
                                if ((attrs[attIndex] <= MEDIA_ATTR_MAX) &&
                                            (attrs[attIndex] >= MEDIA_ATTR_MIN)) {
                                    attValues[(7 * index) + attIndex] =
                                        getAttributeStringFromCursor(cursor, attrs[attIndex]);
                                    attIds[(7 * index) + attIndex] = attrs[attIndex];
                                    validAttrib ++;
                                }
                            }
                            numAtt[index] = (byte)validAttrib;
                            cursor.moveToNext();
                        }
                        numItems = index;
@@ -2668,7 +2690,7 @@ public final class Avrcp {
                    }
                } else {
                    long folderUid = Long.valueOf(mCurrentPathUid);
                    int availableItems = 0;
                    long availableItems = 0;
                    Cursor cursor = null;
                    try {
                        cursor = mContext.getContentResolver().query(
@@ -2716,12 +2738,17 @@ public final class Avrcp {
                            displayName[index] =
                                cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.
                                                                        Audio.Media.TITLE));
                            numAtt[index] = numAttr;
                            int validAttrib = 0;
                            for (attIndex = 0; attIndex < numAttr; attIndex++) {
                                attValues[(7 * index) + attIndex] = getAttributeStringFromCursor(
                                                                        cursor, attrs[attIndex]);
                                if ((attrs[attIndex] <= MEDIA_ATTR_MAX) &&
                                            (attrs[attIndex] >= MEDIA_ATTR_MIN)) {
                                    attValues[(7 * index) + attIndex] =
                                        getAttributeStringFromCursor(cursor, attrs[attIndex]);
                                    attIds[(7 * index) + attIndex] = attrs[attIndex];
                                    validAttrib ++;
                                }
                            }
                            numAtt[index] = (byte)validAttrib;
                            cursor.moveToNext();
                        }
                        numItems = index;
@@ -2817,7 +2844,7 @@ public final class Avrcp {
                    }
                } else {
                    long folderUid = Long.valueOf(mCurrentPathUid);
                    int availableItems = 0;
                    long availableItems = 0;
                    Cursor cursor = null;

                    String[] playlistMemberCols = new String[] {
@@ -2881,12 +2908,17 @@ public final class Avrcp {
                            displayName[index] =
                                cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.
                                                                        Audio.Media.TITLE));
                            numAtt[index] = numAttr;
                            int validAttrib = 0;
                            for (attIndex = 0; attIndex < numAttr; attIndex++) {
                                attValues[(7 * index) + attIndex] = getAttributeStringFromCursor(
                                                                        cursor, attrs[attIndex]);
                                if ((attrs[attIndex] <= MEDIA_ATTR_MAX) &&
                                            (attrs[attIndex] >= MEDIA_ATTR_MIN)) {
                                    attValues[(7 * index) + attIndex] =
                                        getAttributeStringFromCursor(cursor, attrs[attIndex]);
                                    attIds[(7 * index) + attIndex] = attrs[attIndex];
                                    validAttrib ++;
                                }
                            }
                            numAtt[index] = (byte)validAttrib;
                            cursor.moveToNext();
                        }
                        numItems = index;
@@ -3130,7 +3162,7 @@ public final class Avrcp {
    }

    private String getAttributeStringFromCursor(Cursor cursor, int attrId) {
        String attrStr = null;
        String attrStr = "<unknown>";
        switch (attrId) {
            case MEDIA_ATTR_TITLE:
                attrStr = cursor.getString(cursor.getColumnIndexOrThrow(
@@ -3471,6 +3503,7 @@ private void updateLocalPlayerSettings( byte[] data) {
    final static short PLAYSTATUS_ERROR = 255;

    // match up with btrc_media_attr_t enum of bt_rc.h
    final static int MEDIA_ATTR_MIN = 1;
    final static int MEDIA_ATTR_TITLE = 1;
    final static int MEDIA_ATTR_ARTIST = 2;
    final static int MEDIA_ATTR_ALBUM = 3;
@@ -3478,6 +3511,7 @@ private void updateLocalPlayerSettings( byte[] data) {
    final static int MEDIA_ATTR_NUM_TRACKS = 5;
    final static int MEDIA_ATTR_GENRE = 6;
    final static int MEDIA_ATTR_PLAYING_TIME = 7;
    final static int MEDIA_ATTR_MAX = 7;

    // match up with btrc_event_id_t enum of bt_rc.h
    final static int EVT_PLAY_STATUS_CHANGED = 1;
@@ -3817,7 +3851,7 @@ private void updateLocalPlayerSettings( byte[] data) {
    private native boolean setAdressedPlayerRspNative(byte statusCode);
    private native boolean getMediaPlayerListRspNative(byte statusCode, int uidCounter,
                                    int itemCount, byte[] folderItems, int[] folderItemLengths);
    private native boolean getFolderItemsRspNative(byte statusCode, int numItems,
    private native boolean getFolderItemsRspNative(byte statusCode, long numItems,
        int[] itemType, long[] uid, int[] type, byte[] playable, String[] displayName,
        byte[] numAtt, String[] attValues, int[] attIds);
    private native boolean getListPlayerappAttrRspNative(byte attr, byte[] attrIds);