summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAyan Ghosh <abghosh@codeaurora.org>2014-11-09 14:48:25 +0530
committerrakesh reddy <ramare@codeaurora.org>2014-11-12 17:19:39 +0530
commitc1db133f088845dbf3d3abf1c747d723f554e8d2 (patch)
treedfd2027082ac1ced956bb277e84b961b9f9442c2
parent637282364053a9477490cb0732532ea806504768 (diff)
downloadandroid_packages_apps_Bluetooth-c1db133f088845dbf3d3abf1c747d723f554e8d2.tar.gz
android_packages_apps_Bluetooth-c1db133f088845dbf3d3abf1c747d723f554e8d2.tar.bz2
android_packages_apps_Bluetooth-c1db133f088845dbf3d3abf1c747d723f554e8d2.zip
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
-rw-r--r--jni/com_android_bluetooth_avrcp.cpp22
-rw-r--r--src/com/android/bluetooth/avrcp/Avrcp.java132
2 files changed, 100 insertions, 54 deletions
diff --git a/jni/com_android_bluetooth_avrcp.cpp b/jni/com_android_bluetooth_avrcp.cpp
index eaed3bd5d..a8ff2c986 100644
--- a/jni/com_android_bluetooth_avrcp.cpp
+++ b/jni/com_android_bluetooth_avrcp.cpp
@@ -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},
};
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<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) {
- 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 = "<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);