diff options
Diffstat (limited to 'src/com/android/bluetooth/avrcp/Avrcp.java')
-rw-r--r-- | src/com/android/bluetooth/avrcp/Avrcp.java | 365 |
1 files changed, 247 insertions, 118 deletions
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java index 095f0ed6c..3b7a4bfc6 100644 --- a/src/com/android/bluetooth/avrcp/Avrcp.java +++ b/src/com/android/bluetooth/avrcp/Avrcp.java @@ -310,6 +310,7 @@ public final class Avrcp { private final String UPDATE_ATTRIB_TEXT = "UpdateAttributesText"; private final String UPDATE_VALUE_TEXT = "UpdateValuesText"; private ArrayList <Integer> mPendingCmds; + private ArrayList <Integer> mPendingSetAttributes; static { classInitNative(); @@ -359,6 +360,7 @@ public final class Avrcp { Looper looper = thread.getLooper(); mHandler = new AvrcpMessageHandler(looper); mPendingCmds = new ArrayList<Integer>(); + mPendingSetAttributes = new ArrayList<Integer>(); mCurrentPath = PATH_INVALID; mCurrentPathUid = null; mMediaUri = Uri.EMPTY; @@ -402,14 +404,19 @@ public final class Avrcp { GET_INVALID); byte [] data; String [] text; + boolean isSetAttrValRsp = false; synchronized (mPendingCmds) { Integer val = new Integer(getResponse); if (mPendingCmds.contains(val)) { + if (getResponse == SET_ATTRIBUTE_VALUES) { + isSetAttrValRsp = true; + if (DEBUG) Log.v(TAG,"Response received for SET_ATTRIBUTE_VALUES"); + } mHandler.removeMessages(MESSAGE_PLAYERSETTINGS_TIMEOUT); mPendingCmds.remove(val); } } - if (DEBUG) Log.v(TAG,"getResponse" + getResponse); + if (DEBUG) Log.v(TAG,"getResponse " + getResponse); switch (getResponse) { case GET_ATTRIBUTE_IDS: data = intent.getByteArrayExtra(EXTRA_ATTIBUTE_ID_ARRAY); @@ -420,35 +427,34 @@ public final class Avrcp { case GET_VALUE_IDS: data = intent.getByteArrayExtra(EXTRA_VALUE_ID_ARRAY); numAttr = (byte) data.length; - if (DEBUG) Log.v(TAG,"GET_VALUE_IDS" + numAttr); + if (DEBUG) Log.v(TAG,"GET_VALUE_IDS " + numAttr); getPlayerAppValueRspNative(numAttr, data); break; case GET_ATTRIBUTE_VALUES: data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS); updateLocalPlayerSettings(data); numAttr = (byte) data.length; - if (DEBUG) Log.v(TAG,"GET_ATTRIBUTE_VALUES" + numAttr); + if (DEBUG) Log.v(TAG,"GET_ATTRIBUTE_VALUES " + numAttr); SendCurrentPlayerValueRspNative(numAttr, data); break; case SET_ATTRIBUTE_VALUES: data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS); updateLocalPlayerSettings(data); - Log.v(TAG,"SET_ATTRIBUTE_VALUES: " + data[0] + ", " + data[1]); - if (data[0] == ATTRIBUTE_EQUALIZER || - data[0] == ATTRIBUTE_REPEATMODE || - data[0] == ATTRIBUTE_SHUFFLEMODE) { - if (mPlayerStatusChangeNT == NOTIFICATION_TYPE_INTERIM) { - Log.v(TAG,"Send Player appl attribute changed response"); - mPlayerStatusChangeNT = NOTIFICATION_TYPE_CHANGED; - sendPlayerAppChangedRsp(mPlayerStatusChangeNT); + Log.v(TAG,"SET_ATTRIBUTE_VALUES: "); + if (isSetAttrValRsp){ + isSetAttrValRsp = false; + Log.v(TAG,"Respond to SET_ATTRIBUTE_VALUES request"); + if (checkPlayerAttributeResponse(data)) { + SendSetPlayerAppRspNative(OPERATION_SUCCESSFUL); } else { - Log.v(TAG,"Respond to SET_ATTRIBUTE_VALUES request"); - if (data[1] == ATTRIBUTE_NOTSUPPORTED) { - SendSetPlayerAppRspNative(INTERNAL_ERROR); - } else { - SendSetPlayerAppRspNative(OPERATION_SUCCESSFUL); - } + SendSetPlayerAppRspNative(INTERNAL_ERROR); } + } else if (mPlayerStatusChangeNT == NOTIFICATION_TYPE_INTERIM) { + Log.v(TAG,"Send Player appl attribute changed response"); + mPlayerStatusChangeNT = NOTIFICATION_TYPE_CHANGED; + sendPlayerAppChangedRsp(mPlayerStatusChangeNT); + } else { + Log.v(TAG,"Drop Set Attr Val update from media player"); } break; case GET_ATTRIBUTE_TEXT: @@ -1259,8 +1265,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]; @@ -1288,7 +1294,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, @@ -1297,18 +1303,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")); @@ -1316,20 +1327,25 @@ 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 ++; + } } - cursor.close(); + numAtt[index] = (byte)validAttrib; } } catch(Exception e) { - Log.i(TAG, "Exception e"+ e); - cursor.close(); + Log.i(TAG, "Exception "+ e); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } numItems = index; @@ -1338,11 +1354,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; @@ -1355,12 +1371,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; @@ -1418,11 +1434,16 @@ public final class Avrcp { final MediaPlayerInfo di = rccIterator.next(); if (di.GetPlayerFocus()) { if (DEBUG) Log.v(TAG, "resetting current MetaData"); - mMetadata = di.GetMetadata(); + mMetadata.artist = di.GetMetadata().artist; + mMetadata.trackTitle = di.GetMetadata().trackTitle; + mMetadata.albumTitle = di.GetMetadata().albumTitle; + mMetadata.genre = di.GetMetadata().genre; + mMetadata.tracknum = di.GetMetadata().tracknum; break; } } } + String oldMetadata = mMetadata.toString(); mMetadata.artist = data.getString(MediaMetadataRetriever.METADATA_KEY_ARTIST, null); mMetadata.trackTitle = data.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, null); @@ -1431,7 +1452,8 @@ public final class Avrcp { mTrackNumber = data.getLong(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, -1L); mMetadata.tracknum = data.getLong(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, -1L); - Log.v(TAG,"mMetadata.toString() = " + mMetadata.toString()); + Log.v(TAG,"old Metadata = " + oldMetadata); + Log.v(TAG,"new MetaData " + mMetadata.toString()); if (mMediaPlayers.size() > 0) { final Iterator<MediaPlayerInfo> rccIterator = mMediaPlayers.iterator(); @@ -1444,6 +1466,7 @@ public final class Avrcp { } } } + if (!oldMetadata.equals(mMetadata.toString())) { updateTrackNumber(); Log.v(TAG,"new mMetadata, mTrackNumber update to " + mTrackNumber); @@ -1622,11 +1645,13 @@ public final class Avrcp { status = NOT_A_DIRECTORY; else status = DOES_NOT_EXIST; - cursor.close(); } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } break; default: @@ -1661,12 +1686,14 @@ public final class Avrcp { } else{ numberOfItems = cursor.getCount(); mCurrentPathUid = String.valueOf(folderUid); - cursor.close(); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { // Path @ Individual Album id Cursor cursor = null; @@ -1682,11 +1709,13 @@ public final class Avrcp { status = NOT_A_DIRECTORY; else status = DOES_NOT_EXIST; - cursor.close(); } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } } break; @@ -1723,12 +1752,14 @@ public final class Avrcp { numberOfItems = cursor.getCount(); mCurrentPathUid = String.valueOf(folderUid); mCurrentPath = PATH_ARTISTS; - cursor.close(); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { Cursor cursor = null; @@ -1742,11 +1773,13 @@ public final class Avrcp { status = NOT_A_DIRECTORY; else status = DOES_NOT_EXIST; - cursor.close(); } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } } break; @@ -1789,12 +1822,14 @@ public final class Avrcp { numberOfItems = cursor.getCount(); mCurrentPathUid = String.valueOf(folderUid); mCurrentPath = PATH_PLAYLISTS; - cursor.close(); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); changePathRspNative(INTERNAL_ERROR, numberOfItems); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { numberOfItems = 0; @@ -1829,13 +1864,15 @@ public final class Avrcp { return 0; } else { long count = cursor.getCount(); - cursor.close(); return count; } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); return 0; + } finally { + if (cursor != null) { + cursor.close(); + } } } @@ -1853,7 +1890,6 @@ public final class Avrcp { return 0; } else if (path.equals(PATH_TITLES)) { long count = cursor.getCount(); - cursor.close(); return count; } else if (path.equals(PATH_ALBUMS) || path.equals(PATH_ARTISTS)){ long elemCount = 0; @@ -1872,12 +1908,14 @@ public final class Avrcp { count--; } Log.i(TAG, "element Count is "+ elemCount); - cursor.close(); return elemCount; } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); + } finally { + if (cursor != null) { + cursor.close(); + } } return 0; } @@ -1924,13 +1962,15 @@ public final class Avrcp { playItemRspNative(DOES_NOT_EXIST); } else { Log.i(TAG, "Play uid:" + uid); - cursor.close(); mRemoteController.setRemoteControlClientPlayItem(uid, scope); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); playItemRspNative(INTERNAL_ERROR); + } finally { + if (cursor != null) { + cursor.close(); + } } } else if (mCurrentPath.equals(PATH_ALBUMS)) { if (mCurrentPathUid == null) { @@ -1949,13 +1989,15 @@ public final class Avrcp { playItemRspNative(DOES_NOT_EXIST); } else { Log.i(TAG, "Play uid:" + uid); - cursor.close(); mRemoteController.setRemoteControlClientPlayItem(uid, scope); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); playItemRspNative(INTERNAL_ERROR); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else if (mCurrentPath.equals(PATH_ARTISTS)) { @@ -1975,13 +2017,15 @@ public final class Avrcp { playItemRspNative(DOES_NOT_EXIST); } else { Log.i(TAG, "Play uid:" + uid); - cursor.close(); mRemoteController.setRemoteControlClientPlayItem(uid, scope); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); playItemRspNative(INTERNAL_ERROR); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else if (mCurrentPath.equals(PATH_PLAYLISTS)) { @@ -2014,13 +2058,15 @@ public final class Avrcp { playItemRspNative(DOES_NOT_EXIST); } else { Log.i(TAG, "Play uid:" + uid); - cursor.close(); mRemoteController.setRemoteControlClientPlayItem(uid, scope); } } catch (Exception e) { Log.e(TAG, "Exception " + e); - cursor.close(); playItemRspNative(INTERNAL_ERROR); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else { @@ -2083,16 +2129,23 @@ 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); - cursor.close(); + getItemAttrRspNative((byte)validAttrib, attrs, textArray); } } catch (Exception e) { - Log.e(TAG, "Exception " + e); cursor.close(); + Log.e(TAG, "Exception " + e); getItemAttrRspNative((byte)0, attrs, textArray); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { Log.i(TAG, "Invalid scope"); @@ -2153,7 +2206,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); @@ -2168,7 +2221,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); @@ -2183,7 +2236,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]; @@ -2223,12 +2276,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]; @@ -2269,7 +2322,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, @@ -2288,8 +2341,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; @@ -2336,7 +2389,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( @@ -2350,7 +2403,6 @@ public final class Avrcp { getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); return; } cursor.moveToFirst(); @@ -2382,23 +2434,30 @@ 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; getFolderItemsRspNative((byte)OPERATION_SUCCESSFUL, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } else if (mCurrentPath.equals(PATH_ALBUMS)) { if (mCurrentPathUid == null) { @@ -2477,16 +2536,18 @@ public final class Avrcp { itemType, uid, type, playable, displayName, numAtt, attValues, attIds); } - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { long folderUid = Long.valueOf(mCurrentPathUid); - int availableItems = 0; + long availableItems = 0; Cursor cursor = null; try { cursor = mContext.getContentResolver().query( @@ -2502,7 +2563,6 @@ public final class Avrcp { getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); return; } cursor.moveToFirst(); @@ -2535,24 +2595,31 @@ 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; getFolderItemsRspNative((byte)OPERATION_SUCCESSFUL, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else if (mCurrentPath.equals(PATH_ARTISTS)) { @@ -2630,16 +2697,18 @@ public final class Avrcp { getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); } - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { long folderUid = Long.valueOf(mCurrentPathUid); - int availableItems = 0; + long availableItems = 0; Cursor cursor = null; try { cursor = mContext.getContentResolver().query( @@ -2655,7 +2724,6 @@ public final class Avrcp { getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); return; } cursor.moveToFirst(); @@ -2688,23 +2756,30 @@ 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; getFolderItemsRspNative((byte)OPERATION_SUCCESSFUL, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else if (mCurrentPath.equals(PATH_PLAYLISTS)) { @@ -2776,16 +2851,18 @@ public final class Avrcp { itemType, uid, type, playable, displayName, numAtt, attValues, attIds); } - cursor.close(); } catch(Exception e) { Log.i(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } else { long folderUid = Long.valueOf(mCurrentPathUid); - int availableItems = 0; + long availableItems = 0; Cursor cursor = null; String[] playlistMemberCols = new String[] { @@ -2816,7 +2893,6 @@ public final class Avrcp { getFolderItemsRspNative((byte)RANGE_OUT_OF_BOUNDS, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); return; } cursor.moveToFirst(); @@ -2850,23 +2926,30 @@ 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; getFolderItemsRspNative((byte)OPERATION_SUCCESSFUL, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); - cursor.close(); } catch(Exception e) { Log.e(TAG, "Exception e" + e); - cursor.close(); getFolderItemsRspNative((byte)INTERNAL_ERROR, numItems, itemType, uid, type, playable, displayName, numAtt, attValues, attIds); + } finally { + if (cursor != null) { + cursor.close(); + } } } } else { @@ -3097,7 +3180,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( @@ -3285,8 +3368,10 @@ public final class Avrcp { return (int) Math.ceil((double) volume*AVRCP_MAX_VOL/mAudioStreamMax); } -private void updateLocalPlayerSettings( byte[] data) { + private void updateLocalPlayerSettings( byte[] data) { + if (DEBUG) Log.v(TAG, "updateLocalPlayerSettings"); for (int i = 0; i < data.length; i += 2) { + if (DEBUG) Log.v(TAG, "ID: " + data[i] + " Value: " + data[i+1]); switch (data[i]) { case ATTRIBUTE_EQUALIZER: settingValues.eq_value = data[i+1]; @@ -3304,6 +3389,45 @@ private void updateLocalPlayerSettings( byte[] data) { } } + private boolean checkPlayerAttributeResponse( byte[] data) { + boolean ret = false; + if (DEBUG) Log.v(TAG, "checkPlayerAttributeResponse"); + for (int i = 0; i < data.length; i += 2) { + if (DEBUG) Log.v(TAG, "ID: " + data[i] + " Value: " + data[i+1]); + switch (data[i]) { + case ATTRIBUTE_EQUALIZER: + if (mPendingSetAttributes.contains(new Integer(ATTRIBUTE_EQUALIZER))) { + if(data[i+1] == ATTRIBUTE_NOTSUPPORTED) { + ret = false; + } else { + ret = true; + } + } + break; + case ATTRIBUTE_REPEATMODE: + if (mPendingSetAttributes.contains(new Integer(ATTRIBUTE_REPEATMODE))) { + if(data[i+1] == ATTRIBUTE_NOTSUPPORTED) { + ret = false; + } else { + ret = true; + } + } + break; + case ATTRIBUTE_SHUFFLEMODE: + if (mPendingSetAttributes.contains(new Integer(ATTRIBUTE_SHUFFLEMODE))) { + if(data[i+1] == ATTRIBUTE_NOTSUPPORTED) { + ret = false; + } else { + ret = true; + } + } + break; + } + } + mPendingSetAttributes.clear(); + return ret; + } + //PDU ID 0x11 private void onListPlayerAttributeRequest() { if (DEBUG) Log.v(TAG, "onListPlayerAttributeRequest"); @@ -3360,12 +3484,13 @@ private void updateLocalPlayerSettings( byte[] data) { //PDU 0x14 private void setPlayerAppSetting( byte num , byte [] attr_id , byte [] attr_val ) { - if (DEBUG) Log.v(TAG, "setPlayerAppSetting" + num ); + if (DEBUG) Log.v(TAG, "setPlayerAppSetting " + num ); byte[] array = new byte[num*2]; for ( int i = 0; i < num; i++) { array[i] = attr_id[i] ; array[i+1] = attr_val[i]; + mPendingSetAttributes.add(new Integer(attr_id[i])); } Intent intent = new Intent(PLAYERSETTINGS_REQUEST); intent.putExtra(COMMAND, CMDSET); @@ -3375,7 +3500,7 @@ private void updateLocalPlayerSettings( byte[] data) { msg.what = MESSAGE_PLAYERSETTINGS_TIMEOUT; msg.arg1 = SET_ATTRIBUTE_VALUES; mPendingCmds.add(new Integer(msg.arg1)); - mHandler.sendMessageDelayed(msg, 130); + mHandler.sendMessageDelayed(msg, 500); } //PDU 0x15 @@ -3438,6 +3563,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; @@ -3445,6 +3571,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; @@ -3784,7 +3911,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); @@ -3894,6 +4021,8 @@ private void updateLocalPlayerSettings( byte[] data) { mMetadata.albumTitle = metaData.albumTitle; mMetadata.artist = metaData.artist; mMetadata.trackTitle = metaData.trackTitle; + mMetadata.genre = metaData.genre; + mMetadata.tracknum = metaData.tracknum; } public byte GetPlayState() { return mPlayState; |