From c1db133f088845dbf3d3abf1c747d723f554e8d2 Mon Sep 17 00:00:00 2001 From: Ayan Ghosh Date: Sun, 9 Nov 2014 14:48:25 +0530 Subject: 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 --- src/com/android/bluetooth/avrcp/Avrcp.java | 132 ++++++++++++++++++----------- 1 file changed, 83 insertions(+), 49 deletions(-) (limited to 'src/com/android') diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java index 98f6ca537..e7cd00885 100644 --- a/src/com/android/bluetooth/avrcp/Avrcp.java +++ b/src/com/android/bluetooth/avrcp/Avrcp.java @@ -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]; @@ -1283,7 +1283,7 @@ public final class Avrcp { return; } - if ((mCachedRequest.mStart < 0) || (mCachedRequest.mEnd< 0) || + if ((mCachedRequest.mStart < 0) || (mCachedRequest.mEnd < 0) || (mCachedRequest.mStart > mCachedRequest.mEnd)) { Log.i(TAG, "wrong start / end index"); getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, @@ -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); - attIds[(7 * index) + attIndex] = 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 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 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) { - textArray[i] = getAttributeStringFromCursor(cursor, attrs[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]); - attIds[(7 * index) + attIndex] = 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( @@ -2560,13 +2577,18 @@ public final class Avrcp { playable[index] = 0; displayName[index] = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore. - Audio.Media.TITLE)); - numAtt[index] = numAttr; + Audio.Media.TITLE)); + int validAttrib = 0; for (attIndex = 0; attIndex < numAttr; attIndex++) { - attValues[(7 * index) + attIndex] = getAttributeStringFromCursor( - cursor, attrs[attIndex]); - attIds[(7 * index) + attIndex] = 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]); - attIds[(7 * index) + attIndex] = 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]); - attIds[(7 * index) + attIndex] = 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 = ""; 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); -- cgit v1.2.3