diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0c71e21..c3ee7e4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -316,7 +316,7 @@
         </service>
         <service
             android:process="@string/process"
-            android:name = ".avrcp.AvrcpControllerService"
+            android:name = ".avrcpcontroller.AvrcpControllerService"
             android:enabled="@bool/profile_supported_avrcp_controller">
             <intent-filter>
                 <action android:name="android.bluetooth.IBluetoothAvrcpController" />
diff --git a/jni/com_android_bluetooth_avrcp_controller.cpp b/jni/com_android_bluetooth_avrcp_controller.cpp
index c28b15a..457b771 100644
--- a/jni/com_android_bluetooth_avrcp_controller.cpp
+++ b/jni/com_android_bluetooth_avrcp_controller.cpp
@@ -37,12 +37,22 @@
 static jmethodID method_handletrackchanged;
 static jmethodID method_handleplaypositionchanged;
 static jmethodID method_handleplaystatuschanged;
+static jmethodID method_handleGetFolderItemsRsp;
+static jmethodID method_handleGetPlayerItemsRsp;
 static jmethodID method_handleGroupNavigationRsp;
+static jmethodID method_createFromNativeMediaItem;
+static jmethodID method_createFromNativeFolderItem;
+static jmethodID method_createFromNativePlayerItem;
+static jmethodID method_handleChangeFolderRsp;
+static jmethodID method_handleSetBrowsedPlayerRsp;
 
+static jclass class_MediaBrowser_MediaItem;
+static jclass class_AvrcpPlayer;
 
 static const btrc_ctrl_interface_t *sBluetoothAvrcpInterface = NULL;
-static jobject mCallbacksObj = NULL;
+static jobject sCallbacksObj = NULL;
 static JNIEnv *sCallbackEnv = NULL;
+static JNIEnv *sEnv = NULL;
 
 static bool checkCallbackThread() {
     // Always fetch the latest callbackEnv from AdapterService.
@@ -56,7 +66,7 @@
     return true;
 }
 
-static void btavrcp_passthrough_response_callback(int id, int pressed, bt_bdaddr_t* bd_addr) {
+static void btavrcp_passthrough_response_callback(bt_bdaddr_t* bd_addr, int id, int pressed)  {
     jbyteArray addr;
 
     ALOGI("%s", __func__);
@@ -75,7 +85,7 @@
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
 
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughRsp, (jint)id,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handlePassthroughRsp, (jint)id,
                                                                              (jint)pressed,
                                                                              addr);
     checkAndClearExceptionFromCallback(sCallbackEnv, __func__);
@@ -84,23 +94,24 @@
 }
 
 static void btavrcp_groupnavigation_response_callback(int id, int pressed) {
-    ALOGI("%s", __FUNCTION__);
+    ALOGV("%s", __FUNCTION__);
 
     if (!checkCallbackThread()) {
         ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
         return;
     }
 
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleGroupNavigationRsp, (jint)id,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGroupNavigationRsp, (jint)id,
                                                                              (jint)pressed);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
-static void btavrcp_connection_state_callback(bool state, bt_bdaddr_t* bd_addr) {
+static void btavrcp_connection_state_callback(
+        bool rc_connect, bool br_connect, bt_bdaddr_t* bd_addr) {
     jbyteArray addr;
 
-    ALOGI("%s", __FUNCTION__);
-    ALOGI("conn state: %d", state);
+    ALOGV("%s", __FUNCTION__);
+    ALOGI("%s conn state rc: %d br: %d", __FUNCTION__, rc_connect, br_connect);
 
     if (!checkCallbackThread()) {                                       \
         ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
@@ -115,8 +126,8 @@
     }
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, (jboolean) state,
-                                 addr);
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_onConnectionStateChanged,
+                                 (jboolean) rc_connect, (jboolean) br_connect, addr);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
 }
@@ -124,7 +135,7 @@
 static void btavrcp_get_rcfeatures_callback(bt_bdaddr_t *bd_addr, int features) {
     jbyteArray addr;
 
-    ALOGI("%s", __FUNCTION__);
+    ALOGV("%s", __FUNCTION__);
 
     if (!checkCallbackThread()) {                                       \
         ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
@@ -139,7 +150,7 @@
     }
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features);
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcFeatures, addr, (jint)features);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
 }
@@ -148,7 +159,7 @@
                                                                     uint8_t accepted) {
     jbyteArray addr;
 
-    ALOGI("%s", __FUNCTION__);
+    ALOGV("%s", __FUNCTION__);
 
     if (!checkCallbackThread()) {                                       \
         ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); \
@@ -163,7 +174,7 @@
     }
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_setplayerappsettingrsp, addr, (jint)accepted);
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_setplayerappsettingrsp, addr, (jint)accepted);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
 }
@@ -171,7 +182,7 @@
 static void btavrcp_playerapplicationsetting_callback(bt_bdaddr_t *bd_addr, uint8_t num_attr,
         btrc_player_app_attr_t *app_attrs, uint8_t num_ext_attr,
         btrc_player_app_ext_attr_t *ext_attrs) {
-    ALOGI("%s", __FUNCTION__);
+    ALOGV("%s", __FUNCTION__);
     jbyteArray addr;
     jbyteArray playerattribs;
     jint arraylen;
@@ -198,7 +209,7 @@
         /*2 bytes for id and num */
         arraylen += 2 + app_attrs[i].num_val;
     }
-    ALOGI(" arraylen %d", arraylen);
+    ALOGV(" arraylen %d", arraylen);
     playerattribs = sCallbackEnv->NewByteArray(arraylen);
     if(!playerattribs)
     {
@@ -218,7 +229,7 @@
                 (jbyte*)(app_attrs[i].attr_val));
         k = k + app_attrs[i].num_val;
     }
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleplayerappsetting, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsetting, addr,
             playerattribs, (jint)arraylen);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
@@ -265,7 +276,7 @@
         sCallbackEnv->SetByteArrayRegion(playerattribs, k, 1, (jbyte*)&(p_vals->attr_values[i]));
         k++;
     }
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleplayerappsettingchanged, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsettingchanged, addr,
             playerattribs, (jint)arraylen);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
@@ -291,7 +302,7 @@
     }
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleSetAbsVolume, addr, (jbyte)abs_vol,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetAbsVolume, addr, (jbyte)abs_vol,
                                  (jbyte)label);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
@@ -315,7 +326,7 @@
     }
 
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleRegisterNotificationAbsVol, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleRegisterNotificationAbsVol, addr,
                                  (jbyte)label);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
@@ -379,7 +390,7 @@
         sCallbackEnv->DeleteLocalRef(str);
     }
 
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handletrackchanged, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handletrackchanged, addr,
          (jbyte)(num_attr), attribIds, stringArray);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
     sCallbackEnv->DeleteLocalRef(addr);
@@ -402,7 +413,7 @@
         return;
     }
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleplaypositionchanged, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaypositionchanged, addr,
          (jint)(song_len), (jint)song_pos);
     sCallbackEnv->DeleteLocalRef(addr);
 }
@@ -419,11 +430,196 @@
         return;
     }
     sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
-    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handleplaystatuschanged, addr,
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaystatuschanged, addr,
              (jbyte)play_status);
     sCallbackEnv->DeleteLocalRef(addr);
 }
 
+static void btavrcp_get_folder_items_callback(bt_bdaddr_t *bd_addr,
+        const btrc_folder_items_t *folder_items, uint8_t count) {
+    /* Folder items are list of items that can be either BTRC_ITEM_PLAYER
+     * BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java
+     * counterparts by calling the java constructor for each of the items.
+     */
+    ALOGV("%s count %d", __FUNCTION__, count);
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+
+    // Inspect if the first element is a folder/item or player listing. They are
+    // always exclusive.
+    bool isPlayerListing = count > 0 && (folder_items[0].item_type == BTRC_ITEM_PLAYER);
+
+    // Initialize arrays for Folder OR Player listing.
+    jobjectArray playerItemArray = NULL;
+    jobjectArray folderItemArray = NULL;
+    if (isPlayerListing) {
+        playerItemArray = sCallbackEnv->NewObjectArray((jint) count, class_AvrcpPlayer, 0);
+        if (!playerItemArray) {
+            ALOGE("%s playerItemArray allocation failed.", __FUNCTION__);
+            checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+            return;
+        }
+    } else {
+        folderItemArray = sCallbackEnv->NewObjectArray(
+            (jint) count, class_MediaBrowser_MediaItem, 0);
+        if (!folderItemArray) {
+            ALOGE("%s folderItemArray is empty.", __FUNCTION__);
+            checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+            return;
+        }
+    }
+
+    for (int i = 0; i < count; i++) {
+        const btrc_folder_items_t *item = &(folder_items[i]);
+        ALOGV("%s item type %d", __FUNCTION__, item->item_type);
+        switch (item->item_type) {
+            case BTRC_ITEM_MEDIA:
+            {
+                // Parse name
+                jstring mediaName = sCallbackEnv->NewStringUTF((const char *) item->media.name);
+                // Parse UID
+                jbyteArray uidByteArray = sCallbackEnv->NewByteArray(
+                    sizeof(uint8_t) * BTRC_UID_SIZE);
+                sCallbackEnv->SetByteArrayRegion(
+                    uidByteArray, 0, BTRC_UID_SIZE * sizeof (uint8_t), (jbyte *) item->media.uid);
+
+                // Parse Attrs
+                jintArray attrIdArray = sCallbackEnv->NewIntArray(item->media.num_attrs);
+                jobjectArray attrValArray = sCallbackEnv->NewObjectArray(
+                      item->media.num_attrs,
+                      sCallbackEnv->FindClass("java/lang/String"),
+                      0);
+
+                for (int j = 0; j < item->media.num_attrs; j++) {
+                    sCallbackEnv->SetIntArrayRegion(
+                        attrIdArray, j, 1, (jint *)&(item->media.p_attrs[j].attr_id));
+                    jstring attrValStr = sCallbackEnv->NewStringUTF(
+                        (char *)(item->media.p_attrs[j].text));
+                    sCallbackEnv->SetObjectArrayElement(
+                        attrValArray, j, attrValStr);
+                    sCallbackEnv->DeleteLocalRef(attrValStr);
+                }
+
+                jobject mediaObj = (jobject) sCallbackEnv->CallObjectMethod(
+                    sCallbacksObj, method_createFromNativeMediaItem, uidByteArray,
+                    (jint) item->media.type, mediaName, attrIdArray, attrValArray);
+                sCallbackEnv->DeleteLocalRef(uidByteArray);
+                sCallbackEnv->DeleteLocalRef(mediaName);
+                sCallbackEnv->DeleteLocalRef(attrIdArray);
+                sCallbackEnv->DeleteLocalRef(attrValArray);
+
+                if (!mediaObj) {
+                    ALOGE("%s failed to create MediaItem for type ITEM_MEDIA", __FUNCTION__);
+                    return;
+                }
+                sCallbackEnv->SetObjectArrayElement(folderItemArray, i, mediaObj);
+                sCallbackEnv->DeleteLocalRef(mediaObj);
+                break;
+            }
+
+            case BTRC_ITEM_FOLDER:
+            {
+                // Parse name
+                jstring folderName = sCallbackEnv->NewStringUTF((const char *) item->folder.name);
+                // Parse UID
+                jbyteArray uidByteArray = sCallbackEnv->NewByteArray(
+                    sizeof(uint8_t) * BTRC_UID_SIZE);
+                sCallbackEnv->SetByteArrayRegion(
+                    uidByteArray, 0, BTRC_UID_SIZE * sizeof (uint8_t), (jbyte *) item->folder.uid);
+
+                jobject folderObj = (jobject) sCallbackEnv->CallObjectMethod(
+                    sCallbacksObj, method_createFromNativeFolderItem, uidByteArray,
+                    (jint) item->folder.type, folderName, (jint) item->folder.playable);
+                sCallbackEnv->DeleteLocalRef(uidByteArray);
+                sCallbackEnv->DeleteLocalRef(folderName);
+
+                if (!folderObj) {
+                    ALOGE("%s failed to create MediaItem for type ITEM_MEDIA", __FUNCTION__);
+                    return;
+                }
+                sCallbackEnv->SetObjectArrayElement(folderItemArray, i, folderObj);
+                sCallbackEnv->DeleteLocalRef(folderObj);
+                break;
+            }
+
+            case BTRC_ITEM_PLAYER:
+            {
+                // Parse name
+                isPlayerListing = true;
+                jint id = (jint) item->player.player_id;
+                jint playerType = (jint) item->player.major_type;
+                jint playStatus = (jint) item->player.play_status;
+                jbyteArray featureBitArray = sCallbackEnv->NewByteArray(
+                    BTRC_FEATURE_BIT_MASK_SIZE * sizeof (uint8_t));
+                if (!featureBitArray) {
+                    ALOGE("%s failed to allocate featureBitArray", __FUNCTION__);
+                    sCallbackEnv->DeleteLocalRef(playerItemArray);
+                    sCallbackEnv->DeleteLocalRef(folderItemArray);
+                    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+                    return;
+                }
+                sCallbackEnv->SetByteArrayRegion(
+                    featureBitArray, 0, sizeof(uint8_t) * BTRC_FEATURE_BIT_MASK_SIZE,
+                    (jbyte *) item->player.features);
+                jstring playerName = sCallbackEnv->NewStringUTF((const char *) item->player.name);
+                jobject playerObj = (jobject) sCallbackEnv->CallObjectMethod(
+                    sCallbacksObj, method_createFromNativePlayerItem, id,
+                    playerName, featureBitArray, playStatus, playerType);
+                sCallbackEnv->SetObjectArrayElement(playerItemArray, i, playerObj);
+
+                sCallbackEnv->DeleteLocalRef(featureBitArray);
+                sCallbackEnv->DeleteLocalRef(playerObj);
+                break;
+            }
+
+            default:
+                ALOGE("%s cannot understand type %d", __FUNCTION__, item->item_type);
+        }
+        ALOGI("%s inserted %d elements uptil now", __FUNCTION__, i);
+    }
+
+    ALOGI("%s returning the complete set now", __FUNCTION__);
+    if (isPlayerListing) {
+        sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetPlayerItemsRsp,
+                                     playerItemArray);
+    } else {
+        sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetFolderItemsRsp,
+                                     folderItemArray);
+    }
+    if (isPlayerListing) {
+        sCallbackEnv->DeleteLocalRef(playerItemArray);
+    } else {
+        sCallbackEnv->DeleteLocalRef(folderItemArray);
+    }
+}
+
+static void btavrcp_change_path_callback(bt_bdaddr_t *bd_addr, uint8_t count) {
+    ALOGI("%s count %d", __FUNCTION__, count);
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+
+    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp, (jint) count);
+}
+
+static void btavrcp_set_browsed_player_callback(
+        bt_bdaddr_t *bd_addr, uint8_t num_items, uint8_t depth) {
+    ALOGI("%s items %d depth %d", __FUNCTION__, num_items, depth);
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+
+    sCallbackEnv->CallVoidMethod(
+        sCallbacksObj, method_handleSetBrowsedPlayerRsp, (jint) num_items, (jint) depth);
+}
+
 static btrc_ctrl_callbacks_t sBluetoothAvrcpCallbacks = {
     sizeof(sBluetoothAvrcpCallbacks),
     btavrcp_passthrough_response_callback,
@@ -437,7 +633,10 @@
     btavrcp_register_notification_absvol_callback,
     btavrcp_track_changed_callback,
     btavrcp_play_position_changed_callback,
-    btavrcp_play_status_changed_callback
+    btavrcp_play_status_changed_callback,
+    btavrcp_get_folder_items_callback,
+    btavrcp_change_path_callback,
+    btavrcp_set_browsed_player_callback
 };
 
 static void classInitNative(JNIEnv* env, jclass clazz) {
@@ -448,7 +647,7 @@
         env->GetMethodID(clazz, "handleGroupNavigationRsp", "(II)V");
 
     method_onConnectionStateChanged =
-        env->GetMethodID(clazz, "onConnectionStateChanged", "(Z[B)V");
+        env->GetMethodID(clazz, "onConnectionStateChanged", "(ZZ[B)V");
 
     method_getRcFeatures =
         env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
@@ -475,13 +674,40 @@
         env->GetMethodID(clazz, "onPlayPositionChanged", "([BII)V");
 
     method_handleplaystatuschanged =
-            env->GetMethodID(clazz, "onPlayStatusChanged", "([BB)V");
+        env->GetMethodID(clazz, "onPlayStatusChanged", "([BB)V");
+
+    method_handleGetFolderItemsRsp =
+        env->GetMethodID(clazz, "handleGetFolderItemsRsp", "([Landroid/media/browse/MediaBrowser$MediaItem;)V");
+    method_handleGetPlayerItemsRsp =
+        env->GetMethodID(clazz, "handleGetPlayerItemsRsp",
+                         "([Lcom/android/bluetooth/avrcpcontroller/AvrcpPlayer;)V");
+
+    method_createFromNativeMediaItem =
+        env->GetMethodID(clazz, "createFromNativeMediaItem",
+                         "([BILjava/lang/String;[I[Ljava/lang/String;)Landroid/media/browse/MediaBrowser$MediaItem;");
+    method_createFromNativeFolderItem =
+        env->GetMethodID(clazz, "createFromNativeFolderItem",
+                         "([BILjava/lang/String;I)Landroid/media/browse/MediaBrowser$MediaItem;");
+    method_createFromNativePlayerItem =
+        env->GetMethodID(clazz, "createFromNativePlayerItem",
+                         "(ILjava/lang/String;[BII)Lcom/android/bluetooth/avrcpcontroller/AvrcpPlayer;");
+    method_handleChangeFolderRsp =
+        env->GetMethodID(clazz, "handleChangeFolderRsp", "(I)V");
+    method_handleSetBrowsedPlayerRsp =
+        env->GetMethodID(clazz, "handleSetBrowsedPlayerRsp", "(II)V");
     ALOGI("%s: succeeds", __FUNCTION__);
 }
 
 static void initNative(JNIEnv *env, jobject object) {
     const bt_interface_t* btInf;
     bt_status_t status;
+    sEnv = env;
+
+    jclass tmpMediaItem = env->FindClass("android/media/browse/MediaBrowser$MediaItem");
+    class_MediaBrowser_MediaItem = (jclass) env->NewGlobalRef(tmpMediaItem);
+
+    jclass tmpBtPlayer = env->FindClass("com/android/bluetooth/avrcpcontroller/AvrcpPlayer");
+    class_AvrcpPlayer = (jclass) env->NewGlobalRef(tmpBtPlayer);
 
     if ( (btInf = getBluetoothInterface()) == NULL) {
         ALOGE("Bluetooth module is not loaded");
@@ -494,10 +720,10 @@
          sBluetoothAvrcpInterface = NULL;
     }
 
-    if (mCallbacksObj != NULL) {
+    if (sCallbacksObj != NULL) {
          ALOGW("Cleaning up Avrcp callback object");
-         env->DeleteGlobalRef(mCallbacksObj);
-         mCallbacksObj = NULL;
+         env->DeleteGlobalRef(sCallbacksObj);
+         sCallbacksObj = NULL;
     }
 
     if ( (sBluetoothAvrcpInterface = (btrc_ctrl_interface_t *)
@@ -513,7 +739,7 @@
         return;
     }
 
-    mCallbacksObj = env->NewGlobalRef(object);
+    sCallbacksObj = env->NewGlobalRef(object);
 }
 
 static void cleanupNative(JNIEnv *env, jobject object) {
@@ -529,9 +755,9 @@
         sBluetoothAvrcpInterface = NULL;
     }
 
-    if (mCallbacksObj != NULL) {
-        env->DeleteGlobalRef(mCallbacksObj);
-        mCallbacksObj = NULL;
+    if (sCallbacksObj != NULL) {
+        env->DeleteGlobalRef(sCallbacksObj);
+        sCallbacksObj = NULL;
     }
 }
 
@@ -685,6 +911,137 @@
     env->ReleaseByteArrayElements(address, addr, 0);
 }
 
+static void getNowPlayingListNative(JNIEnv *env, jobject object, jbyteArray address, jbyte start,
+                                    jbyte items) {
+    bt_status_t status;
+    jbyte *addr;
+
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+    ALOGV("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->get_now_playing_list_cmd(
+        (bt_bdaddr_t *) addr, (uint8_t) start, (uint8_t) items)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending getNowPlayingListNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
+static void getFolderListNative(JNIEnv *env, jobject object, jbyteArray address, jbyte start,
+                                    jbyte items) {
+    bt_status_t status;
+    jbyte *addr;
+
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+    ALOGV("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->get_folder_list_cmd(
+        (bt_bdaddr_t *) addr, (uint8_t) start, (uint8_t) items)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending getFolderListNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
+static void getPlayerListNative(JNIEnv *env, jobject object, jbyteArray address, jbyte start,
+                                    jbyte items) {
+    bt_status_t status;
+    jbyte *addr;
+
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+    ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->get_player_list_cmd(
+        (bt_bdaddr_t *) addr, (uint8_t) start, (uint8_t) items)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending getPlayerListNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
+static void changeFolderPathNative(JNIEnv *env, jobject object, jbyteArray address, jbyte direction,
+                                   jbyteArray uidarr) {
+    bt_status_t status;
+
+    jbyte *addr;
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+
+    jbyte *uid;
+    uid = env->GetByteArrayElements(uidarr, NULL);
+    if (!uid) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+
+    ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->change_folder_path_cmd(
+            (bt_bdaddr_t *) addr, (uint8_t) direction, (uint8_t *) uid)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending changeFolderPathNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
+static void setBrowsedPlayerNative(JNIEnv *env, jobject object, jbyteArray address, jint id) {
+    bt_status_t status;
+
+    jbyte *addr;
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+
+    ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->set_browsed_player_cmd(
+            (bt_bdaddr_t *) addr, (uint16_t) id)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending changeFolderPathNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
+static void playItemNative(JNIEnv *env, jobject object, jbyteArray address, jbyte scope,
+                                   jbyteArray uidArr, jint uidCounter) {
+    bt_status_t status;
+
+    jbyte *addr;
+    if (!sBluetoothAvrcpInterface) return;
+    addr = env->GetByteArrayElements(address, NULL);
+    if (!addr) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+
+    jbyte *uid;
+    uid = env->GetByteArrayElements(uidArr, NULL);
+    if (!uid) {
+        jniThrowIOException(env, EINVAL);
+        return;
+    }
+
+    ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if ((status = sBluetoothAvrcpInterface->play_item_cmd(
+            (bt_bdaddr_t *) addr, (uint8_t) scope, (uint8_t *) uid,
+            (uint16_t) uidCounter)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed sending playItemNative command, status: %d", status);
+    }
+    env->ReleaseByteArrayElements(address, addr, 0);
+}
+
 static JNINativeMethod sMethods[] = {
     {"classInitNative", "()V", (void *) classInitNative},
     {"initNative", "()V", (void *) initNative},
@@ -695,11 +1052,18 @@
                                (void *) setPlayerApplicationSettingValuesNative},
     {"sendAbsVolRspNative", "([BII)V",(void *) sendAbsVolRspNative},
     {"sendRegisterAbsVolRspNative", "([BBII)V",(void *) sendRegisterAbsVolRspNative},
+    {"getNowPlayingListNative", "([BBB)V", (void *) getNowPlayingListNative},
+    {"getFolderListNative", "([BBB)V", (void *) getFolderListNative},
+    {"getPlayerListNative", "([BBB)V", (void *) getPlayerListNative},
+    {"changeFolderPathNative", "([BB[B)V", (void *) changeFolderPathNative},
+    {"playItemNative", "([BB[BI)V", (void *) playItemNative},
+    {"setBrowsedPlayerNative", "([BI)V", (void *) setBrowsedPlayerNative},
 };
 
 int register_com_android_bluetooth_avrcp_controller(JNIEnv* env)
 {
-    return jniRegisterNativeMethods(env, "com/android/bluetooth/avrcp/AvrcpControllerService",
+    return jniRegisterNativeMethods(env,
+                                    "com/android/bluetooth/avrcpcontroller/AvrcpControllerService",
                                     sMethods, NELEM(sMethods));
 }
 
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index fa57e4f..70dcfea 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -1365,7 +1365,6 @@
     if (!sGattIf) return;
 
     set_uuid(uuid.uu, app_uuid_msb, app_uuid_lsb);
-    error("advertiser address is: %d", sGattIf->advertiser);
     sGattIf->advertiser->RegisterAdvertiser(base::Bind(&ble_advertiser_register_cb, uuid));
 }
 
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
index 1d84d0f..4d0d2ca 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
@@ -17,13 +17,14 @@
 package com.android.bluetooth.a2dpsink;
 
 import android.bluetooth.BluetoothAudioConfig;
-import android.bluetooth.BluetoothAvrcpController;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.IBluetoothA2dpSink;
 import android.content.Intent;
 import android.provider.Settings;
 import android.util.Log;
+
+import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
 import com.android.bluetooth.a2dpsink.mbs.A2dpMediaBrowserService;
 
 import com.android.bluetooth.btservice.ProfileService;
@@ -192,12 +193,12 @@
      */
     public void informAvrcpPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) {
         if (mStateMachine != null) {
-            if (keyCode == BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY &&
-                keyState == BluetoothAvrcpController.KEY_STATE_RELEASED) {
+            if (keyCode == AvrcpControllerService.PASS_THRU_CMD_ID_PLAY &&
+                keyState == AvrcpControllerService.KEY_STATE_RELEASED) {
                 mStateMachine.sendMessage(A2dpSinkStateMachine.EVENT_AVRCP_CT_PLAY);
-            } else if ((keyCode == BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE ||
-                       keyCode == BluetoothAvrcpController.PASS_THRU_CMD_ID_STOP) &&
-                       keyState == BluetoothAvrcpController.KEY_STATE_RELEASED) {
+            } else if ((keyCode == AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE ||
+                       keyCode == AvrcpControllerService.PASS_THRU_CMD_ID_STOP) &&
+                       keyState == AvrcpControllerService.KEY_STATE_RELEASED) {
                 mStateMachine.sendMessage(A2dpSinkStateMachine.EVENT_AVRCP_CT_PAUSE);
             }
         }
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
index 6e6e2af..c005f27 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
@@ -29,7 +29,6 @@
 package com.android.bluetooth.a2dpsink;
 
 import android.bluetooth.BluetoothA2dpSink;
-import android.bluetooth.BluetoothAvrcpController;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothAudioConfig;
 import android.bluetooth.BluetoothDevice;
@@ -49,7 +48,7 @@
 import com.android.bluetooth.Utils;
 import com.android.bluetooth.btservice.AdapterService;
 import com.android.bluetooth.btservice.ProfileService;
-import com.android.bluetooth.avrcp.AvrcpControllerService;
+import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
@@ -694,16 +693,21 @@
         return false;
     }
 
+    // Utility Functions
     boolean okToConnect(BluetoothDevice device) {
         AdapterService adapterService = AdapterService.getAdapterService();
-        boolean ret = true;
-        //check if this is an incoming connection in Quiet mode.
-        if((adapterService == null) ||
-           ((adapterService.isQuietModeEnabled() == true) &&
-           (mTargetDevice == null))){
-            ret = false;
+        int priority = mService.getPriority(device);
+
+        // check priority and accept or reject the connection. if priority is undefined
+        // it is likely that our SDP has not completed and peer is initiating the
+        // connection. Allow this connection, provided the device is bonded
+        if((BluetoothProfile.PRIORITY_OFF < priority) ||
+                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
+                (device.getBondState() != BluetoothDevice.BOND_NONE))){
+            return true;
         }
-        return ret;
+        logw("okToConnect not OK to connect " + device);
+        return false;
     }
 
     synchronized List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
@@ -802,6 +806,7 @@
             this.type = type;
         }
     }
+
     /** Handles A2DP connection state change intent broadcasts. */
     private class IntentBroadcastHandler extends Handler {
 
@@ -833,11 +838,11 @@
             if ((avrcpCtrlService != null) && (mDevice != null) &&
                 (avrcpCtrlService.getConnectedDevices().contains(mDevice))){
                 avrcpCtrlService.sendPassThroughCmd(mDevice,
-                    BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY,
-                    BluetoothAvrcpController.KEY_STATE_PRESSED);
+                    AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+                    AvrcpControllerService.KEY_STATE_PRESSED);
                 avrcpCtrlService.sendPassThroughCmd(mDevice,
-                    BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY,
-                    BluetoothAvrcpController.KEY_STATE_RELEASED);
+                    AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+                    AvrcpControllerService.KEY_STATE_RELEASED);
                 log(" SendPassThruPlay command sent - ");
                 return true;
             } else {
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamingStateMachine.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamingStateMachine.java
index fb62c95..9a84eb0 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamingStateMachine.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamingStateMachine.java
@@ -17,7 +17,6 @@
 package com.android.bluetooth.a2dpsink;
 
 import android.bluetooth.BluetoothA2dpSink;
-import android.bluetooth.BluetoothAvrcpController;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.media.AudioManager;
@@ -25,7 +24,7 @@
 import android.os.Message;
 import android.util.Log;
 
-import com.android.bluetooth.avrcp.AvrcpControllerService;
+import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
 import com.android.bluetooth.R;
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
@@ -209,12 +208,12 @@
             }
             avrcpService.sendPassThroughCmd(
                 avrcpService.getConnectedDevices().get(0),
-                BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE,
-                BluetoothAvrcpController.KEY_STATE_PRESSED);
+                AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
+                AvrcpControllerService.KEY_STATE_PRESSED);
             avrcpService.sendPassThroughCmd(
                 avrcpService.getConnectedDevices().get(0),
-                BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE,
-                BluetoothAvrcpController.KEY_STATE_RELEASED);
+                AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE,
+                AvrcpControllerService.KEY_STATE_RELEASED);
         } else {
             Log.e(TAG, "Passthrough not sent, connection un-available.");
         }
@@ -233,12 +232,12 @@
             }
             avrcpService.sendPassThroughCmd(
                 avrcpService.getConnectedDevices().get(0),
-                BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY,
-                BluetoothAvrcpController.KEY_STATE_PRESSED);
+                AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+                AvrcpControllerService.KEY_STATE_PRESSED);
             avrcpService.sendPassThroughCmd(
                 avrcpService.getConnectedDevices().get(0),
-                BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY,
-                BluetoothAvrcpController.KEY_STATE_RELEASED);
+                AvrcpControllerService.PASS_THRU_CMD_ID_PLAY,
+                AvrcpControllerService.KEY_STATE_RELEASED);
         } else {
             Log.e(TAG, "Passthrough not sent, connection un-available.");
         }
diff --git a/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java b/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
index 7ee0276..f663571 100644
--- a/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
+++ b/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java
@@ -24,8 +24,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.media.MediaMetadata;
+import android.media.browse.MediaBrowser;
 import android.media.browse.MediaBrowser.MediaItem;
+import android.media.MediaDescription;
+import android.media.MediaMetadata;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
@@ -33,44 +35,54 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcelable;
 import android.os.ResultReceiver;
 import android.service.media.MediaBrowserService;
 import android.util.Pair;
 import android.util.Log;
 
 import com.android.bluetooth.R;
+import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
+import com.android.bluetooth.avrcpcontroller.BrowseTree;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class A2dpMediaBrowserService extends MediaBrowserService {
     private static final String TAG = "A2dpMediaBrowserService";
-    private static final String MEDIA_ID_ROOT = "__ROOT__";
     private static final String UNKNOWN_BT_AUDIO = "__UNKNOWN_BT_AUDIO__";
     private static final float PLAYBACK_SPEED = 1.0f;
 
     // Message sent when A2DP device is disconnected.
     private static final int MSG_DEVICE_DISCONNECT = 0;
-    // Message snet when the AVRCP profile is disconnected = 1;
-    private static final int MSG_PROFILE_DISCONNECT = 1;
     // Message sent when A2DP device is connected.
     private static final int MSG_DEVICE_CONNECT = 2;
-    // Message sent when AVRCP profile is connected (note AVRCP profile may be connected before or
-    // after A2DP device is connected).
-    private static final int MSG_PROFILE_CONNECT = 3;
     // Message sent when we recieve a TRACK update from AVRCP profile over a connected A2DP device.
     private static final int MSG_TRACK = 4;
     // Internal message sent to trigger a AVRCP action.
     private static final int MSG_AVRCP_PASSTHRU = 5;
+    // Message sent when AVRCP browse is connected.
+    private static final int MSG_DEVICE_BROWSE_CONNECT = 6;
+    // Message sent when AVRCP browse is disconnected.
+    private static final int MSG_DEVICE_BROWSE_DISCONNECT = 7;
+    // Message sent when folder list is fetched.
+    private static final int MSG_FOLDER_LIST = 9;
 
     private MediaSession mSession;
     private MediaMetadata mA2dpMetadata;
 
-    private BluetoothAdapter mAdapter;
-    private BluetoothAvrcpController mAvrcpProfile;
+    private AvrcpControllerService mAvrcpCtrlSrvc;
+    private boolean mBrowseConnected = false;
     private BluetoothDevice mA2dpDevice = null;
     private Handler mAvrcpCommandQueue;
+    private final Map<String, Result<List<MediaItem>>> mParentIdToRequestMap = new HashMap<>();
+    private static final List<MediaItem> mEmptyList = new ArrayList<MediaItem>();
+
+    // Browsing related structures.
+    private List<MediaItem> mNowPlayingList = null;
 
     private long mTransportControlFlags = PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY
             | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS;
@@ -95,15 +107,9 @@
                 case MSG_DEVICE_CONNECT:
                     inst.msgDeviceConnect((BluetoothDevice) msg.obj);
                     break;
-                case MSG_PROFILE_CONNECT:
-                    inst.msgProfileConnect((BluetoothProfile) msg.obj);
-                    break;
                 case MSG_DEVICE_DISCONNECT:
                     inst.msgDeviceDisconnect((BluetoothDevice) msg.obj);
                     break;
-                case MSG_PROFILE_DISCONNECT:
-                    inst.msgProfileDisconnect();
-                    break;
                 case MSG_TRACK:
                     Pair<PlaybackState, MediaMetadata> pair =
                         (Pair<PlaybackState, MediaMetadata>) (msg.obj);
@@ -112,6 +118,17 @@
                 case MSG_AVRCP_PASSTHRU:
                     inst.msgPassThru((int) msg.obj);
                     break;
+                case MSG_DEVICE_BROWSE_CONNECT:
+                    inst.msgDeviceBrowseConnect((BluetoothDevice) msg.obj);
+                    break;
+                case MSG_DEVICE_BROWSE_DISCONNECT:
+                    inst.msgDeviceBrowseDisconnect((BluetoothDevice) msg.obj);
+                    break;
+                case MSG_FOLDER_LIST:
+                    inst.msgFolderList((Intent) msg.obj);
+                    break;
+                default:
+                    Log.e(TAG, "Message not handled " + msg);
             }
         }
     }
@@ -120,6 +137,7 @@
     public void onCreate() {
         Log.d(TAG, "onCreate");
         super.onCreate();
+
         mSession = new MediaSession(this, TAG);
         setSessionToken(mSession.getSessionToken());
         mSession.setCallback(mSessionCallbacks);
@@ -127,13 +145,18 @@
                 MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
         mAvrcpCommandQueue = new AvrcpCommandQueueHandler(Looper.getMainLooper(), this);
 
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mAdapter.getProfileProxy(this, mServiceListener, BluetoothProfile.AVRCP_CONTROLLER);
+        refreshInitialPlayingState();
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothAvrcpController.ACTION_TRACK_EVENT);
+        filter.addAction(AvrcpControllerService.ACTION_BROWSE_CONNECTION_STATE_CHANGED);
+        filter.addAction(AvrcpControllerService.ACTION_TRACK_EVENT);
+        filter.addAction(AvrcpControllerService.ACTION_FOLDER_LIST);
         registerReceiver(mBtReceiver, filter);
+
+        synchronized (this) {
+            mParentIdToRequestMap.clear();
+        }
     }
 
     @Override
@@ -146,37 +169,32 @@
 
     @Override
     public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
-        return new BrowserRoot(MEDIA_ID_ROOT, null);
+        return new BrowserRoot(BrowseTree.ROOT, null);
     }
 
     @Override
-    public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) {
+    public synchronized void onLoadChildren(
+            final String parentMediaId, final Result<List<MediaItem>> result) {
+        if (mAvrcpCtrlSrvc == null) {
+            Log.e(TAG, "AVRCP not yet connected.");
+            result.sendResult(mEmptyList);
+            return;
+        }
+
         Log.d(TAG, "onLoadChildren parentMediaId=" + parentMediaId);
-        List<MediaItem> items = new ArrayList<MediaItem>();
-        result.sendResult(items);
+        mAvrcpCtrlSrvc.getChildren(mA2dpDevice, parentMediaId, 0, 0xff);
+
+        // Since we are using this thread from a binder thread we should make sure that
+        // we synchronize against other such asynchronous calls.
+        synchronized (this) {
+            mParentIdToRequestMap.put(parentMediaId, result);
+        }
+        result.detach();
     }
 
-    BluetoothProfile.ServiceListener mServiceListener = new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            Log.d(TAG, "onServiceConnected");
-            if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
-                mAvrcpCommandQueue.obtainMessage(MSG_PROFILE_CONNECT, proxy).sendToTarget();
-                List<BluetoothDevice> devices = proxy.getConnectedDevices();
-                if (devices != null && devices.size() > 0) {
-                    BluetoothDevice device = devices.get(0);
-                    Log.d(TAG, "got AVRCP device " + device);
-                }
-            }
-        }
-
-        public void onServiceDisconnected(int profile) {
-            Log.d(TAG, "onServiceDisconnected " + profile);
-            if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
-                mAvrcpProfile = null;
-                mAvrcpCommandQueue.obtainMessage(MSG_PROFILE_DISCONNECT).sendToTarget();
-            }
-        }
-    };
+    @Override
+    public void onLoadItem(String itemId, Result<MediaBrowser.MediaItem> result) {
+    }
 
     // Media Session Stuff.
     private MediaSession.Callback mSessionCallbacks = new MediaSession.Callback() {
@@ -184,7 +202,7 @@
         public void onPlay() {
             Log.d(TAG, "onPlay");
             mAvrcpCommandQueue.obtainMessage(
-                MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY).sendToTarget();
+                MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY).sendToTarget();
             // TRACK_EVENT should be fired eventually and the UI should be hence updated.
         }
 
@@ -192,7 +210,7 @@
         public void onPause() {
             Log.d(TAG, "onPause");
             mAvrcpCommandQueue.obtainMessage(
-                MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE).sendToTarget();
+                MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE).sendToTarget();
             // TRACK_EVENT should be fired eventually and the UI should be hence updated.
         }
 
@@ -200,7 +218,7 @@
         public void onSkipToNext() {
             Log.d(TAG, "onSkipToNext");
             mAvrcpCommandQueue.obtainMessage(
-                MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_FORWARD)
+                MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FORWARD)
                 .sendToTarget();
             // TRACK_EVENT should be fired eventually and the UI should be hence updated.
         }
@@ -210,7 +228,7 @@
             Log.d(TAG, "onSkipToPrevious");
 
             mAvrcpCommandQueue.obtainMessage(
-                MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_BACKWARD)
+                MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_BACKWARD)
                 .sendToTarget();
             // TRACK_EVENT should be fired eventually and the UI should be hence updated.
         }
@@ -243,9 +261,16 @@
 
         @Override
         public void onPlayFromMediaId(String mediaId, Bundle extras) {
-            Log.d(TAG, "onPlayFromMediaId mediaId=" + mediaId + " extras=" + extras);
-        }
+            synchronized (A2dpMediaBrowserService.this) {
+                // Play the item if possible.
+                mAvrcpCtrlSrvc.fetchAttrAndPlayItem(mA2dpDevice, mediaId);
 
+                // Since we request explicit playback here we should start the updates to UI.
+                mAvrcpCtrlSrvc.startAvrcpUpdates();
+            }
+
+            // TRACK_EVENT should be fired eventually and the UI should be hence updated.
+        }
     };
 
     private BroadcastReceiver mBtReceiver = new BroadcastReceiver() {
@@ -268,40 +293,49 @@
                     // Set the playback state to unconnected.
                     mAvrcpCommandQueue.obtainMessage(MSG_DEVICE_DISCONNECT, btDev).sendToTarget();
                 }
-            } else if (BluetoothAvrcpController.ACTION_TRACK_EVENT.equals(action)) {
+            } else if (AvrcpControllerService.ACTION_BROWSE_CONNECTION_STATE_CHANGED.equals(
+                action)) {
+                if (state == BluetoothProfile.STATE_CONNECTED) {
+                    mAvrcpCommandQueue.obtainMessage(
+                        MSG_DEVICE_BROWSE_CONNECT, btDev).sendToTarget();
+                } else if (state == BluetoothProfile.STATE_DISCONNECTED) {
+                    mAvrcpCommandQueue.obtainMessage(
+                        MSG_DEVICE_BROWSE_DISCONNECT, btDev).sendToTarget();
+                }
+            } else if (AvrcpControllerService.ACTION_TRACK_EVENT.equals(action)) {
                 PlaybackState pbb =
-                    intent.getParcelableExtra(BluetoothAvrcpController.EXTRA_PLAYBACK);
+                    intent.getParcelableExtra(AvrcpControllerService.EXTRA_PLAYBACK);
                 MediaMetadata mmd =
-                    intent.getParcelableExtra(BluetoothAvrcpController.EXTRA_METADATA);
+                    intent.getParcelableExtra(AvrcpControllerService.EXTRA_METADATA);
                 mAvrcpCommandQueue.obtainMessage(
                     MSG_TRACK, new Pair<PlaybackState, MediaMetadata>(pbb, mmd)).sendToTarget();
+            } else if (AvrcpControllerService.ACTION_FOLDER_LIST.equals(action)) {
+                mAvrcpCommandQueue.obtainMessage(MSG_FOLDER_LIST, intent).sendToTarget();
             }
         }
     };
 
-    private void msgDeviceConnect(BluetoothDevice device) {
+    private synchronized void msgDeviceConnect(BluetoothDevice device) {
         Log.d(TAG, "msgDeviceConnect");
         // We are connected to a new device via A2DP now.
         mA2dpDevice = device;
-        refreshInitialPlayingState();
-    }
-
-    private void msgProfileConnect(BluetoothProfile profile) {
-        Log.d(TAG, "msgProfileConnect");
-        if (profile != null) {
-            mAvrcpProfile = (BluetoothAvrcpController) profile;
+        mAvrcpCtrlSrvc = AvrcpControllerService.getAvrcpControllerService();
+        if (mAvrcpCtrlSrvc == null) {
+            Log.e(TAG, "!!!AVRCP Controller cannot be null");
+            return;
         }
         refreshInitialPlayingState();
     }
 
+
     // Refresh the UI if we have a connected device and AVRCP is initialized.
-    private void refreshInitialPlayingState() {
-        if (mAvrcpProfile == null || mA2dpDevice == null) {
-            Log.d(TAG, "AVRCP Profile " + mAvrcpProfile + " device " + mA2dpDevice);
+    private synchronized void refreshInitialPlayingState() {
+        if (mA2dpDevice == null) {
+            Log.d(TAG, "device " + mA2dpDevice);
             return;
         }
 
-        List<BluetoothDevice> devices = mAvrcpProfile.getConnectedDevices();
+        List<BluetoothDevice> devices = mAvrcpCtrlSrvc.getConnectedDevices();
         if (devices.size() == 0) {
             Log.w(TAG, "No devices connected yet");
             return;
@@ -309,17 +343,18 @@
 
         if (mA2dpDevice != null && !mA2dpDevice.equals(devices.get(0))) {
             Log.e(TAG, "A2dp device : " + mA2dpDevice + " avrcp device " + devices.get(0));
+            return;
         }
         mA2dpDevice = devices.get(0);
 
-        PlaybackState playbackState = mAvrcpProfile.getPlaybackState(mA2dpDevice);
+        PlaybackState playbackState = mAvrcpCtrlSrvc.getPlaybackState(mA2dpDevice);
         // Add actions required for playback and rebuild the object.
         PlaybackState.Builder pbb = new PlaybackState.Builder(playbackState);
         playbackState = pbb.setActions(mTransportControlFlags).build();
 
-        MediaMetadata mediaMetadata = mAvrcpProfile.getMetadata(mA2dpDevice);
+        MediaMetadata mediaMetadata = mAvrcpCtrlSrvc.getMetaData(mA2dpDevice);
         Log.d(TAG, "Media metadata " + mediaMetadata + " playback state " + playbackState);
-        mSession.setMetadata(mAvrcpProfile.getMetadata(mA2dpDevice));
+        mSession.setMetadata(mAvrcpCtrlSrvc.getMetaData(mA2dpDevice));
         mSession.setPlaybackState(playbackState);
     }
 
@@ -341,21 +376,10 @@
                 .setActions(mTransportControlFlags)
                 .setErrorMessage(getString(R.string.bluetooth_disconnected));
         mSession.setPlaybackState(pbb.build());
-    }
 
-    private void msgProfileDisconnect() {
-        Log.d(TAG, "msgProfileDisconnect");
-        // The profile is disconnected - even if the device is still connected we cannot really have
-        // a functioning UI so reset the session.
-        mAvrcpProfile = null;
-
-        // Unset the session.
-        PlaybackState.Builder pbb = new PlaybackState.Builder();
-        pbb = pbb.setState(PlaybackState.STATE_ERROR, PlaybackState.PLAYBACK_POSITION_UNKNOWN,
-                    PLAYBACK_SPEED)
-                .setActions(mTransportControlFlags)
-                .setErrorMessage(getString(R.string.bluetooth_disconnected));
-        mSession.setPlaybackState(pbb.build());
+        // Set device to null.
+        mA2dpDevice = null;
+        mBrowseConnected = false;
     }
 
     private void msgTrack(PlaybackState pb, MediaMetadata mmd) {
@@ -388,7 +412,7 @@
         }
     }
 
-    private void msgPassThru(int cmd) {
+    private synchronized void msgPassThru(int cmd) {
         Log.d(TAG, "msgPassThru " + cmd);
         if (mA2dpDevice == null) {
             // We should have already disconnected - ignore this message.
@@ -396,17 +420,54 @@
             return;
         }
 
-        if (mAvrcpProfile == null) {
-            // We may be disconnected with the profile but there is not much we can do for now but
-            // to wait for the profile to come back up.
-            Log.e(TAG, "Profile disconnected; ignoring.");
+        // Send the pass through.
+        mAvrcpCtrlSrvc.sendPassThroughCmd(
+            mA2dpDevice, cmd, AvrcpControllerService.KEY_STATE_PRESSED);
+        mAvrcpCtrlSrvc.sendPassThroughCmd(
+            mA2dpDevice, cmd, AvrcpControllerService.KEY_STATE_RELEASED);
+    }
+
+    private void msgDeviceBrowseConnect(BluetoothDevice device) {
+        Log.d(TAG, "msgDeviceBrowseConnect device " + device);
+        // We should already be connected to this device over A2DP.
+        if (!device.equals(mA2dpDevice)) {
+            Log.e(TAG, "Browse connected over different device a2dp " + mA2dpDevice +
+                " browse " + device);
             return;
         }
+        mBrowseConnected = true;
+    }
 
-        // Send the pass through.
-        mAvrcpProfile.sendPassThroughCmd(
-            mA2dpDevice, cmd, BluetoothAvrcpController.KEY_STATE_PRESSED);
-        mAvrcpProfile.sendPassThroughCmd(
-            mA2dpDevice, cmd, BluetoothAvrcpController.KEY_STATE_RELEASED);
+    private void msgFolderList(Intent intent) {
+        // Parse the folder list for children list and id.
+        List<Parcelable> extraParcelableList =
+            (ArrayList<Parcelable>) intent.getParcelableArrayListExtra(
+                AvrcpControllerService.EXTRA_FOLDER_LIST);
+        List<MediaItem> folderList = new ArrayList<MediaItem>();
+        for (Parcelable p : extraParcelableList) {
+            folderList.add((MediaItem) p);
+        }
+
+        String id = intent.getStringExtra(AvrcpControllerService.EXTRA_FOLDER_ID);
+        Log.d(TAG, "Parent: " + id + " Folder list: " + folderList);
+        synchronized (this) {
+            Result<List<MediaItem>> results = mParentIdToRequestMap.remove(id);
+            if (results == null) {
+                Log.w(TAG, "Request no longer exists, hence ignoring reply!");
+                return;
+            }
+            results.sendResult(folderList);
+        }
+    }
+
+    private void msgDeviceBrowseDisconnect(BluetoothDevice device) {
+        Log.d(TAG, "msgDeviceBrowseDisconnect device " + device);
+        // Disconnect only if mA2dpDevice is non null
+        if (!device.equals(mA2dpDevice)) {
+            Log.w(TAG, "Browse disconnecting from different device a2dp " + mA2dpDevice +
+                " browse " + device);
+            return;
+        }
+        mBrowseConnected = false;
     }
 }
diff --git a/src/com/android/bluetooth/avrcp/AvrcpControllerService.java b/src/com/android/bluetooth/avrcp/AvrcpControllerService.java
deleted file mode 100644
index 6675124..0000000
--- a/src/com/android/bluetooth/avrcp/AvrcpControllerService.java
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.bluetooth.avrcp;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothAvrcpController;
-import android.bluetooth.BluetoothAvrcpPlayerSettings;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothAvrcpController;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.MediaMetadata;
-import android.media.session.PlaybackState;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-import android.media.AudioManager;
-
-import com.android.bluetooth.a2dpsink.A2dpSinkService;
-import com.android.bluetooth.btservice.ProfileService;
-import com.android.bluetooth.Utils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.nio.charset.Charset;
-import java.nio.ByteBuffer;
-
-/**
- * Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application.
- * @hide
- */
-public class AvrcpControllerService extends ProfileService {
-    private static final boolean DBG = AvrcpControllerConstants.DBG;
-    private static final boolean VDBG = AvrcpControllerConstants.VDBG;
-    private static final String TAG = "AvrcpControllerService";
-
-/*
- *  Messages handled by mHandler
- */
-
-    RemoteDevice mAvrcpRemoteDevice;
-    RemoteMediaPlayers mRemoteMediaPlayers;
-    NowPlaying mRemoteNowPlayingList;
-
-    private AvrcpMessageHandler mHandler;
-    private static AvrcpControllerService sAvrcpControllerService;
-    private static AudioManager mAudioManager;
-
-    private final ArrayList<BluetoothDevice> mConnectedDevices
-            = new ArrayList<BluetoothDevice>();
-
-    static {
-        classInitNative();
-    }
-
-    public AvrcpControllerService() {
-        initNative();
-    }
-
-    protected String getName() {
-        return TAG;
-    }
-
-    protected IProfileServiceBinder initBinder() {
-        return new BluetoothAvrcpControllerBinder(this);
-    }
-
-    protected boolean start() {
-        HandlerThread thread = new HandlerThread("BluetoothAvrcpHandler");
-        thread.start();
-        Looper looper = thread.getLooper();
-        mHandler = new AvrcpMessageHandler(looper);
-
-        setAvrcpControllerService(this);
-        mAudioManager = (AudioManager)sAvrcpControllerService.
-                                  getSystemService(Context.AUDIO_SERVICE);
-        return true;
-    }
-
-    protected void resetRemoteData() {
-        try {
-            unregisterReceiver(mBroadcastReceiver);
-        }
-        catch (IllegalArgumentException e) {
-            Log.e(TAG,"Receiver not registered");
-        }
-        if(mAvrcpRemoteDevice != null) {
-            mAvrcpRemoteDevice.cleanup();
-            mAvrcpRemoteDevice = null;
-        }
-        if(mRemoteMediaPlayers != null) {
-            mRemoteMediaPlayers.cleanup();
-            mRemoteMediaPlayers = null;
-        }
-        if(mRemoteNowPlayingList != null) {
-            mRemoteNowPlayingList.cleanup();
-            mRemoteNowPlayingList = null;
-        }
-    }
-    protected boolean stop() {
-        if (mHandler != null) {
-            mHandler.removeCallbacksAndMessages(null);
-            Looper looper = mHandler.getLooper();
-            if (looper != null) {
-                looper.quit();
-            }
-        }
-        resetRemoteData();
-        return true;
-    }
-
-    protected boolean cleanup() {
-        if (mHandler != null) {
-            mHandler.removeCallbacksAndMessages(null);
-            Looper looper = mHandler.getLooper();
-            if (looper != null) looper.quit();
-        }
-        resetRemoteData();
-        clearAvrcpControllerService();
-        cleanupNative();
-
-        return true;
-    }
-
-    //API Methods
-
-    public static synchronized AvrcpControllerService getAvrcpControllerService(){
-        if (sAvrcpControllerService != null && sAvrcpControllerService.isAvailable()) {
-            if (DBG) Log.d(TAG, "getAvrcpControllerService(): returning "
-                    + sAvrcpControllerService);
-            return sAvrcpControllerService;
-        }
-        if (DBG)  {
-            if (sAvrcpControllerService == null) {
-                Log.d(TAG, "getAvrcpControllerService(): service is NULL");
-            } else if (!(sAvrcpControllerService.isAvailable())) {
-                Log.d(TAG,"getAvrcpControllerService(): service is not available");
-            }
-        }
-        return null;
-    }
-
-    private static synchronized void setAvrcpControllerService(AvrcpControllerService instance) {
-        if (instance != null && instance.isAvailable()) {
-            if (DBG) Log.d(TAG, "setAvrcpControllerService(): set to: " + sAvrcpControllerService);
-            sAvrcpControllerService = instance;
-        } else {
-            if (DBG)  {
-                if (sAvrcpControllerService == null) {
-                    Log.d(TAG, "setAvrcpControllerService(): service not available");
-                } else if (!sAvrcpControllerService.isAvailable()) {
-                    Log.d(TAG,"setAvrcpControllerService(): service is cleaning up");
-                }
-            }
-        }
-    }
-
-    private static synchronized void clearAvrcpControllerService() {
-        sAvrcpControllerService = null;
-    }
-
-    public List<BluetoothDevice> getConnectedDevices() {
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return mConnectedDevices;
-    }
-
-    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        for (int i = 0; i < states.length; i++) {
-            if (states[i] == BluetoothProfile.STATE_CONNECTED) {
-                return mConnectedDevices;
-            }
-        }
-        return new ArrayList<BluetoothDevice>();
-    }
-
-    int getConnectionState(BluetoothDevice device) {
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return (mConnectedDevices.contains(device) ? BluetoothProfile.STATE_CONNECTED
-                                                : BluetoothProfile.STATE_DISCONNECTED);
-    }
-
-    public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
-        Log.v(TAG, "sendGroupNavigationCmd keyCode: " + keyCode + " keyState: " + keyState);
-        if (device == null) {
-            throw new NullPointerException("device == null");
-        }
-        if (!(mConnectedDevices.contains(device))) {
-            for (BluetoothDevice cdevice : mConnectedDevices) {
-                Log.e(TAG, "Device: " + cdevice);
-            }
-            Log.e(TAG," Device does not match " + device);
-            return;
-        }
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_SEND_GROUP_NAVIGATION_CMD,keyCode, keyState, device);
-        mHandler.sendMessage(msg);
-    }
-
-    public void sendPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) {
-        Log.v(TAG, "sendPassThroughCmd keyCode: " + keyCode + " keyState: " + keyState);
-        if (device == null) {
-            throw new NullPointerException("device == null");
-        }
-        if (!(mConnectedDevices.contains(device))) {
-            Log.d(TAG," Device does not match");
-            return;
-        }
-        if ((mAvrcpRemoteDevice == null)||
-            (mAvrcpRemoteDevice.mRemoteFeatures == AvrcpControllerConstants.BTRC_FEAT_NONE)||
-            (mRemoteMediaPlayers == null) ||
-            (mRemoteMediaPlayers.getAddressedPlayer() == null)){
-            Log.d(TAG," Device connected but PlayState not present ");
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            Message msg = mHandler.obtainMessage(AvrcpControllerConstants.MESSAGE_SEND_PASS_THROUGH_CMD,
-                    keyCode, keyState, device);
-            mHandler.sendMessage(msg);
-            return;
-        }
-        boolean sendCommand = false;
-        switch(keyCode) {
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY:
-                sendCommand  = (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_STOPPED)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PAUSED) ||
-                                (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PLAYING);
-                break;
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE:
-            /*
-             * allowing pause command in pause state to handle A2DP Sink Concurrency
-             * If call is ongoing and Start is initiated from remote, we will send pause again
-             * If acquireFocus fails, we will send Pause again
-             * To Stop sending multiple Pause, check in application.
-             */
-                sendCommand  = (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PLAYING)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_FWD_SEEK)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_STOPPED)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PAUSED)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_REV_SEEK);
-                break;
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_STOP:
-                sendCommand  = (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PLAYING)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_FWD_SEEK)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_REV_SEEK)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_STOPPED)||
-                               (mRemoteMediaPlayers.getPlayStatus() ==
-                                       AvrcpControllerConstants.PLAY_STATUS_PAUSED);
-                break;
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_BACKWARD:
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_FORWARD:
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_FF:
-            case BluetoothAvrcpController.PASS_THRU_CMD_ID_REWIND:
-                sendCommand = true; // we can send this command in all states
-                break;
-        }
-        if (sendCommand) {
-            enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-            Message msg = mHandler.obtainMessage(AvrcpControllerConstants.MESSAGE_SEND_PASS_THROUGH_CMD,
-                keyCode, keyState, device);
-            mHandler.sendMessage(msg);
-        }
-        else {
-            Log.e(TAG," Not in right state, don't send Pass Thru cmd ");
-        }
-    }
-
-    public void startAvrcpUpdates() {
-        mHandler.obtainMessage(
-            AvrcpControllerConstants.MESSAGE_START_METADATA_BROADCASTS).sendToTarget();
-    }
-
-    public void stopAvrcpUpdates() {
-        mHandler.obtainMessage(
-            AvrcpControllerConstants.MESSAGE_STOP_METADATA_BROADCASTS).sendToTarget();
-    }
-
-    public MediaMetadata getMetaData(BluetoothDevice device) {
-        Log.d(TAG, "getMetaData = ");
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if((mRemoteNowPlayingList != null) && (mRemoteNowPlayingList.getCurrentTrack() != null)) {
-            return getCurrentMetaData(AvrcpControllerConstants.AVRCP_SCOPE_NOW_PLAYING, 0);
-        }
-        else
-            return null;
-    }
-    public PlaybackState getPlaybackState(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getPlayBackState device = "+ device);
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return getCurrentPlayBackState();
-    }
-    public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
-        if (DBG) Log.d(TAG, "getPlayerApplicationSetting ");
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        return getCurrentPlayerAppSetting();
-    }
-    public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
-        if ((mAvrcpRemoteDevice == null)||(mRemoteMediaPlayers == null)) {
-            return false;
-        }
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        /*
-         * We have to extract values from BluetoothAvrcpPlayerSettings
-         */
-        int mSettings = plAppSetting.getSettings();
-        int numAttributes = 0;
-        /* calculate number of attributes in request */
-        while(mSettings > 0) {
-            numAttributes += ((mSettings & 0x01)!= 0)?1: 0;
-            mSettings = mSettings >> 1;
-        }
-        byte[] attribArray = new byte [2*numAttributes];
-        mSettings = plAppSetting.getSettings();
-        /*
-         * Now we will flatten it <id, val>
-         */
-        int i = 0;
-        if((mSettings & BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER) != 0) {
-            attribArray[i++] = AvrcpControllerConstants.ATTRIB_EQUALIZER_STATUS;
-            attribArray[i++] = (byte)AvrcpUtils.mapAvrcpPlayerSettingstoBTAttribVal(
-                    BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER, plAppSetting.
-                    getSettingValue(BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER));
-        }
-        if((mSettings & BluetoothAvrcpPlayerSettings.SETTING_REPEAT) != 0) {
-            attribArray[i++] = AvrcpControllerConstants.ATTRIB_REPEAT_STATUS;
-            attribArray[i++] = (byte)AvrcpUtils.mapAvrcpPlayerSettingstoBTAttribVal(
-                    BluetoothAvrcpPlayerSettings.SETTING_REPEAT, plAppSetting.
-                    getSettingValue(BluetoothAvrcpPlayerSettings.SETTING_REPEAT));
-        }
-        if((mSettings & BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE) != 0) {
-            attribArray[i++] = AvrcpControllerConstants.ATTRIB_SHUFFLE_STATUS;
-            attribArray[i++] = (byte)AvrcpUtils.mapAvrcpPlayerSettingstoBTAttribVal(
-                    BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE, plAppSetting.
-                    getSettingValue(BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE));
-        }
-        if((mSettings & BluetoothAvrcpPlayerSettings.SETTING_SCAN) != 0) {
-            attribArray[i++] = AvrcpControllerConstants.ATTRIB_SCAN_STATUS;
-            attribArray[i++] = (byte)AvrcpUtils.mapAvrcpPlayerSettingstoBTAttribVal(
-                    BluetoothAvrcpPlayerSettings.SETTING_SCAN, plAppSetting.
-                    getSettingValue(BluetoothAvrcpPlayerSettings.SETTING_SCAN));
-        }
-        boolean isSettingSupported = mRemoteMediaPlayers.getAddressedPlayer().
-                                   isPlayerAppSettingSupported((byte)numAttributes, attribArray);
-        if(isSettingSupported) {
-            ByteBuffer bb = ByteBuffer.wrap(attribArray, 0, (2*numAttributes));
-             Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_SEND_SET_CURRENT_PLAYER_APPLICATION_SETTINGS, numAttributes, 0, bb);
-            mHandler.sendMessage(msg);
-        }
-        return isSettingSupported;
-    }
-
-    //Binder object: Must be static class or memory leak may occur
-    private static class BluetoothAvrcpControllerBinder extends IBluetoothAvrcpController.Stub
-        implements IProfileServiceBinder {
-        private AvrcpControllerService mService;
-
-        private AvrcpControllerService getService() {
-            if (!Utils.checkCaller()) {
-                Log.w(TAG,"AVRCP call not allowed for non-active user");
-                return null;
-            }
-
-            if (mService != null && mService.isAvailable()) {
-                return mService;
-            }
-            return null;
-        }
-
-        BluetoothAvrcpControllerBinder(AvrcpControllerService svc) {
-            mService = svc;
-        }
-
-        public boolean cleanup()  {
-            mService = null;
-            return true;
-        }
-
-        public List<BluetoothDevice> getConnectedDevices() {
-            AvrcpControllerService service = getService();
-            if (service == null) return new ArrayList<BluetoothDevice>(0);
-            return service.getConnectedDevices();
-        }
-
-        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
-            AvrcpControllerService service = getService();
-            if (service == null) return new ArrayList<BluetoothDevice>(0);
-            return service.getDevicesMatchingConnectionStates(states);
-        }
-
-        public int getConnectionState(BluetoothDevice device) {
-            AvrcpControllerService service = getService();
-            if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
-            return service.getConnectionState(device);
-        }
-
-        public void sendPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) {
-            Log.v(TAG,"Binder Call: sendPassThroughCmd");
-            AvrcpControllerService service = getService();
-            if (service == null) return;
-            service.sendPassThroughCmd(device, keyCode, keyState);
-        }
-
-        @Override
-        public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
-            Log.v(TAG,"Binder Call: sendGroupNavigationCmd");
-            AvrcpControllerService service = getService();
-            if (service == null) return;
-            service.sendGroupNavigationCmd(device, keyCode, keyState);
-        }
-
-        @Override
-        public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
-            Log.v(TAG,"Binder Call: getPlayerApplicationSetting ");
-            AvrcpControllerService service = getService();
-            if (service == null) return null;
-            return service.getPlayerSettings(device);
-        }
-
-        @Override
-        public MediaMetadata getMetadata(BluetoothDevice device) {
-            Log.v(TAG,"Binder Call: getMetaData ");
-            AvrcpControllerService service = getService();
-            if (service == null) return null;
-            return service.getMetaData(device);
-        }
-
-        @Override
-        public PlaybackState getPlaybackState(BluetoothDevice device) {
-            Log.v(TAG,"Binder Call: getPlaybackState");
-            AvrcpControllerService service = getService();
-            if (service == null) return null;
-            return service.getPlaybackState(device);
-        }
-
-        @Override
-        public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
-            Log.v(TAG,"Binder Call: setPlayerApplicationSetting " );
-            AvrcpControllerService service = getService();
-            if (service == null) return false;
-            return service.setPlayerApplicationSetting(plAppSetting);
-        }
-    };
-
-    private String utf8ToString(byte[] input)
-    {
-        Charset UTF8_CHARSET = Charset.forName("UTF-8");
-        return new String(input,UTF8_CHARSET);
-    }
-    private int asciiToInt(int len, byte[] array)
-    {
-        return Integer.parseInt(utf8ToString(array));
-    }
-    private BluetoothAvrcpPlayerSettings getCurrentPlayerAppSetting() {
-        if((mRemoteMediaPlayers == null) || (mRemoteMediaPlayers.getAddressedPlayer() == null))
-            return null;
-        return mRemoteMediaPlayers.getAddressedPlayer().getSupportedPlayerAppSetting();
-    }
-    private PlaybackState getCurrentPlayBackState() {
-        if ((mRemoteMediaPlayers == null) || (mRemoteMediaPlayers.getAddressedPlayer() == null)) {
-            return new PlaybackState.Builder().setState(PlaybackState.STATE_ERROR,
-                                                        PlaybackState.PLAYBACK_POSITION_UNKNOWN,
-                                                        0).build();
-        }
-        return AvrcpUtils.mapBtPlayStatustoPlayBackState(
-                mRemoteMediaPlayers.getAddressedPlayer().mPlayStatus,
-                mRemoteMediaPlayers.getAddressedPlayer().mPlayTime);
-    }
-    private MediaMetadata getCurrentMetaData(int scope, int trackId) {
-        /* if scope is now playing */
-        if(scope == AvrcpControllerConstants.AVRCP_SCOPE_NOW_PLAYING) {
-            if((mRemoteNowPlayingList == null) || (mRemoteNowPlayingList.
-                                                           getTrackFromId(trackId) == null))
-                return null;
-            TrackInfo mNowPlayingTrack = mRemoteNowPlayingList.getTrackFromId(trackId);
-            return AvrcpUtils.getMediaMetaData(mNowPlayingTrack);
-        }
-        /* if scope is now playing */
-        else if(scope == AvrcpControllerConstants.AVRCP_SCOPE_VFS) {
-            /* TODO for browsing */
-        }
-        return null;
-    }
-    private void broadcastMetaDataChanged(MediaMetadata mMetaData) {
-        Intent intent = new Intent(BluetoothAvrcpController.ACTION_TRACK_EVENT);
-        intent.putExtra(BluetoothAvrcpController.EXTRA_METADATA, mMetaData);
-        if(DBG) Log.d(TAG," broadcastMetaDataChanged = " +
-                                                   AvrcpUtils.displayMetaData(mMetaData));
-        sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
-    }
-    private void broadcastPlayBackStateChanged(PlaybackState state) {
-        Intent intent = new Intent(BluetoothAvrcpController.ACTION_TRACK_EVENT);
-        intent.putExtra(BluetoothAvrcpController.EXTRA_PLAYBACK, state);
-        if(DBG) Log.d(TAG," broadcastPlayBackStateChanged = " + state.toString());
-        sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
-    }
-    private void broadcastPlayerAppSettingChanged(BluetoothAvrcpPlayerSettings mPlAppSetting) {
-        Intent intent = new Intent(BluetoothAvrcpController.ACTION_PLAYER_SETTING);
-        intent.putExtra(BluetoothAvrcpController.EXTRA_PLAYER_SETTING, mPlAppSetting);
-        if(DBG) Log.d(TAG," broadcastPlayerAppSettingChanged = " +
-                AvrcpUtils.displayBluetoothAvrcpSettings(mPlAppSetting));
-        sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
-    }
-    /** Handles Avrcp messages. */
-    private final class AvrcpMessageHandler extends Handler {
-        private boolean mBroadcastMetadata = false;
-
-        private AvrcpMessageHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            Log.d(TAG," HandleMessage: "+ AvrcpControllerConstants.dumpMessageString(msg.what) +
-                  " Remote Connected " + !mConnectedDevices.isEmpty());
-            A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
-            switch (msg.what) {
-            case AvrcpControllerConstants.MESSAGE_STOP_METADATA_BROADCASTS:
-                // Any messages hence forth about play pos/play status/song info will be ignored.
-                if(mRemoteMediaPlayers != null) {
-                    // Mock the current state to *look like* it is paused. The remote play state is
-                    // still cached in mRemoteMediaPlayers and will be restored when the
-                    // startAvrcpUpdates is called again.
-                    broadcastPlayBackStateChanged(AvrcpUtils.mapBtPlayStatustoPlayBackState
-                            ((byte) AvrcpControllerConstants.PLAY_STATUS_PAUSED,
-                             mRemoteMediaPlayers.getAddressedPlayer().mPlayTime));
-                }
-                mBroadcastMetadata = false;
-                break;
-            case AvrcpControllerConstants.MESSAGE_START_METADATA_BROADCASTS:
-                // Any messages hence forth about play pos/play status/song info will be sent.
-                if(mRemoteMediaPlayers != null) {
-                    broadcastPlayBackStateChanged(getCurrentPlayBackState());
-                    broadcastMetaDataChanged(
-                        getCurrentMetaData(AvrcpControllerConstants.AVRCP_SCOPE_NOW_PLAYING, 0));
-                }
-                mBroadcastMetadata = true;
-                break;
-            case AvrcpControllerConstants.MESSAGE_SEND_PASS_THROUGH_CMD:
-                BluetoothDevice device = (BluetoothDevice)msg.obj;
-                sendPassThroughCommandNative(getByteAddress(device), msg.arg1, msg.arg2);
-                if((a2dpSinkService != null)&&(!mConnectedDevices.isEmpty())) {
-                    Log.d(TAG," inform AVRCP Commands to A2DP Sink ");
-                    a2dpSinkService.informAvrcpPassThroughCmd(device, msg.arg1, msg.arg2);
-                }
-                break;
-            case AvrcpControllerConstants.MESSAGE_SEND_GROUP_NAVIGATION_CMD:
-                BluetoothDevice peerDevice = (BluetoothDevice)msg.obj;
-                sendGroupNavigationCommandNative(getByteAddress(peerDevice), msg.arg1, msg.arg2);
-                break;
-            case AvrcpControllerConstants.MESSAGE_SEND_SET_CURRENT_PLAYER_APPLICATION_SETTINGS:
-                byte numAttributes = (byte)msg.arg1;
-                ByteBuffer bbRsp = (ByteBuffer)msg.obj;
-                byte[] attributeIds = new byte [numAttributes];
-                byte[] attributeVals = new byte [numAttributes];
-                for(int i = 0; (bbRsp.hasRemaining())&&(i < numAttributes); i++) {
-                    attributeIds[i] = bbRsp.get();
-                    attributeVals[i] = bbRsp.get();
-                }
-                setPlayerApplicationSettingValuesNative(getByteAddress(mAvrcpRemoteDevice.mBTDevice),
-                        numAttributes, attributeIds, attributeVals);
-                break;
-
-            case AvrcpControllerConstants.MESSAGE_PROCESS_CONNECTION_CHANGE:
-                int newState = msg.arg1;
-                int oldState = msg.arg2;
-                BluetoothDevice rtDevice =  (BluetoothDevice)msg.obj;
-                if ((newState == BluetoothProfile.STATE_CONNECTED) &&
-                    (oldState == BluetoothProfile.STATE_DISCONNECTED)) {
-                    /* We create RemoteDevice and MediaPlayerList here
-                     * Now playing list after RC features
-                     */
-                    if(mAvrcpRemoteDevice == null){
-                        mAvrcpRemoteDevice =  new RemoteDevice(rtDevice);
-                        /* Remote will have a player irrespective of AVRCP Version
-                         * Create a Default player, we will add entries in case Browsing
-                         * is supported by remote
-                         */
-                        if(mRemoteMediaPlayers == null) {
-                            mRemoteMediaPlayers = new RemoteMediaPlayers(mAvrcpRemoteDevice);
-                            PlayerInfo mPlayer = new PlayerInfo();
-                            mPlayer.mPlayerId = 0;
-                            mRemoteMediaPlayers.addPlayer(mPlayer);
-                            mRemoteMediaPlayers.setAddressedPlayer(mPlayer);
-                        }
-                    }
-                }
-                else if ((newState == BluetoothProfile.STATE_DISCONNECTED) &&
-                        (oldState == BluetoothProfile.STATE_CONNECTED)) /* connection down */
-                {
-                    resetRemoteData();
-                    mHandler.removeCallbacksAndMessages(null);
-                }
-                /*
-                 * Send intent now
-                 */
-                Intent intent = new Intent(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);
-                intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, oldState);
-                intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
-                intent.putExtra(BluetoothDevice.EXTRA_DEVICE, rtDevice);
-//              intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-                sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_RC_FEATURES:
-                if(mAvrcpRemoteDevice == null)
-                    break;
-                mAvrcpRemoteDevice.mRemoteFeatures = msg.arg1;
-                /* in case of AVRCP version < 1.3, no need to add track info */
-                if(mAvrcpRemoteDevice.isMetaDataSupported()) {
-                    if(mRemoteNowPlayingList == null)
-                        mRemoteNowPlayingList = new NowPlaying(mAvrcpRemoteDevice);
-                    TrackInfo mTrack = new TrackInfo();
-                    /* First element of NowPlayingList will be current Track
-                     * for 1.3 this will be the only song
-                     * for >= 1.4, others songs will have non-zero UID
-                     */
-                    mTrack.mItemUid = 0;
-                    mRemoteNowPlayingList.addTrack(mTrack);
-                    mRemoteNowPlayingList.setCurrTrack(mTrack);
-                }
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_SET_ABS_VOL_CMD:
-                mAvrcpRemoteDevice.mAbsVolNotificationState =
-                                         AvrcpControllerConstants.DEFER_VOLUME_CHANGE_RSP;
-                setAbsVolume(msg.arg1, msg.arg2);
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION:
-                /* start BroadcastReceiver now */
-                IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
-                mAvrcpRemoteDevice.mNotificationLabel = msg.arg1;
-                mAvrcpRemoteDevice.mAbsVolNotificationState =
-                        AvrcpControllerConstants.SEND_VOLUME_CHANGE_RSP;
-                registerReceiver(mBroadcastReceiver, filter);
-                int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-                int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
-                int percentageVol = ((currIndex* AvrcpControllerConstants.ABS_VOL_BASE)/maxVolume);
-                Log.d(TAG," Sending Interim Response = "+ percentageVol + " label " + msg.arg1);
-                sendRegisterAbsVolRspNative(getByteAddress(mAvrcpRemoteDevice.mBTDevice),
-                        (byte)AvrcpControllerConstants.NOTIFICATION_RSP_TYPE_INTERIM, percentageVol,
-                        mAvrcpRemoteDevice.mNotificationLabel);
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_TRACK_CHANGED:
-                if(mRemoteNowPlayingList != null) {
-                    mRemoteNowPlayingList.updateCurrentTrack((TrackInfo)msg.obj);
-
-                    if (!mBroadcastMetadata) {
-                        Log.d(TAG, "Metadata is not broadcasted, ignoring.");
-                        return;
-                    }
-
-                    broadcastMetaDataChanged(AvrcpUtils.getMediaMetaData
-                                       (mRemoteNowPlayingList.getCurrentTrack()));
-                }
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_PLAY_POS_CHANGED:
-                if(mRemoteMediaPlayers != null) {
-                    mRemoteMediaPlayers.getAddressedPlayer().mPlayTime = msg.arg2;
-
-                    if (!mBroadcastMetadata) {
-                        Log.d(TAG, "Metadata is not broadcasted, ignoring.");
-                        return;
-                    }
-
-                    broadcastPlayBackStateChanged(AvrcpUtils.mapBtPlayStatustoPlayBackState
-                            (mRemoteMediaPlayers.getAddressedPlayer().mPlayStatus,
-                                    mRemoteMediaPlayers.getAddressedPlayer().mPlayTime));
-                }
-                if(mRemoteNowPlayingList != null) {
-                    mRemoteNowPlayingList.getCurrentTrack().mTrackLen = msg.arg1;
-                }
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
-                if(mRemoteMediaPlayers != null) {
-                    int status = msg.arg1;
-                    mRemoteMediaPlayers.getAddressedPlayer().mPlayStatus = (byte) status;
-                    if (status == AvrcpControllerConstants.PLAY_STATUS_PLAYING) {
-                        a2dpSinkService.informTGStatePlaying(mConnectedDevices.get(0), true);
-                    } else if (status == AvrcpControllerConstants.PLAY_STATUS_PAUSED ||
-                               status == AvrcpControllerConstants.PLAY_STATUS_STOPPED) {
-                        a2dpSinkService.informTGStatePlaying(mConnectedDevices.get(0), false);
-                    }
-
-                    if (mBroadcastMetadata) {
-                        broadcastPlayBackStateChanged(AvrcpUtils.mapBtPlayStatustoPlayBackState
-                                (mRemoteMediaPlayers.getAddressedPlayer().mPlayStatus,
-                                 mRemoteMediaPlayers.getAddressedPlayer().mPlayTime));
-                    } else {
-                        Log.d(TAG, "Metadata is not broadcasted, ignoring.");
-                        return;
-                    }
-                }
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_SUPPORTED_PLAYER_APP_SETTING:
-                if(mRemoteMediaPlayers != null)
-                    mRemoteMediaPlayers.getAddressedPlayer().
-                                           setSupportedPlayerAppSetting((ByteBuffer)msg.obj);
-                break;
-            case AvrcpControllerConstants.MESSAGE_PROCESS_PLAYER_APP_SETTING_CHANGED:
-                if(mRemoteMediaPlayers != null) {
-                    mRemoteMediaPlayers.getAddressedPlayer().
-                                           updatePlayerAppSetting((ByteBuffer)msg.obj);
-                    broadcastPlayerAppSettingChanged(getCurrentPlayerAppSetting());
-                }
-                break;
-            }
-        }
-    }
-
-    private void setAbsVolume(int absVol, int label)
-    {
-        int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-        int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
-        if (mAvrcpRemoteDevice.mFirstAbsVolCmdRecvd) {
-            int newIndex = (maxVolume*absVol)/AvrcpControllerConstants.ABS_VOL_BASE;
-            Log.d(TAG," setAbsVolume ="+absVol + " maxVol = " + maxVolume + " cur = " + currIndex +
-                                              " new = "+newIndex);
-            /*
-             * In some cases change in percentage is not sufficient enough to warrant
-             * change in index values which are in range of 0-15. For such cases
-             * no action is required
-             */
-            if (newIndex != currIndex) {
-                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newIndex,
-                                                     AudioManager.FLAG_SHOW_UI);
-            }
-        }
-        else {
-            mAvrcpRemoteDevice.mFirstAbsVolCmdRecvd = true;
-            absVol = (currIndex*AvrcpControllerConstants.ABS_VOL_BASE)/maxVolume;
-            Log.d(TAG," SetAbsVol recvd for first time, respond with " + absVol);
-        }
-        sendAbsVolRspNative(getByteAddress(mAvrcpRemoteDevice.mBTDevice), absVol, label);
-    }
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
-                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
-                if (streamType == AudioManager.STREAM_MUSIC) {
-                    int streamValue = intent
-                            .getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
-                    int streamPrevValue = intent.getIntExtra(
-                            AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, -1);
-                    if (streamValue != -1 && streamValue != streamPrevValue) {
-                        if ((mAvrcpRemoteDevice == null)
-                            ||((mAvrcpRemoteDevice.mRemoteFeatures &
-                                    AvrcpControllerConstants.BTRC_FEAT_ABSOLUTE_VOLUME) == 0)
-                            ||(mConnectedDevices.isEmpty()))
-                            return;
-                        if(mAvrcpRemoteDevice.mAbsVolNotificationState ==
-                                AvrcpControllerConstants.SEND_VOLUME_CHANGE_RSP) {
-                            int maxVol = mAudioManager.
-                                                  getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-                            int currIndex = mAudioManager.
-                                                  getStreamVolume(AudioManager.STREAM_MUSIC);
-                            int percentageVol = ((currIndex*
-                                            AvrcpControllerConstants.ABS_VOL_BASE)/maxVol);
-                            Log.d(TAG," Abs Vol Notify Rsp Changed vol = "+ percentageVol);
-                            sendRegisterAbsVolRspNative(getByteAddress(mAvrcpRemoteDevice.mBTDevice),
-                                (byte)AvrcpControllerConstants.NOTIFICATION_RSP_TYPE_CHANGED,
-                                    percentageVol, mAvrcpRemoteDevice.mNotificationLabel);
-                        }
-                        else if (mAvrcpRemoteDevice.mAbsVolNotificationState ==
-                                AvrcpControllerConstants.DEFER_VOLUME_CHANGE_RSP) {
-                            Log.d(TAG," Don't Complete Notification Rsp. ");
-                            mAvrcpRemoteDevice.mAbsVolNotificationState =
-                                              AvrcpControllerConstants.SEND_VOLUME_CHANGE_RSP;
-                        }
-                    }
-                }
-            }
-        }
-    };
-
-    private void handlePassthroughRsp(int id, int keyState, byte[] address) {
-        Log.d(TAG, "passthrough response received as: key: " + id + " state: " + keyState);
-    }
-
-    private void onConnectionStateChanged(boolean connected, byte[] address) {
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-            (Utils.getAddressStringFromByte(address));
-        Log.d(TAG, "onConnectionStateChanged " + connected + " " + device+ " size "+
-                    mConnectedDevices.size());
-        if (device == null)
-            return;
-        int oldState = (mConnectedDevices.contains(device) ? BluetoothProfile.STATE_CONNECTED
-                                                        : BluetoothProfile.STATE_DISCONNECTED);
-        int newState = (connected ? BluetoothProfile.STATE_CONNECTED
-                                  : BluetoothProfile.STATE_DISCONNECTED);
-
-        if (connected && oldState == BluetoothProfile.STATE_DISCONNECTED) {
-            /* AVRCPControllerService supports single connection */
-            if(mConnectedDevices.size() > 0) {
-                Log.d(TAG,"A Connection already exists, returning");
-                return;
-            }
-            mConnectedDevices.add(device);
-            Message msg =  mHandler.obtainMessage(
-                    AvrcpControllerConstants.MESSAGE_PROCESS_CONNECTION_CHANGE, newState,
-                        oldState, device);
-            mHandler.sendMessage(msg);
-        } else if (!connected && oldState == BluetoothProfile.STATE_CONNECTED) {
-            mConnectedDevices.remove(device);
-            Message msg =  mHandler.obtainMessage(
-                    AvrcpControllerConstants.MESSAGE_PROCESS_CONNECTION_CHANGE, newState,
-                        oldState, device);
-            mHandler.sendMessage(msg);
-        }
-    }
-
-    private void getRcFeatures(byte[] address, int features) {
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        Message msg = mHandler.obtainMessage(
-                AvrcpControllerConstants.MESSAGE_PROCESS_RC_FEATURES, features, 0, device);
-        mHandler.sendMessage(msg);
-    }
-    private void setPlayerAppSettingRsp(byte[] address, byte accepted) {
-              /* TODO do we need to do anything here */
-    }
-    private void handleRegisterNotificationAbsVol(byte[] address, byte label)
-    {
-        Log.d(TAG,"handleRegisterNotificationAbsVol ");
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION, label, 0);
-        mHandler.sendMessage(msg);
-    }
-
-    private void handleSetAbsVolume(byte[] address, byte absVol, byte label)
-    {
-        Log.d(TAG,"handleSetAbsVolume ");
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        Message msg = mHandler.obtainMessage(
-                AvrcpControllerConstants.MESSAGE_PROCESS_SET_ABS_VOL_CMD, absVol, label);
-        mHandler.sendMessage(msg);
-    }
-
-    private void onTrackChanged(byte[] address, byte numAttributes, int[] attributes,
-                                               String[] attribVals)
-    {
-        Log.d(TAG,"onTrackChanged ");
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        TrackInfo mTrack = new TrackInfo(0, numAttributes, attributes, attribVals);
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_TRACK_CHANGED, numAttributes, 0, mTrack);
-        mHandler.sendMessage(msg);
-    }
-
-    private void onPlayPositionChanged(byte[] address, int songLen, int currSongPosition) {
-        Log.d(TAG,"onPlayPositionChanged ");
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_PLAY_POS_CHANGED, songLen, currSongPosition);
-        mHandler.sendMessage(msg);
-    }
-
-    private void onPlayStatusChanged(byte[] address, byte playStatus) {
-        if(DBG) Log.d(TAG,"onPlayStatusChanged " + playStatus);
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_PLAY_STATUS_CHANGED, playStatus, 0);
-        mHandler.sendMessage(msg);
-    }
-
-    private void handlePlayerAppSetting(byte[] address, byte[] playerAttribRsp, int rspLen) {
-        Log.d(TAG,"handlePlayerAppSetting rspLen = " + rspLen);
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        ByteBuffer bb = ByteBuffer.wrap(playerAttribRsp, 0, rspLen);
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_SUPPORTED_PLAYER_APP_SETTING, 0, 0, bb);
-        mHandler.sendMessage(msg);
-    }
-
-    private void onPlayerAppSettingChanged(byte[] address, byte[] playerAttribRsp, int rspLen) {
-        Log.d(TAG,"onPlayerAppSettingChanged ");
-        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice
-                (Utils.getAddressStringFromByte(address));
-        if (!mConnectedDevices.contains(device))
-            return;
-        ByteBuffer bb = ByteBuffer.wrap(playerAttribRsp, 0, rspLen);
-        Message msg = mHandler.obtainMessage(AvrcpControllerConstants.
-                MESSAGE_PROCESS_PLAYER_APP_SETTING_CHANGED, 0, 0, bb);
-        mHandler.sendMessage(msg);
-    }
-
-    private void handleGroupNavigationRsp(int id, int keyState) {
-        Log.d(TAG, "group navigation response received as: key: "
-                                + id + " state: " + keyState);
-    }
-
-    private byte[] getByteAddress(BluetoothDevice device) {
-        return Utils.getBytesFromAddress(device.getAddress());
-    }
-
-    @Override
-    public void dump(StringBuilder sb) {
-        super.dump(sb);
-    }
-
-    private native static void classInitNative();
-    private native void initNative();
-    private native void cleanupNative();
-    private native boolean sendPassThroughCommandNative(byte[] address, int keyCode, int keyState);
-    private native boolean sendGroupNavigationCommandNative(byte[] address, int keyCode,
-                                                                                     int keyState);
-    private native void setPlayerApplicationSettingValuesNative(byte[] address, byte numAttrib,
-                                                    byte[] atttibIds, byte[]attribVal);
-    /* This api is used to send response to SET_ABS_VOL_CMD */
-    private native void sendAbsVolRspNative(byte[] address, int absVol, int label);
-    /* This api is used to inform remote for any volume level changes */
-    private native void sendRegisterAbsVolRspNative(byte[] address, byte rspType, int absVol,
-                                                    int label);
-}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
new file mode 100644
index 0000000..4142e63
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -0,0 +1,1095 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothAvrcpController;
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowser.MediaItem;
+import android.media.MediaDescription;
+import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.ProfileService;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application.
+ */
+public class AvrcpControllerService extends ProfileService {
+    static final String TAG = "AvrcpControllerService";
+    static final boolean DBG = true;
+    static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
+    /*
+     *  Play State Values from JNI
+     */
+    private static final byte JNI_PLAY_STATUS_STOPPED = 0x00;
+    private static final byte JNI_PLAY_STATUS_PLAYING = 0x01;
+    private static final byte JNI_PLAY_STATUS_PAUSED  = 0x02;
+    private static final byte JNI_PLAY_STATUS_FWD_SEEK = 0x03;
+    private static final byte JNI_PLAY_STATUS_REV_SEEK = 0x04;
+    private static final byte JNI_PLAY_STATUS_ERROR    = -1;
+
+    /*
+     * Browsing Media Item Attribute IDs
+     * This should be kept in sync with BTRC_MEDIA_ATTR_ID_* in bt_rc.h
+     */
+    private static final int JNI_MEDIA_ATTR_ID_INVALID = -1;
+    private static final int JNI_MEDIA_ATTR_ID_TITLE = 0x00000001;
+    private static final int JNI_MEDIA_ATTR_ID_ARTIST = 0x00000002;
+    private static final int JNI_MEDIA_ATTR_ID_ALBUM = 0x00000003;
+    private static final int JNI_MEDIA_ATTR_ID_TRACK_NUM = 0x00000004;
+    private static final int JNI_MEDIA_ATTR_ID_NUM_TRACKS = 0x00000005;
+    private static final int JNI_MEDIA_ATTR_ID_GENRE = 0x00000006;
+    private static final int JNI_MEDIA_ATTR_ID_PLAYING_TIME = 0x00000007;
+
+    /*
+     * Browsing folder types
+     * This should be kept in sync with BTRC_FOLDER_TYPE_* in bt_rc.h
+     */
+    private static final int JNI_FOLDER_TYPE_TITLES = 0x01;
+    private static final int JNI_FOLDER_TYPE_ALBUMS = 0x02;
+    private static final int JNI_FOLDER_TYPE_ARTISTS = 0x03;
+    private static final int JNI_FOLDER_TYPE_GENRES = 0x04;
+    private static final int JNI_FOLDER_TYPE_PLAYLISTS = 0x05;
+    private static final int JNI_FOLDER_TYPE_YEARS = 0x06;
+
+    /**
+     * Intent used to broadcast the change in browse connection state of the AVRCP Controller
+     * profile.
+     *
+     * <p>This intent will have 2 extras:
+     * <ul>
+     *   <li> {@link BluetoothProfile#EXTRA_STATE} - The current state of the profile. </li>
+     *   <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+     * </ul>
+     *
+     * <p>{@link #EXTRA_STATE} can be any of
+     * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+     * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+     * receive.
+     */
+    public static final String ACTION_BROWSE_CONNECTION_STATE_CHANGED =
+        "android.bluetooth.avrcp-controller.profile.action.BROWSE_CONNECTION_STATE_CHANGED";
+
+    /**
+     * intent used to broadcast the change in metadata state of playing track on the avrcp
+     * ag.
+     *
+     * <p>this intent will have the two extras:
+     * <ul>
+     *    <li> {@link #extra_metadata} - {@link mediametadata} containing the current metadata.</li>
+     *    <li> {@link #extra_playback} - {@link playbackstate} containing the current playback
+     *    state. </li>
+     * </ul>
+     */
+    public static final String ACTION_TRACK_EVENT =
+        "android.bluetooth.avrcp-controller.profile.action.TRACK_EVENT";
+
+    /**
+     * Intent used to broadcast the change of folder list.
+     *
+     * <p>This intent will have the one extra:
+     * <ul>
+     *    <li> {@link #EXTRA_FOLDER_LIST} - array of {@link MediaBrowser#MediaItem}
+     *    containing the folder listing of currently selected folder.
+     * </ul>
+     */
+    public static final String ACTION_FOLDER_LIST =
+        "android.bluetooth.avrcp-controller.profile.action.FOLDER_LIST";
+
+    public static final String EXTRA_FOLDER_LIST =
+            "android.bluetooth.avrcp-controller.profile.extra.FOLDER_LIST";
+
+    public static final String EXTRA_FOLDER_ID = "com.android.bluetooth.avrcp.EXTRA_FOLDER_ID";
+    public static final String EXTRA_FOLDER_BT_ID =
+        "com.android.bluetooth.avrcp-controller.EXTRA_FOLDER_BT_ID";
+
+    public static final String EXTRA_METADATA =
+            "android.bluetooth.avrcp-controller.profile.extra.METADATA";
+
+    public static final String EXTRA_PLAYBACK =
+            "android.bluetooth.avrcp-controller.profile.extra.PLAYBACK";
+
+    public static final String MEDIA_ITEM_UID_KEY = "media-item-uid-key";
+
+    /*
+     * KeyCoded for Pass Through Commands
+     */
+    public static final int PASS_THRU_CMD_ID_PLAY = 0x44;
+    public static final int PASS_THRU_CMD_ID_PAUSE = 0x46;
+    public static final int PASS_THRU_CMD_ID_VOL_UP = 0x41;
+    public static final int PASS_THRU_CMD_ID_VOL_DOWN = 0x42;
+    public static final int PASS_THRU_CMD_ID_STOP = 0x45;
+    public static final int PASS_THRU_CMD_ID_FF = 0x49;
+    public static final int PASS_THRU_CMD_ID_REWIND = 0x48;
+    public static final int PASS_THRU_CMD_ID_FORWARD = 0x4B;
+    public static final int PASS_THRU_CMD_ID_BACKWARD = 0x4C;
+
+    /* Key State Variables */
+    public static final int KEY_STATE_PRESSED = 0;
+    public static final int KEY_STATE_RELEASED = 1;
+
+    /* Group Navigation Key Codes */
+    public static final int PASS_THRU_CMD_ID_NEXT_GRP = 0x00;
+    public static final int PASS_THRU_CMD_ID_PREV_GRP = 0x01;
+
+    /* Folder navigation directions
+     * This is borrowed from AVRCP 1.6 spec and must be kept with same values
+     */
+    public static final int FOLDER_NAVIGATION_DIRECTION_UP = 0x00;
+    public static final int FOLDER_NAVIGATION_DIRECTION_DOWN = 0x01;
+
+    /* Folder/Media Item scopes.
+     * Keep in sync with AVRCP 1.6 sec. 6.10.1
+     */
+    public static final int BROWSE_SCOPE_PLAYER_LIST = 0x00;
+    public static final int BROWSE_SCOPE_VFS = 0x01;
+    public static final int BROWSE_SCOPE_SEARCH = 0x02;
+    public static final int BROWSE_SCOPE_NOW_PLAYING = 0x03;
+
+    private AvrcpControllerStateMachine mAvrcpCtSm;
+    private static AvrcpControllerService sAvrcpControllerService;
+    // UID size is 8 bytes (AVRCP 1.6 spec)
+    private static final byte[] EMPTY_UID = {0, 0, 0, 0, 0, 0, 0, 0};
+
+    // We only support one device.
+    private BluetoothDevice mConnectedDevice = null;
+    // If browse is supported (only valid if mConnectedDevice != null).
+    private boolean mBrowseConnected = false;
+    // Caches the current browse folder. If this is null then root is the currently browsed folder
+    // (which also has no UID).
+    private String mCurrentBrowseFolderUID = null;
+
+    static {
+        classInitNative();
+    }
+
+    public AvrcpControllerService() {
+        initNative();
+    }
+
+    protected String getName() {
+        return TAG;
+    }
+
+    protected IProfileServiceBinder initBinder() {
+        return new BluetoothAvrcpControllerBinder(this);
+    }
+
+    protected boolean start() {
+        HandlerThread thread = new HandlerThread("BluetoothAvrcpHandler");
+        thread.start();
+        mAvrcpCtSm = new AvrcpControllerStateMachine(this);
+        mAvrcpCtSm.start();
+
+        setAvrcpControllerService(this);
+        return true;
+    }
+
+    protected boolean stop() {
+        if (mAvrcpCtSm != null) {
+            mAvrcpCtSm.doQuit();
+        }
+        return true;
+    }
+
+    //API Methods
+
+    public static synchronized AvrcpControllerService getAvrcpControllerService() {
+        if (sAvrcpControllerService != null && sAvrcpControllerService.isAvailable()) {
+            if (DBG) {
+                Log.d(TAG, "getAvrcpControllerService(): returning "
+                    + sAvrcpControllerService);
+            }
+            return sAvrcpControllerService;
+        }
+        if (DBG) {
+            if (sAvrcpControllerService == null) {
+                Log.d(TAG, "getAvrcpControllerService(): service is NULL");
+            } else if (!(sAvrcpControllerService.isAvailable())) {
+                Log.d(TAG, "getAvrcpControllerService(): service is not available");
+            }
+        }
+        return null;
+    }
+
+    private static synchronized void setAvrcpControllerService(AvrcpControllerService instance) {
+        if (instance != null && instance.isAvailable()) {
+            if (DBG) {
+                Log.d(TAG, "setAvrcpControllerService(): set to: " + sAvrcpControllerService);
+            }
+            sAvrcpControllerService = instance;
+        } else {
+            if (DBG) {
+                if (instance == null) {
+                    Log.d(TAG, "setAvrcpControllerService(): service not available");
+                } else if (!instance.isAvailable()) {
+                    Log.d(TAG, "setAvrcpControllerService(): service is cleaning up");
+                }
+            }
+        }
+    }
+
+    private static synchronized void clearAvrcpControllerService() {
+        sAvrcpControllerService = null;
+    }
+
+    public synchronized List<BluetoothDevice> getConnectedDevices() {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
+        if (mConnectedDevice != null) {
+            devices.add(mConnectedDevice);
+        }
+        return devices;
+    }
+
+    /**
+     * This function only supports STATE_CONNECTED
+     */
+    public synchronized List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
+        for (int i = 0; i < states.length; i++) {
+            if (states[i] == BluetoothProfile.STATE_CONNECTED && mConnectedDevice != null) {
+                devices.add(mConnectedDevice);
+            }
+        }
+        return devices;
+    }
+
+    public synchronized int getConnectionState(BluetoothDevice device) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        return (mConnectedDevice != null ? BluetoothProfile.STATE_CONNECTED :
+            BluetoothProfile.STATE_DISCONNECTED);
+    }
+
+    public synchronized void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
+        Log.v(TAG, "sendGroupNavigationCmd keyCode: " + keyCode + " keyState: " + keyState);
+        if (device == null) {
+            Log.e(TAG, "sendGroupNavigationCmd device is null");
+        }
+
+        if (!(device.equals(mConnectedDevice))) {
+            Log.e(TAG, " Device does not match " + device + " connected " + mConnectedDevice);
+            return;
+        }
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_SEND_GROUP_NAVIGATION_CMD, keyCode, keyState, device);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public synchronized void sendPassThroughCmd(BluetoothDevice device, int keyCode, int keyState) {
+        Log.v(TAG, "sendPassThroughCmd keyCode: " + keyCode + " keyState: " + keyState);
+        if (device == null) {
+            Log.e(TAG, "sendPassThroughCmd Device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.w(TAG, " Device does not match device " + device + " conn " + mConnectedDevice);
+            return;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        Message msg = mAvrcpCtSm
+            .obtainMessage(AvrcpControllerStateMachine.MESSAGE_SEND_PASS_THROUGH_CMD,
+                keyCode, keyState, device);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public void startAvrcpUpdates() {
+        mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_START_METADATA_BROADCASTS).sendToTarget();
+    }
+
+    public void stopAvrcpUpdates() {
+        mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_STOP_METADATA_BROADCASTS).sendToTarget();
+    }
+
+    public synchronized MediaMetadata getMetaData(BluetoothDevice device) {
+        if (DBG) {
+            Log.d(TAG, "getMetaData");
+        }
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        if (device == null) {
+            Log.e(TAG, "getMetadata device is null");
+            return null;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            return null;
+        }
+        return mAvrcpCtSm.getCurrentMetaData();
+    }
+
+    public synchronized PlaybackState getPlaybackState(BluetoothDevice device) {
+        if (DBG) {
+            Log.d(TAG, "getPlayBackState device = " + device);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getPlaybackState device is null");
+            return null;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "Device " + device + " does not match connected deivce " + mConnectedDevice);
+            return null;
+
+        }
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        return mAvrcpCtSm.getCurrentPlayBackState();
+    }
+
+    public synchronized BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
+        if (DBG) {
+            Log.d(TAG, "getPlayerApplicationSetting ");
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getPlayerSettings device is null");
+            return null;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "device " + device + " does not match connected device " + mConnectedDevice);
+            return null;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        /* Do nothing */
+        return null;
+    }
+
+    public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
+        if (DBG) {
+            Log.d(TAG, "getPlayerApplicationSetting");
+        }
+
+        /* Do nothing */
+        return false;
+    }
+
+    /**
+     * Fetches the list of children for the parentID node.
+     *
+     * This function manages the overall tree for browsing structure.
+     *
+     * Arguments:
+     * device - Device to browse content for.
+     * parentMediaId - ID of the parent that we need to browse content for. Since most
+     * of the players are database unware, fetching a root invalidates all the children.
+     * start - number of item to start scanning from
+     * items - number of items to fetch
+     */
+    public synchronized void getChildren(BluetoothDevice device, String parentMediaId, int start, int items) {
+        if (DBG) {
+            Log.d(TAG, "getChildrent device = " + device + " parent " + parentMediaId);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getChildren device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "getChildren device " + device + " does not match " +
+                mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "getChildren browse not yet connected");
+            return;
+        }
+
+        if (!mAvrcpCtSm.isConnected()) {
+            return;
+        }
+        mAvrcpCtSm.getChildren(parentMediaId, start, items);
+    }
+
+    public synchronized void getNowPlayingList(BluetoothDevice device, String id, int start, int items) {
+        if (DBG) {
+            Log.d(TAG, "getNowPlayingList device = " + device + " start = " + start +
+                "items = " + items);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getNowPlayingList device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "getNowPlayingList device " + device + " does not match " + mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "getNowPlayingList browse not yet connected");
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_GET_NOW_PLAYING_LIST, start, items, id);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public synchronized void getFolderList(BluetoothDevice device, String id, int start, int items) {
+        if (DBG) {
+            Log.d(TAG, "getFolderListing device = " + device + " start = " + start +
+                "items = " + items);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getFolderListing device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "getFolderListing device " + device + " does not match " + mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "getFolderListing browse not yet connected");
+            return;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_GET_FOLDER_LIST, start, items, id);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public synchronized void getPlayerList(BluetoothDevice device, int start, int items) {
+        if (DBG) {
+            Log.d(TAG, "getPlayerList device = " + device + " start = " + start +
+                "items = " + items);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "getPlayerList device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "getPlayerList device " + device + " does not match " + mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "getPlayerList browse not yet connected");
+            return;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_GET_PLAYER_LIST, start, items);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public synchronized void changeFolderPath(
+            BluetoothDevice device, int direction, String uid, String fid) {
+        if (DBG) {
+            Log.d(TAG, "changeFolderPath device = " + device + " direction " +
+                direction + " uid " + uid);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "changeFolderPath device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "changeFolderPath device " + device + " does not match " +
+                mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "changeFolderPath browse not yet connected");
+            return;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        Bundle b = new Bundle();
+        b.putString(EXTRA_FOLDER_ID, fid);
+        b.putString(EXTRA_FOLDER_BT_ID, uid);
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_CHANGE_FOLDER_PATH, direction, 0, b);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public void setBrowsedPlayer(BluetoothDevice device, int id, String fid) {
+        if (DBG) {
+            Log.d(TAG, "setBrowsedPlayer device = " + device + " id" + id + " fid " + fid);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "setBrowsedPlayer device is null");
+            return;
+        }
+
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "setBrowsedPlayer browse not yet connected");
+            return;
+        }
+
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_SET_BROWSED_PLAYER, id, 0, fid);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    public synchronized void fetchAttrAndPlayItem(BluetoothDevice device, String uid) {
+        if (DBG) {
+            Log.d(TAG, "fetchAttrAndPlayItem device = " + device + " uid " + uid);
+        }
+
+        if (device == null) {
+            Log.e(TAG, "fetchAttrAndPlayItem device is null");
+            return;
+        }
+
+        if (!device.equals(mConnectedDevice)) {
+            Log.e(TAG, "fetchAttrAndPlayItem device " + device + " does not match " +
+                mConnectedDevice);
+            return;
+        }
+
+        if (!mBrowseConnected) {
+            Log.e(TAG, "fetchAttrAndPlayItem browse not yet connected");
+            return;
+        }
+        mAvrcpCtSm.fetchAttrAndPlayItem(uid);
+    }
+
+    //Binder object: Must be static class or memory leak may occur
+    private static class BluetoothAvrcpControllerBinder extends IBluetoothAvrcpController.Stub
+        implements IProfileServiceBinder {
+
+        private AvrcpControllerService mService;
+
+        private AvrcpControllerService getService() {
+            if (!Utils.checkCaller()) {
+                Log.w(TAG, "AVRCP call not allowed for non-active user");
+                return null;
+            }
+
+            if (mService != null && mService.isAvailable()) {
+                return mService;
+            }
+            return null;
+        }
+
+        BluetoothAvrcpControllerBinder(AvrcpControllerService svc) {
+            mService = svc;
+        }
+
+        public boolean cleanup() {
+            mService = null;
+            return true;
+        }
+
+        @Override
+        public List<BluetoothDevice> getConnectedDevices() {
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return new ArrayList<BluetoothDevice>(0);
+            }
+            return service.getConnectedDevices();
+        }
+
+        @Override
+        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return new ArrayList<BluetoothDevice>(0);
+            }
+            return service.getDevicesMatchingConnectionStates(states);
+        }
+
+        @Override
+        public int getConnectionState(BluetoothDevice device) {
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+
+            if (device == null) {
+              throw new IllegalStateException("Device cannot be null!");
+            }
+
+            return service.getConnectionState(device);
+        }
+
+        @Override
+        public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
+            Log.v(TAG, "Binder Call: sendGroupNavigationCmd");
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return;
+            }
+
+            if (device == null) {
+              throw new IllegalStateException("Device cannot be null!");
+            }
+
+            service.sendGroupNavigationCmd(device, keyCode, keyState);
+        }
+
+        @Override
+        public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
+            Log.v(TAG, "Binder Call: getPlayerApplicationSetting ");
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return null;
+            }
+
+            if (device == null) {
+              throw new IllegalStateException("Device cannot be null!");
+            }
+
+            return service.getPlayerSettings(device);
+        }
+
+        @Override
+        public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
+            Log.v(TAG, "Binder Call: setPlayerApplicationSetting ");
+            AvrcpControllerService service = getService();
+            if (service == null) {
+                return false;
+            }
+            return service.setPlayerApplicationSetting(plAppSetting);
+        }
+    }
+
+    // Called by JNI when a passthrough key was received.
+    private void handlePassthroughRsp(int id, int keyState) {
+        Log.d(TAG, "passthrough response received as: key: " + id + " state: " +
+            keyState);
+    }
+
+    private void handleGroupNavigationRsp(int id, int keyState) {
+        Log.d(TAG, "group navigation response received as: key: " + id + " state: " +
+            keyState);
+    }
+
+    // Called by JNI when a device has connected or disconnected.
+    private synchronized void onConnectionStateChanged(
+            boolean rc_connected, boolean br_connected, byte[] address) {
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        Log.d(TAG, "onConnectionStateChanged " + rc_connected + " " + br_connected +
+            device + " conn device " + mConnectedDevice);
+        if (device == null) {
+            Log.e(TAG, "onConnectionStateChanged Device is null");
+            return;
+        }
+
+        // Adjust the AVRCP connection state.
+        int oldState = (device.equals(mConnectedDevice) ? BluetoothProfile.STATE_CONNECTED :
+            BluetoothProfile.STATE_DISCONNECTED);
+        int newState = (rc_connected ? BluetoothProfile.STATE_CONNECTED :
+            BluetoothProfile.STATE_DISCONNECTED);
+
+        if (rc_connected && oldState == BluetoothProfile.STATE_DISCONNECTED) {
+            /* AVRCPControllerService supports single connection */
+            if (mConnectedDevice != null) {
+                Log.d(TAG, "A Connection already exists, returning");
+                return;
+            }
+            mConnectedDevice = device;
+            Message msg = mAvrcpCtSm.obtainMessage(
+                AvrcpControllerStateMachine.MESSAGE_PROCESS_CONNECTION_CHANGE, newState,
+                oldState, device);
+            mAvrcpCtSm.sendMessage(msg);
+        } else if (!rc_connected && oldState == BluetoothProfile.STATE_CONNECTED) {
+            mConnectedDevice = null;
+            Message msg = mAvrcpCtSm.obtainMessage(
+                AvrcpControllerStateMachine.MESSAGE_PROCESS_CONNECTION_CHANGE, newState,
+                oldState, device);
+            mAvrcpCtSm.sendMessage(msg);
+        }
+
+        // Adjust the browse connection state. If RC is connected we should have already sent the
+        // connection status out.
+        if (rc_connected && br_connected) {
+            mBrowseConnected = true;
+            Message msg = mAvrcpCtSm.obtainMessage(
+               AvrcpControllerStateMachine.MESSAGE_PROCESS_BROWSE_CONNECTION_CHANGE);
+            msg.arg1 = 1;
+            msg.obj = device;
+            mAvrcpCtSm.sendMessage(msg);
+        }
+    }
+
+    // Called by JNI to notify Avrcp of features supported by the Remote device.
+    private void getRcFeatures(byte[] address, int features) {
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_PROCESS_RC_FEATURES, features, 0, device);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI
+    private void setPlayerAppSettingRsp(byte[] address, byte accepted) {
+              /* Do Nothing. */
+    }
+
+    // Called by JNI when remote wants to receive absolute volume notifications.
+    private synchronized void handleRegisterNotificationAbsVol(byte[] address, byte label) {
+        Log.d(TAG, "handleRegisterNotificationAbsVol ");
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "handleRegisterNotificationAbsVol device not found " + address);
+            return;
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION, (int) label, 0);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI when remote wants to set absolute volume.
+    private synchronized void handleSetAbsVolume(byte[] address, byte absVol, byte label) {
+        Log.d(TAG, "handleSetAbsVolume ");
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "handleSetAbsVolume device not found " + address);
+            return;
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_ABS_VOL_CMD, absVol, label);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI when a track changes and local AvrcpController is registered for updates.
+    private synchronized void onTrackChanged(byte[] address, byte numAttributes, int[] attributes,
+        String[] attribVals) {
+        if (DBG) {
+            Log.d(TAG, "onTrackChanged");
+        }
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "onTrackChanged device not found " + address);
+            return;
+        }
+
+        List<Integer> attrList = new ArrayList<>();
+        for (int attr : attributes) {
+            attrList.add(attr);
+        }
+        List<String> attrValList = Arrays.asList(attribVals);
+        TrackInfo trackInfo = new TrackInfo(attrList, attrValList);
+        if (DBG) {
+            Log.d(TAG, "onTrackChanged " + trackInfo);
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_TRACK_CHANGED, trackInfo);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI periodically based upon timer to update play position
+    private synchronized void onPlayPositionChanged(byte[] address, int songLen, int currSongPosition) {
+        if (DBG) {
+            Log.d(TAG, "onPlayPositionChanged pos " + currSongPosition);
+        }
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "onPlayPositionChanged not found device not found " + address);
+            return;
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_PLAY_POS_CHANGED, songLen, currSongPosition);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI on changes of play status
+    private synchronized void onPlayStatusChanged(byte[] address, byte playStatus) {
+        if (DBG) {
+            Log.d(TAG, "onPlayStatusChanged " + playStatus);
+        }
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "onPlayStatusChanged not found device not found " + address);
+            return;
+        }
+        int playbackState = PlaybackState.STATE_NONE;
+        switch (playStatus) {
+            case JNI_PLAY_STATUS_STOPPED:
+                playbackState =  PlaybackState.STATE_STOPPED;
+                break;
+            case JNI_PLAY_STATUS_PLAYING:
+                playbackState =  PlaybackState.STATE_PLAYING;
+                break;
+            case JNI_PLAY_STATUS_PAUSED:
+                playbackState = PlaybackState.STATE_PAUSED;
+                break;
+            case JNI_PLAY_STATUS_FWD_SEEK:
+                playbackState = PlaybackState.STATE_FAST_FORWARDING;
+                break;
+            case JNI_PLAY_STATUS_REV_SEEK:
+                playbackState = PlaybackState.STATE_FAST_FORWARDING;
+                break;
+            default:
+                playbackState = PlaybackState.STATE_NONE;
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_PLAY_STATUS_CHANGED, playbackState);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // Called by JNI to report remote Player's capabilities
+    private synchronized void handlePlayerAppSetting(byte[] address, byte[] playerAttribRsp, int rspLen) {
+        if (DBG) {
+            Log.d(TAG, "handlePlayerAppSetting rspLen = " + rspLen);
+        }
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "handlePlayerAppSetting not found device not found " + address);
+            return;
+        }
+        PlayerApplicationSettings supportedSettings = PlayerApplicationSettings.
+            makeSupportedSettings(playerAttribRsp);
+        /* Do nothing */
+    }
+
+    private synchronized void onPlayerAppSettingChanged(byte[] address, byte[] playerAttribRsp, int rspLen) {
+        if (DBG) {
+            Log.d(TAG, "onPlayerAppSettingChanged ");
+        }
+        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
+        if (device != null && !device.equals(mConnectedDevice)) {
+            Log.e(TAG, "onPlayerAppSettingChanged not found device not found " + address);
+            return;
+        }
+        PlayerApplicationSettings desiredSettings = PlayerApplicationSettings.
+            makeSettings(playerAttribRsp);
+        /* Do nothing */
+    }
+
+    // Browsing related JNI callbacks.
+    void handleGetFolderItemsRsp(MediaItem[] items) {
+        if (DBG) {
+            Log.d(TAG, "handleGetFolderItemsRsp called with " + items.length + " items.");
+        }
+        for (MediaItem item : items) {
+            if (DBG) {
+                Log.d(TAG, "media item: " + item + " uid: " + item.getDescription().getMediaId());
+            }
+        }
+        ArrayList<MediaItem> itemsList = new ArrayList<>();
+        for (MediaItem item : items) {
+            itemsList.add(item);
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_GET_FOLDER_ITEMS, itemsList);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    void handleGetPlayerItemsRsp(AvrcpPlayer[] items) {
+        if (DBG) {
+            Log.d(TAG, "handleGetFolderItemsRsp called with " + items.length + " items.");
+        }
+        for (AvrcpPlayer item : items) {
+            if (DBG) {
+                Log.d(TAG, "bt player item: " + item);
+            }
+        }
+        List<AvrcpPlayer> itemsList = new ArrayList<>();
+        for (AvrcpPlayer p : items) {
+            itemsList.add(p);
+        }
+
+        Message msg = mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.
+            MESSAGE_PROCESS_GET_PLAYER_ITEMS, itemsList);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    // JNI Helper functions to convert native objects to java.
+    MediaItem createFromNativeMediaItem(
+            byte[] uid, int type, String name, int[] attrIds, String[] attrVals) {
+        if (DBG) {
+            Log.d(TAG, "createFromNativeMediaItem uid: " + uid + " type " + type + " name " +
+                name + " attrids " + attrIds + " attrVals " + attrVals);
+        }
+        MediaDescription.Builder mdb = new MediaDescription.Builder();
+
+        Bundle mdExtra = new Bundle();
+        mdExtra.putString(MEDIA_ITEM_UID_KEY, byteUIDToHexString(uid));
+        mdb.setExtras(mdExtra);
+
+        // Generate a random UUID. We do this since database unaware TGs can send multiple
+        // items with same MEDIA_ITEM_UID_KEY.
+        mdb.setMediaId(UUID.randomUUID().toString());
+
+        // Concise readable name.
+        mdb.setTitle(name);
+
+        // We skip the attributes since we can query them using UID for the item above
+        // Also MediaDescription does not give an easy way to provide this unless we pass
+        // it as an MediaMetadata which is put inside the extras.
+        return new MediaItem(mdb.build(), MediaItem.FLAG_PLAYABLE);
+    }
+
+    MediaItem createFromNativeFolderItem(
+            byte[] uid, int type, String name, int playable) {
+        if (DBG) {
+            Log.d(TAG, "createFromNativeFolderItem uid: " + uid + " type " + type +
+                " name " + name + " playable " + playable);
+        }
+        MediaDescription.Builder mdb = new MediaDescription.Builder();
+
+        // Covert the byte to a hex string. The coversion can be done back here to a
+        // byte array when needed.
+        Bundle mdExtra = new Bundle();
+        mdExtra.putString(MEDIA_ITEM_UID_KEY, byteUIDToHexString(uid));
+        mdb.setExtras(mdExtra);
+
+        // Generate a random UUID. We do this since database unaware TGs can send multiple
+        // items with same MEDIA_ITEM_UID_KEY.
+        mdb.setMediaId(UUID.randomUUID().toString());
+
+        // Concise readable name.
+        mdb.setTitle(name);
+
+        return new MediaItem(mdb.build(), MediaItem.FLAG_BROWSABLE);
+    }
+
+    AvrcpPlayer createFromNativePlayerItem(
+            int id, String name, byte[] transportFlags, int playStatus, int playerType) {
+        if (DBG) {
+            Log.d(TAG, "createFromNativePlayerItem name: " + name + " transportFlags " +
+                transportFlags + " play status " + playStatus + " player type " +
+                playerType);
+        }
+        AvrcpPlayer player = new AvrcpPlayer(id, name, 0, playStatus, playerType);
+        return player;
+    }
+
+    private void handleChangeFolderRsp(int count) {
+        if (DBG) {
+            Log.d(TAG, "handleChangeFolderRsp count: " + count);
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_PROCESS_FOLDER_PATH, count);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    private void handleSetBrowsedPlayerRsp(int items, int depth) {
+        if (DBG) {
+            Log.d(TAG, "handleSetBrowsedPlayerRsp depth: " + depth);
+        }
+        Message msg = mAvrcpCtSm.obtainMessage(
+            AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_BROWSED_PLAYER, items, depth);
+        mAvrcpCtSm.sendMessage(msg);
+    }
+
+    @Override
+    public void dump(StringBuilder sb) {
+        super.dump(sb);
+        mAvrcpCtSm.dump(sb);
+    }
+
+    public static String byteUIDToHexString(byte[] uid) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b : uid) {
+            sb.append(String.format("%02X", b));
+        }
+        return sb.toString();
+    }
+
+    public static byte[] hexStringToByteUID(String uidStr) {
+        if (uidStr == null) {
+            Log.e(TAG, "Null hex string.");
+            return EMPTY_UID;
+        } else if (uidStr.length() % 2 == 1) {
+            // Odd length strings should not be possible.
+            Log.e(TAG, "Odd length hex string " + uidStr);
+            return EMPTY_UID;
+        }
+        int len = uidStr.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+          data[i / 2] = (byte) ((Character.digit(uidStr.charAt(i), 16) << 4)
+              + Character.digit(uidStr.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+    private native static void classInitNative();
+
+    private native void initNative();
+
+    private native void cleanupNative();
+
+    native static boolean sendPassThroughCommandNative(byte[] address, int keyCode, int keyState);
+
+    native static boolean sendGroupNavigationCommandNative(byte[] address, int keyCode,
+        int keyState);
+
+    native static void setPlayerApplicationSettingValuesNative(byte[] address, byte numAttrib,
+        byte[] atttibIds, byte[] attribVal);
+
+    /* This api is used to send response to SET_ABS_VOL_CMD */
+    native static void sendAbsVolRspNative(byte[] address, int absVol, int label);
+
+    /* This api is used to inform remote for any volume level changes */
+    native static void sendRegisterAbsVolRspNative(byte[] address, byte rspType, int absVol,
+        int label);
+
+    /* API used to fetch the current now playing list */
+    native static void getNowPlayingListNative(byte[] address, byte start, byte items);
+    /* API used to fetch the current folder's listing */
+    native static void getFolderListNative(byte[] address, byte start, byte items);
+    /* API used to fetch the listing of players */
+    native static void getPlayerListNative(byte[] address, byte start, byte items);
+    /* API used to change the folder */
+    native static void changeFolderPathNative(byte[] address, byte direction, byte[] uid);
+    native static void playItemNative(
+        byte[] address, byte scope, byte[] uid, int uidCounter);
+    native static void setBrowsedPlayerNative(byte[] address, int playerId);
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
new file mode 100644
index 0000000..874512b
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -0,0 +1,1019 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAvrcpController;
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowser.MediaItem;
+import android.media.MediaDescription;
+import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.a2dpsink.A2dpSinkService;
+import com.android.bluetooth.btservice.ProfileService;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * Provides Bluetooth AVRCP Controller State Machine responsible for all remote control connections
+ * and interactions with a remote controlable device.
+ */
+class AvrcpControllerStateMachine extends StateMachine {
+
+    // commands from Binder service
+    static final int MESSAGE_SEND_PASS_THROUGH_CMD = 1;
+    static final int MESSAGE_SEND_GROUP_NAVIGATION_CMD = 3;
+    static final int MESSAGE_GET_NOW_PLAYING_LIST = 5;
+    static final int MESSAGE_GET_FOLDER_LIST = 6;
+    static final int MESSAGE_GET_PLAYER_LIST = 7;
+    static final int MESSAGE_CHANGE_FOLDER_PATH = 8;
+    static final int MESSAGE_FETCH_ATTR_AND_PLAY_ITEM = 9;
+    static final int MESSAGE_SET_BROWSED_PLAYER = 10;
+
+    // commands from native layer
+    static final int MESSAGE_PROCESS_SET_ABS_VOL_CMD = 103;
+    static final int MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION = 104;
+    static final int MESSAGE_PROCESS_TRACK_CHANGED = 105;
+    static final int MESSAGE_PROCESS_PLAY_POS_CHANGED = 106;
+    static final int MESSAGE_PROCESS_PLAY_STATUS_CHANGED = 107;
+    static final int MESSAGE_PROCESS_VOLUME_CHANGED_NOTIFICATION = 108;
+    static final int MESSAGE_PROCESS_GET_FOLDER_ITEMS = 109;
+    static final int MESSAGE_PROCESS_GET_PLAYER_ITEMS = 110;
+    static final int MESSAGE_PROCESS_FOLDER_PATH = 111;
+    static final int MESSAGE_PROCESS_SET_BROWSED_PLAYER = 113;
+
+    // commands from A2DP sink
+    static final int MESSAGE_STOP_METADATA_BROADCASTS = 201;
+    static final int MESSAGE_START_METADATA_BROADCASTS = 202;
+
+    // commands for connection
+    static final int MESSAGE_PROCESS_RC_FEATURES = 301;
+    static final int MESSAGE_PROCESS_CONNECTION_CHANGE = 302;
+    static final int MESSAGE_PROCESS_BROWSE_CONNECTION_CHANGE = 303;
+
+    // Interal messages
+    static final int MESSAGE_INTERNAL_BROWSE_DEPTH_INCREMENT = 401;
+    static final int MESSAGE_INTERNAL_MOVE_N_LEVELS_UP = 402;
+    static final int MESSAGE_INTERNAL_CMD_TIMEOUT = 403;
+
+    static final int CMD_TIMEOUT_MILLIS = 5000; // 5s
+
+    /*
+     * Base value for absolute volume from JNI
+     */
+    private static final int ABS_VOL_BASE = 127;
+
+    /*
+     * Notification types for Avrcp protocol JNI.
+     */
+    private static final byte NOTIFICATION_RSP_TYPE_INTERIM = 0x00;
+    private static final byte NOTIFICATION_RSP_TYPE_CHANGED = 0x01;
+
+
+    private static final String TAG = "AvrcpControllerSM";
+    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
+
+    private final Context mContext;
+    private final AudioManager mAudioManager;
+
+    private final State mDisconnected;
+    private final State mConnected;
+    private final SetBrowsedPlayer mSetBrowsedPlayer;
+    private final ChangeFolderPath mChangeFolderPath;
+    private final GetFolderList mGetFolderListing;
+    private final GetPlayerListing mGetPlayerListing;
+    private final GetNowPlayingList mGetNowPlayingList;
+    private final MoveToRoot mMoveToRoot;
+
+    private final Object mLock = new Object();
+    private static final ArrayList<MediaItem> mEmptyMediaItemList = new ArrayList<>();
+    private static final MediaMetadata mEmptyMMD = new MediaMetadata.Builder().build();
+
+    // APIs exist to access these so they must be thread safe
+    private Boolean mIsConnected = false;
+    private RemoteDevice mRemoteDevice;
+    private AvrcpPlayer mAddressedPlayer;
+
+    // Only accessed from State Machine processMessage
+    private boolean mAbsoluteVolumeChangeInProgress = false;
+    private boolean mBroadcastMetadata = false;
+    private int previousPercentageVol = -1;
+
+    // New addressed player.
+    private String mCurrentPlayer = null;
+
+    // Depth from root of current browsing. This can be used to move to root directly.
+    // Only valid if mCurrentPlayer != null.
+    private int mBrowseDepth = 0;
+
+    // Browse tree.
+    private BrowseTree mBrowseTree = new BrowseTree();
+
+    AvrcpControllerStateMachine(Context context) {
+        super(TAG);
+        mContext = context;
+
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        mDisconnected = new Disconnected();
+        mConnected = new Connected();
+
+        // Used to change folder path and fetch the new folder listing.
+        mSetBrowsedPlayer = new SetBrowsedPlayer();
+        mChangeFolderPath = new ChangeFolderPath();
+        mGetFolderListing = new GetFolderList();
+        mGetPlayerListing = new GetPlayerListing();
+        mGetNowPlayingList = new GetNowPlayingList();
+        mMoveToRoot = new MoveToRoot();
+
+        addState(mDisconnected);
+        addState(mConnected);
+
+        // Any action that needs blocking other requests to the state machine will be implemented as
+        // a separate substate of the mConnected state. Once transtition to the sub-state we should
+        // only handle the messages that are relevant to the sub-action. Everything else should be
+        // deferred so that once we transition to the mConnected we can process them hence.
+        addState(mSetBrowsedPlayer, mConnected);
+        addState(mChangeFolderPath, mConnected);
+        addState(mGetFolderListing, mConnected);
+        addState(mGetPlayerListing, mConnected);
+        addState(mGetNowPlayingList, mConnected);
+        addState(mMoveToRoot, mConnected);
+
+        setInitialState(mDisconnected);
+    }
+
+    class Disconnected extends State {
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(TAG, " HandleMessage: " + dumpMessageString(msg.what));
+            switch (msg.what) {
+                case MESSAGE_PROCESS_CONNECTION_CHANGE:
+                    if (msg.arg1 == BluetoothProfile.STATE_CONNECTED) {
+                        transitionTo(mConnected);
+                        BluetoothDevice rtDevice = (BluetoothDevice) msg.obj;
+                        synchronized(mLock) {
+                            mRemoteDevice = new RemoteDevice(rtDevice);
+                            mAddressedPlayer = new AvrcpPlayer();
+                            mIsConnected = true;
+                        }
+                        Intent intent = new Intent(
+                            BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);
+                        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
+                            BluetoothProfile.STATE_DISCONNECTED);
+                        intent.putExtra(BluetoothProfile.EXTRA_STATE,
+                            BluetoothProfile.STATE_CONNECTED);
+                        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, rtDevice);
+                        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+                    }
+                    break;
+
+                default:
+                    Log.w(TAG,"Currently Disconnected not handling " + dumpMessageString(msg.what));
+                    return false;
+            }
+            return true;
+        }
+    }
+
+    class Connected extends State {
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(TAG, " HandleMessage: " + dumpMessageString(msg.what));
+            A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
+            synchronized (mLock) {
+                switch (msg.what) {
+                    case MESSAGE_STOP_METADATA_BROADCASTS:
+                        mBroadcastMetadata = false;
+                        broadcastPlayBackStateChanged(new PlaybackState.Builder().setState(
+                            PlaybackState.STATE_PAUSED, mAddressedPlayer.getPlayTime(),
+                            0).build());
+                        break;
+
+                    case MESSAGE_START_METADATA_BROADCASTS:
+                        mBroadcastMetadata = true;
+                        broadcastPlayBackStateChanged(mAddressedPlayer.getPlaybackState());
+                        if (mAddressedPlayer.getCurrentTrack() != null) {
+                            broadcastMetaDataChanged(
+                                mAddressedPlayer.getCurrentTrack().getMediaMetaData());
+                        }
+                        break;
+
+                    case MESSAGE_SEND_PASS_THROUGH_CMD:
+                        BluetoothDevice device = (BluetoothDevice) msg.obj;
+                        AvrcpControllerService
+                            .sendPassThroughCommandNative(Utils.getByteAddress(device), msg.arg1,
+                                msg.arg2);
+                        if (a2dpSinkService != null) {
+                            Log.d(TAG, " inform AVRCP Commands to A2DP Sink ");
+                            a2dpSinkService.informAvrcpPassThroughCmd(device, msg.arg1, msg.arg2);
+                        }
+                        break;
+
+                    case MESSAGE_SEND_GROUP_NAVIGATION_CMD:
+                        AvrcpControllerService.sendGroupNavigationCommandNative(
+                            mRemoteDevice.getBluetoothAddress(), msg.arg1, msg.arg2);
+                        break;
+
+                    case MESSAGE_GET_NOW_PLAYING_LIST:
+                        AvrcpControllerService.getNowPlayingListNative(
+                            mRemoteDevice.getBluetoothAddress(), (byte) msg.arg1,
+                            (byte) msg.arg2);
+                        mGetNowPlayingList.setFolder((String) msg.obj);
+                        transitionTo(mGetNowPlayingList);
+                        break;
+
+                    case MESSAGE_GET_FOLDER_LIST:
+                        AvrcpControllerService.getFolderListNative(
+                            mRemoteDevice.getBluetoothAddress(), (byte) msg.arg1,
+                            (byte) msg.arg2);
+
+                        // Whenever we transition we set the information for folder we need to
+                        // return result.
+                        mGetFolderListing.setFolder((String) msg.obj);
+                        transitionTo(mGetFolderListing);
+                        sendMessageDelayed(MESSAGE_INTERNAL_CMD_TIMEOUT, CMD_TIMEOUT_MILLIS);
+                        break;
+
+                    case MESSAGE_GET_PLAYER_LIST:
+                        AvrcpControllerService.getPlayerListNative(
+                            mRemoteDevice.getBluetoothAddress(), (byte) msg.arg1,
+                            (byte) msg.arg2);
+                        transitionTo(mGetPlayerListing);
+                        sendMessageDelayed(MESSAGE_INTERNAL_CMD_TIMEOUT, CMD_TIMEOUT_MILLIS);
+                        break;
+
+                    case MESSAGE_CHANGE_FOLDER_PATH: {
+                        int direction = msg.arg1;
+                        Bundle b = (Bundle) msg.obj;
+                        String uid = b.getString(AvrcpControllerService.EXTRA_FOLDER_BT_ID);
+                        String fid = b.getString(AvrcpControllerService.EXTRA_FOLDER_ID);
+
+                        // String is encoded as a Hex String (mostly for display purposes)
+                        // hence convert this back to real byte string.
+                        AvrcpControllerService.changeFolderPathNative(
+                            mRemoteDevice.getBluetoothAddress(), (byte) msg.arg1,
+                            AvrcpControllerService.hexStringToByteUID(uid));
+                        mChangeFolderPath.setFolder(fid);
+                        transitionTo(mChangeFolderPath);
+                        sendMessage(MESSAGE_INTERNAL_BROWSE_DEPTH_INCREMENT, (byte) msg.arg1);
+                        sendMessageDelayed(MESSAGE_INTERNAL_CMD_TIMEOUT, CMD_TIMEOUT_MILLIS);
+                        break;
+                    }
+
+                    case MESSAGE_FETCH_ATTR_AND_PLAY_ITEM: {
+                        int scope = msg.arg1;
+                        String uid = (String) msg.obj;
+                        // String is encoded as a Hex String (mostly for display purposes)
+                        // hence convert this back to real byte string.
+                        AvrcpControllerService.playItemNative(
+                            mRemoteDevice.getBluetoothAddress(), (byte) msg.arg1,
+                            AvrcpControllerService.hexStringToByteUID(uid), (int) 0);
+                        break;
+                    }
+
+                    case MESSAGE_SET_BROWSED_PLAYER: {
+                        AvrcpControllerService.setBrowsedPlayerNative(
+                            mRemoteDevice.getBluetoothAddress(), (int) msg.arg1);
+                        mSetBrowsedPlayer.setFolder((String) msg.obj);
+                        transitionTo(mSetBrowsedPlayer);
+                        break;
+                    }
+
+                    case MESSAGE_PROCESS_CONNECTION_CHANGE:
+                        if (msg.arg1 == BluetoothProfile.STATE_DISCONNECTED) {
+                            synchronized (mLock) {
+                                mIsConnected = false;
+                                mRemoteDevice = null;
+                            }
+                            transitionTo(mDisconnected);
+                            BluetoothDevice rtDevice = (BluetoothDevice) msg.obj;
+                            Intent intent = new Intent(
+                                BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED);
+                            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
+                                BluetoothProfile.STATE_CONNECTED);
+                            intent.putExtra(BluetoothProfile.EXTRA_STATE,
+                                BluetoothProfile.STATE_DISCONNECTED);
+                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, rtDevice);
+                            mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+                        }
+                        break;
+
+                    case MESSAGE_PROCESS_BROWSE_CONNECTION_CHANGE:
+                        // Service tells us if the browse is connected or disconnected.
+                        // This is useful only for deciding whether to send browse commands rest of
+                        // the connection state handling should be done via the message
+                        // MESSAGE_PROCESS_CONNECTION_CHANGE.
+                        Intent intent = new Intent(
+                            AvrcpControllerService.ACTION_BROWSE_CONNECTION_STATE_CHANGED);
+                        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, (BluetoothDevice) msg.obj);
+                        if (DBG) {
+                            Log.d(TAG, "Browse connection state " + msg.arg1);
+                        }
+                        if (msg.arg1 == 1) {
+                            intent.putExtra(
+                                BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+                        } else if (msg.arg1 == 0) {
+                            intent.putExtra(
+                                BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED);
+                            // If browse is disconnected, the next time we connect we should
+                            // be at the ROOT.
+                            mBrowseDepth = 0;
+                        } else {
+                            Log.w(TAG, "Incorrect browse state " + msg.arg1);
+                        }
+
+                        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+                        break;
+
+                    case MESSAGE_PROCESS_RC_FEATURES:
+                        mRemoteDevice.setRemoteFeatures(msg.arg1);
+                        break;
+
+                    case MESSAGE_PROCESS_SET_ABS_VOL_CMD:
+                        mAbsoluteVolumeChangeInProgress = true;
+                        setAbsVolume(msg.arg1, msg.arg2);
+                        break;
+
+                    case MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION: {
+                        mRemoteDevice.setNotificationLabel(msg.arg1);
+                        mRemoteDevice.setAbsVolNotificationRequested(true);
+                        int percentageVol = getVolumePercentage();
+                        Log.d(TAG,
+                            " Sending Interim Response = " + percentageVol + " label " + msg.arg1);
+                        AvrcpControllerService
+                            .sendRegisterAbsVolRspNative(mRemoteDevice.getBluetoothAddress(),
+                                NOTIFICATION_RSP_TYPE_INTERIM,
+                                percentageVol,
+                                mRemoteDevice.getNotificationLabel());
+                    }
+                    break;
+
+                    case MESSAGE_PROCESS_VOLUME_CHANGED_NOTIFICATION: {
+                        if (mAbsoluteVolumeChangeInProgress) {
+                            mAbsoluteVolumeChangeInProgress = false;
+                        } else {
+                            if (mRemoteDevice.getAbsVolNotificationRequested()) {
+                                int percentageVol = getVolumePercentage();
+                                if (percentageVol != previousPercentageVol) {
+                                    AvrcpControllerService.sendRegisterAbsVolRspNative(
+                                        mRemoteDevice.getBluetoothAddress(),
+                                        NOTIFICATION_RSP_TYPE_CHANGED,
+                                        percentageVol, mRemoteDevice.getNotificationLabel());
+                                    previousPercentageVol = percentageVol;
+                                    mRemoteDevice.setAbsVolNotificationRequested(false);
+                                }
+                            }
+                        }
+                    }
+                    break;
+
+                    case MESSAGE_PROCESS_TRACK_CHANGED:
+                        mAddressedPlayer.updateCurrentTrack((TrackInfo) msg.obj);
+                        if (mBroadcastMetadata) {
+                            broadcastMetaDataChanged(mAddressedPlayer.getCurrentTrack().
+                                getMediaMetaData());
+                        }
+                        break;
+
+                    case MESSAGE_PROCESS_PLAY_POS_CHANGED:
+                        mAddressedPlayer.setPlayTime(msg.arg2);
+                        if (mBroadcastMetadata) {
+                            broadcastPlayBackStateChanged(getCurrentPlayBackState());
+                        }
+                        break;
+
+                    case MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
+                        int status = msg.arg1;
+                        mAddressedPlayer.setPlayStatus(status);
+                        if (status == PlaybackState.STATE_PLAYING) {
+                            a2dpSinkService.informTGStatePlaying(mRemoteDevice.mBTDevice, true);
+                        } else if (status == PlaybackState.STATE_PAUSED ||
+                            status == PlaybackState.STATE_STOPPED) {
+                            a2dpSinkService.informTGStatePlaying(mRemoteDevice.mBTDevice, false);
+                        }
+                        break;
+
+                    default:
+                        return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    // Handle the change folder path meta-action.
+    // a) Send Change folder command
+    // b) Once successful transition to folder fetch state.
+    class ChangeFolderPath extends CmdState {
+        private String STATE_TAG = "AVRCPSM.ChangeFolderPath";
+        private int mTmpIncrDirection;
+        private String mID = "";
+
+        public void setFolder(String id) {
+            mID = id;
+        }
+
+        @Override
+        public void enter() {
+            super.enter();
+            mTmpIncrDirection = -1;
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg);
+            switch (msg.what) {
+                case MESSAGE_INTERNAL_BROWSE_DEPTH_INCREMENT:
+                    mTmpIncrDirection = msg.arg1;
+                    break;
+
+                case MESSAGE_PROCESS_FOLDER_PATH: {
+                    // Fetch the listing of objects in this folder.
+                    Log.d(STATE_TAG, "MESSAGE_PROCESS_FOLDER_PATH returned " + msg.arg1 +
+                        " elements");
+
+                    // Update the folder depth.
+                    if (mTmpIncrDirection ==
+                        AvrcpControllerService.FOLDER_NAVIGATION_DIRECTION_UP) {
+                        mBrowseDepth -= 1;;
+                    } else if (mTmpIncrDirection ==
+                        AvrcpControllerService.FOLDER_NAVIGATION_DIRECTION_DOWN) {
+                        mBrowseDepth += 1;
+                    } else {
+                        throw new IllegalStateException("incorrect nav " + mTmpIncrDirection);
+                    }
+                    Log.d(STATE_TAG, "New browse depth " + mBrowseDepth);
+
+                    if (msg.arg1 > 0) {
+                        sendMessage(MESSAGE_GET_FOLDER_LIST, 0, 0xff, mID);
+                    } else {
+                        // Return an empty response to the upper layer.
+                        broadcastFolderList(mID, mEmptyMediaItemList);
+                    }
+                    mBrowseTree.setCurrentBrowsedFolder(mID);
+                    transitionTo(mConnected);
+                    break;
+                }
+
+                case MESSAGE_INTERNAL_CMD_TIMEOUT:
+                    // We timed out changing folders. It is imperative we tell
+                    // the upper layers that we failed by giving them an empty list.
+                    Log.e(STATE_TAG, "change folder failed, sending empty list.");
+                    broadcastFolderList(mID, mEmptyMediaItemList);
+                    transitionTo(mConnected);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to Connected state.");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    // Handle the get folder listing action
+    // a) Fetch the listing of folders
+    // b) Once completed return the object listing
+    class GetFolderList extends CmdState {
+        private String STATE_TAG = "AVRCPSM.GetFolderList";
+
+        String mID = "";
+
+        public void setFolder(String id) {
+            Log.d(STATE_TAG, "Setting folder to " + id);
+            mID = id;
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg);
+            switch (msg.what) {
+                case MESSAGE_PROCESS_GET_FOLDER_ITEMS:
+                    ArrayList<MediaItem> folderList = (ArrayList<MediaItem>) msg.obj;
+                    BrowseTree.BrowseNode bn = mBrowseTree.findBrowseNodeByID(mID);
+                    if (bn.isPlayer()) {
+                        // Add the now playing folder.
+                        MediaDescription.Builder mdb = new MediaDescription.Builder();
+                        mdb.setMediaId(BrowseTree.NOW_PLAYING_PREFIX + ":" +
+                            bn.getPlayerID());
+                        mdb.setTitle(BrowseTree.NOW_PLAYING_PREFIX);
+                        Bundle mdBundle = new Bundle();
+                        mdBundle.putString(
+                            AvrcpControllerService.MEDIA_ITEM_UID_KEY,
+                            BrowseTree.NOW_PLAYING_PREFIX + ":" + bn.getID());
+                        mdb.setExtras(mdBundle);
+                        folderList.add(new MediaItem(mdb.build(), MediaItem.FLAG_BROWSABLE));
+                    }
+
+                    mBrowseTree.refreshChildren(bn, folderList);
+                    broadcastFolderList(mID, folderList);
+
+                    transitionTo(mConnected);
+                    break;
+
+                case MESSAGE_INTERNAL_CMD_TIMEOUT:
+                    // We have timed out to execute the request.
+                    broadcastFolderList(mID, mEmptyMediaItemList);
+                    transitionTo(mConnected);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to connected!");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    // Handle the get player listing action
+    // a) Fetch the listing of players
+    // b) Once completed return the object listing
+    class GetPlayerListing extends CmdState {
+        private String STATE_TAG = "AVRCPSM.GetPlayerList";
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg);
+            switch (msg.what) {
+                case MESSAGE_PROCESS_GET_PLAYER_ITEMS:
+                    List<AvrcpPlayer> playerList =
+                        (List<AvrcpPlayer>) msg.obj;
+                    mBrowseTree.refreshChildren(BrowseTree.ROOT, playerList);
+                    ArrayList<MediaItem> mediaItemList = new ArrayList<>();
+                    for (BrowseTree.BrowseNode c :
+                            mBrowseTree.findBrowseNodeByID(BrowseTree.ROOT).getChildren()) {
+                        mediaItemList.add(c.getMediaItem());
+                    }
+                    broadcastFolderList(BrowseTree.ROOT, mediaItemList);
+                    mBrowseTree.setCurrentBrowsedFolder(BrowseTree.ROOT);
+                    transitionTo(mConnected);
+                    break;
+
+                case MESSAGE_INTERNAL_CMD_TIMEOUT:
+                    // We have timed out to execute the request.
+                    // Send an empty list here.
+                    broadcastFolderList(BrowseTree.ROOT, mEmptyMediaItemList);
+                    transitionTo(mConnected);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to connected!");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    class GetNowPlayingList extends CmdState {
+        private String STATE_TAG = "AVRCPSM.NowPlayingList";
+        private String mID = "";
+
+        public void setFolder(String id) {
+            mID = id;
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg);
+            switch (msg.what) {
+                case MESSAGE_PROCESS_GET_FOLDER_ITEMS:
+                    ArrayList<MediaItem> folderList = (ArrayList<MediaItem>) msg.obj;
+                    broadcastFolderList(mID, folderList);
+
+                    BrowseTree.BrowseNode bn = mBrowseTree.findBrowseNodeByID(mID);
+                    mBrowseTree.refreshChildren(bn, folderList);
+                    mBrowseTree.setCurrentBrowsedFolder(mID);
+                    transitionTo(mConnected);
+                    break;
+
+                case MESSAGE_INTERNAL_CMD_TIMEOUT:
+                    broadcastFolderList(mID, mEmptyMediaItemList);
+                    transitionTo(mConnected);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to connected!");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    class MoveToRoot extends CmdState {
+        private String STATE_TAG = "AVRCPSM.MoveToRoot";
+        private String mID = "";
+
+        public void setFolder(String id) {
+            Log.d(STATE_TAG, "setFolder " + id);
+            mID = id;
+        }
+
+        @Override
+        public void enter() {
+            // Setup the timeouts.
+            super.enter();
+
+            // We need to move mBrowseDepth levels up. The following message is
+            // completely internal to this state.
+            sendMessage(MESSAGE_INTERNAL_MOVE_N_LEVELS_UP);
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg + " browse depth " + mBrowseDepth);
+            switch (msg.what) {
+                case MESSAGE_INTERNAL_MOVE_N_LEVELS_UP:
+                    if (mBrowseDepth == 0) {
+                        Log.w(STATE_TAG, "Already in root!");
+                        transitionTo(mConnected);
+                        sendMessage(MESSAGE_GET_FOLDER_LIST, 0, 0xff, mID);
+                    } else {
+                        AvrcpControllerService.changeFolderPathNative(
+                            mRemoteDevice.getBluetoothAddress(),
+                            (byte) AvrcpControllerService.FOLDER_NAVIGATION_DIRECTION_UP,
+                            AvrcpControllerService.hexStringToByteUID(null));
+                    }
+                    break;
+
+                case MESSAGE_PROCESS_FOLDER_PATH:
+                    mBrowseDepth -= 1;
+                    Log.d(STATE_TAG, "New browse depth " + mBrowseDepth);
+                    if (mBrowseDepth < 0) {
+                        throw new IllegalArgumentException("Browse depth negative!");
+                    }
+
+                    sendMessage(MESSAGE_INTERNAL_MOVE_N_LEVELS_UP);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to connected!");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    class SetBrowsedPlayer extends CmdState {
+        private String STATE_TAG = "AVRCPSM.SetBrowsedPlayer";
+        String mID = "";
+
+        public void setFolder(String id) {
+            mID = id;
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            Log.d(STATE_TAG, "processMessage " + msg);
+            switch (msg.what) {
+                case MESSAGE_PROCESS_SET_BROWSED_PLAYER:
+                    // Set the new depth.
+                    Log.d(STATE_TAG, "player depth " + msg.arg2);
+                    mBrowseDepth = msg.arg2;
+
+                    // If we already on top of player and there is no content.
+                    // This should very rarely happen.
+                    if (mBrowseDepth == 0 && msg.arg1 == 0) {
+                        broadcastFolderList(mID, mEmptyMediaItemList);
+                        transitionTo(mConnected);
+                    } else {
+                        // Otherwise move to root and fetch the listing.
+                        // the MoveToRoot#enter() function takes care of fetch.
+                        mMoveToRoot.setFolder(mID);
+                        transitionTo(mMoveToRoot);
+                    }
+                    mBrowseTree.setCurrentBrowsedFolder(mID);
+                    break;
+
+                case MESSAGE_INTERNAL_CMD_TIMEOUT:
+                    broadcastFolderList(mID, mEmptyMediaItemList);
+                    transitionTo(mConnected);
+                    break;
+
+                default:
+                    Log.d(STATE_TAG, "deferring message " + msg + " to connected!");
+                    deferMessage(msg);
+            }
+            return true;
+        }
+    }
+
+    // Class template for commands. Each state should do the following:
+    // (a) In enter() send a timeout message which could be tracked in the
+    // processMessage() stage.
+    // (b) In exit() remove all the timeouts.
+    //
+    // Essentially the lifecycle of a timeout should be bounded to a CmdState always.
+    abstract class CmdState extends State {
+        @Override
+        public void enter() {
+            sendMessageDelayed(MESSAGE_INTERNAL_CMD_TIMEOUT, CMD_TIMEOUT_MILLIS);
+        }
+
+        @Override
+        public void exit() {
+            removeMessages(MESSAGE_INTERNAL_CMD_TIMEOUT);
+        }
+    }
+
+    // Interface APIs
+    boolean isConnected() {
+        synchronized (mLock) {
+            return mIsConnected;
+        }
+    }
+
+    void doQuit() {
+        try {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        } catch (IllegalArgumentException expected) {
+            // If the receiver was never registered unregister will throw an
+            // IllegalArgumentException.
+        }
+        quit();
+    }
+
+    void dump(StringBuilder sb) {
+        ProfileService.println(sb, "StateMachine: " + this.toString());
+    }
+
+    MediaMetadata getCurrentMetaData() {
+        synchronized (mLock) {
+            if (mAddressedPlayer != null && mAddressedPlayer.getCurrentTrack() != null) {
+                MediaMetadata mmd = mAddressedPlayer.getCurrentTrack().getMediaMetaData();
+                if (DBG) {
+                    Log.d(TAG, "getCurrentMetaData mmd " + mmd);
+                }
+            }
+            return mEmptyMMD;
+        }
+    }
+
+    PlaybackState getCurrentPlayBackState() {
+        synchronized (mLock) {
+            if (mAddressedPlayer == null) {
+                return new PlaybackState.Builder().setState(PlaybackState.STATE_ERROR,
+                    PlaybackState.PLAYBACK_POSITION_UNKNOWN,0).build();
+            }
+            return mAddressedPlayer.getPlaybackState();
+        }
+    }
+
+    // Browsing related functions.
+    void getChildren(String parentMediaId, int start, int items) {
+        BrowseTree.BrowseNode bn = mBrowseTree.findBrowseNodeByID(parentMediaId);
+        if (bn == null) {
+            Log.e(TAG, "Invalid folder to browse " + mBrowseTree);
+            broadcastFolderList(parentMediaId, mEmptyMediaItemList);
+            return;
+        }
+
+        Message msg = null;
+        if (BrowseTree.ROOT.equals(parentMediaId)) {
+            // Root contains the list of players.
+            msg = obtainMessage(AvrcpControllerStateMachine.MESSAGE_GET_PLAYER_LIST, start, items);
+        } else if (bn.isPlayer()) {
+            // Set browsed (and addressed player) as the new player.
+            // This should fetch the list of folders.
+            msg = obtainMessage(AvrcpControllerStateMachine.MESSAGE_SET_BROWSED_PLAYER,
+                bn.getPlayerID(), 0, bn.getID());
+        } else if (bn.isNowPlaying()) {
+            // Get all songs in the list.
+            msg = obtainMessage(
+                AvrcpControllerStateMachine.MESSAGE_GET_NOW_PLAYING_LIST,
+                start, items, parentMediaId);
+        } else {
+            // Only change folder if desired. If an app refreshes a folder
+            // (because it resumed etc) and current folder does not change
+            // then we can simply fetch list.
+            BrowseTree.BrowseNode currFol = mBrowseTree.getCurrentBrowsedFolder();
+
+            // We exempt two conditions from change folder:
+            // a) If the new folder is the same as current folder (refresh of UI)
+            // b) If the new folder is ROOT and current folder is NOW_PLAYING. In this
+            // condition we 'fake' child-parent hierarchy but it does not exist in
+            // bluetooth world.
+            boolean isNowPlayingToRoot =
+                currFol.isNowPlaying() && bn.getID().equals(BrowseTree.ROOT);
+            if (!bn.equals(currFol) && !isNowPlayingToRoot) {
+                // Find the direction of traversal.
+                int direction;
+                int btDirection = mBrowseTree.getDirection(parentMediaId);
+                Log.d(TAG, "Browse direction " + currFol + " " + bn + " = " + btDirection);
+                if (btDirection == BrowseTree.DIRECTION_DOWN) {
+                    direction = AvrcpControllerService.FOLDER_NAVIGATION_DIRECTION_DOWN;
+                } else if (btDirection == BrowseTree.DIRECTION_UP) {
+                    direction = AvrcpControllerService.FOLDER_NAVIGATION_DIRECTION_UP;
+                } else {
+                    Log.w(TAG, "parent " + bn + " is not a direct " +
+                        "successor or predeccessor of current folder " + currFol);
+                    broadcastFolderList(parentMediaId, mEmptyMediaItemList);
+                    return;
+                }
+                Bundle b = new Bundle();
+                b.putString(AvrcpControllerService.EXTRA_FOLDER_ID, bn.getID());
+                b.putString(AvrcpControllerService.EXTRA_FOLDER_BT_ID, bn.getFolderUID());
+                msg = obtainMessage(
+                    AvrcpControllerStateMachine.MESSAGE_CHANGE_FOLDER_PATH, direction, 0, b);
+            } else {
+                // Fetch the listing without changing paths.
+                msg = obtainMessage(
+                    AvrcpControllerStateMachine.MESSAGE_GET_FOLDER_LIST,
+                    start, items, bn.getFolderUID());
+            }
+        }
+        if (msg != null) {
+            sendMessage(msg);
+        }
+    }
+
+    public void fetchAttrAndPlayItem(String uid) {
+        BrowseTree.BrowseNode currItem = mBrowseTree.findFolderByIDLocked(uid);
+        BrowseTree.BrowseNode currFolder = mBrowseTree.getCurrentBrowsedFolder();
+        Log.d(TAG, "fetchAttrAndPlayItem mediaId=" + uid + " node=" + currItem);
+        if (currItem != null) {
+            int scope = currFolder.isNowPlaying() ?
+                AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING :
+                AvrcpControllerService.BROWSE_SCOPE_VFS;
+            Message msg = obtainMessage(
+                AvrcpControllerStateMachine.MESSAGE_FETCH_ATTR_AND_PLAY_ITEM,
+                scope, 0, currItem.getFolderUID());
+            sendMessage(msg);
+        }
+    }
+
+    private void broadcastMetaDataChanged(MediaMetadata metadata) {
+        Intent intent = new Intent(AvrcpControllerService.ACTION_TRACK_EVENT);
+        intent.putExtra(AvrcpControllerService.EXTRA_METADATA, metadata);
+        if (DBG) {
+            Log.d(TAG, " broadcastMetaDataChanged = " + metadata.getDescription());
+        }
+        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+    }
+
+    private void broadcastFolderList(String id, ArrayList<MediaItem> items) {
+        Intent intent = new Intent(AvrcpControllerService.ACTION_FOLDER_LIST);
+        Log.d(TAG, "broadcastFolderList id " + id + " items " + items);
+        intent.putExtra(AvrcpControllerService.EXTRA_FOLDER_ID, id);
+        intent.putParcelableArrayListExtra(
+            AvrcpControllerService.EXTRA_FOLDER_LIST, items);
+        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+    }
+
+    private void broadcastPlayBackStateChanged(PlaybackState state) {
+        Intent intent = new Intent(AvrcpControllerService.ACTION_TRACK_EVENT);
+        intent.putExtra(AvrcpControllerService.EXTRA_PLAYBACK, state);
+        if (DBG) {
+            Log.d(TAG, " broadcastPlayBackStateChanged = " + state.toString());
+        }
+        mContext.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
+    }
+
+    private void setAbsVolume(int absVol, int label) {
+        int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+        // Ignore first volume command since phone may not know difference between stream volume
+        // and amplifier volume.
+        if (mRemoteDevice.getFirstAbsVolCmdRecvd()) {
+            int newIndex = (maxVolume * absVol) / ABS_VOL_BASE;
+            Log.d(TAG,
+                " setAbsVolume =" + absVol + " maxVol = " + maxVolume + " cur = " + currIndex +
+                    " new = " + newIndex);
+            /*
+             * In some cases change in percentage is not sufficient enough to warrant
+             * change in index values which are in range of 0-15. For such cases
+             * no action is required
+             */
+            if (newIndex != currIndex) {
+                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newIndex,
+                    AudioManager.FLAG_SHOW_UI);
+            }
+        } else {
+            mRemoteDevice.setFirstAbsVolCmdRecvd();
+            absVol = (currIndex * ABS_VOL_BASE) / maxVolume;
+            Log.d(TAG, " SetAbsVol recvd for first time, respond with " + absVol);
+        }
+        AvrcpControllerService.sendAbsVolRspNative(
+            mRemoteDevice.getBluetoothAddress(), absVol, label);
+    }
+
+    private int getVolumePercentage() {
+        int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        int currIndex = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+        int percentageVol = ((currIndex * ABS_VOL_BASE) / maxVolume);
+        return percentageVol;
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
+                int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+                if (streamType == AudioManager.STREAM_MUSIC) {
+                    sendMessage(MESSAGE_PROCESS_VOLUME_CHANGED_NOTIFICATION);
+                }
+            }
+        }
+    };
+
+    public static String dumpMessageString(int message) {
+        String str = "UNKNOWN";
+        switch (message) {
+            case MESSAGE_SEND_PASS_THROUGH_CMD:
+                str = "REQ_PASS_THROUGH_CMD";
+                break;
+            case MESSAGE_SEND_GROUP_NAVIGATION_CMD:
+                str = "REQ_GRP_NAV_CMD";
+                break;
+            case MESSAGE_PROCESS_SET_ABS_VOL_CMD:
+                str = "CB_SET_ABS_VOL_CMD";
+                break;
+            case MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION:
+                str = "CB_REGISTER_ABS_VOL";
+                break;
+            case MESSAGE_PROCESS_TRACK_CHANGED:
+                str = "CB_TRACK_CHANGED";
+                break;
+            case MESSAGE_PROCESS_PLAY_POS_CHANGED:
+                str = "CB_PLAY_POS_CHANGED";
+                break;
+            case MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
+                str = "CB_PLAY_STATUS_CHANGED";
+                break;
+            case MESSAGE_PROCESS_RC_FEATURES:
+                str = "CB_RC_FEATURES";
+                break;
+            case MESSAGE_PROCESS_CONNECTION_CHANGE:
+                str = "CB_CONN_CHANGED";
+                break;
+            default:
+                str = Integer.toString(message);
+                break;
+        }
+        return str;
+    }
+
+    public static String displayBluetoothAvrcpSettings(BluetoothAvrcpPlayerSettings mSett) {
+        StringBuffer sb =  new StringBuffer();
+        int supportedSetting = mSett.getSettings();
+        if(VDBG) Log.d(TAG," setting: " + supportedSetting);
+        if((supportedSetting & BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER) != 0) {
+            sb.append(" EQ : ");
+            sb.append(Integer.toString(mSett.getSettingValue(BluetoothAvrcpPlayerSettings.
+                                                             SETTING_EQUALIZER)));
+        }
+        if((supportedSetting & BluetoothAvrcpPlayerSettings.SETTING_REPEAT) != 0) {
+            sb.append(" REPEAT : ");
+            sb.append(Integer.toString(mSett.getSettingValue(BluetoothAvrcpPlayerSettings.
+                                                             SETTING_REPEAT)));
+        }
+        if((supportedSetting & BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE) != 0) {
+            sb.append(" SHUFFLE : ");
+            sb.append(Integer.toString(mSett.getSettingValue(BluetoothAvrcpPlayerSettings.
+                                                             SETTING_SHUFFLE)));
+        }
+        if((supportedSetting & BluetoothAvrcpPlayerSettings.SETTING_SCAN) != 0) {
+            sb.append(" SCAN : ");
+            sb.append(Integer.toString(mSett.getSettingValue(BluetoothAvrcpPlayerSettings.
+                                                             SETTING_SCAN)));
+        }
+        return sb.toString();
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
new file mode 100644
index 0000000..3f037c2
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+import android.media.session.PlaybackState;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/*
+ * Contains information about remote player
+ */
+class AvrcpPlayer {
+    private static final String TAG = "AvrcpPlayer";
+    private static final boolean DBG = true;
+
+    public static final int INVALID_ID = -1;
+
+    private int mPlayStatus = PlaybackState.STATE_NONE;
+    private long mPlayTime   = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
+    private int mId;
+    private String mName = "";
+    private int mPlayerType;
+    private TrackInfo mCurrentTrack = new TrackInfo();
+
+    AvrcpPlayer() {
+        mId = INVALID_ID;
+    }
+
+    AvrcpPlayer(int id, String name, int transportFlags, int playStatus, int playerType) {
+        mId = id;
+        mName = name;
+        mPlayerType = playerType;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public String getName() {
+      return mName;
+    }
+
+    public void setPlayTime(int playTime) {
+        mPlayTime = playTime;
+    }
+
+    public long getPlayTime() {
+        return mPlayTime;
+    }
+
+    public void setPlayStatus(int playStatus) {
+        mPlayStatus = playStatus;
+    }
+
+    public PlaybackState getPlaybackState() {
+        if (DBG) {
+            Log.d(TAG, "getPlayBackState state " + mPlayStatus + " time " + mPlayTime);
+        }
+
+        long position = mPlayTime;
+        float speed = 1;
+        switch (mPlayStatus) {
+            case PlaybackState.STATE_STOPPED:
+                position = 0;
+                speed = 0;
+                break;
+            case PlaybackState.STATE_PAUSED:
+                speed = 0;
+                break;
+            case PlaybackState.STATE_FAST_FORWARDING:
+                speed = 3;
+                break;
+            case PlaybackState.STATE_REWINDING:
+                speed = -3;
+                break;
+        }
+        return new PlaybackState.Builder().setState(mPlayStatus, position, speed).build();
+    }
+
+    synchronized public void updateCurrentTrack(TrackInfo update) {
+        mCurrentTrack = update;
+    }
+
+    synchronized public TrackInfo getCurrentTrack() {
+        return mCurrentTrack;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java b/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
new file mode 100644
index 0000000..a11988d
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowser.MediaItem;
+import android.media.MediaDescription;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.service.media.MediaBrowserService.Result;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Stack;
+
+// Browsing hierarchy.
+// Root:
+//      Player1:
+//        Now_Playing:
+//          MediaItem1
+//          MediaItem2
+//        Folder1
+//        Folder2
+//        ....
+//      Player2
+//      ....
+public class BrowseTree {
+    private static final String TAG = "BrowseTree";
+    private static final boolean DBG = true;
+
+    public static final int DIRECTION_DOWN = 0;
+    public static final int DIRECTION_UP = 1;
+    public static final int DIRECTION_UNKNOWN = -1;
+
+    public static final String ROOT = "__ROOT__";
+    public static final String NOW_PLAYING_PREFIX = "NOW_PLAYING";
+    public static final String PLAYER_PREFIX = "PLAYER";
+
+    // Static instance of Folder ID <-> Folder Instance (for navigation purposes)
+    private final HashMap<String, BrowseNode> mBrowseMap = new HashMap<String, BrowseNode>();
+    private BrowseNode mCurrentBrowseNode;
+
+    BrowseTree() {
+        MediaDescription.Builder mdb = new MediaDescription.Builder();
+        mdb.setMediaId(ROOT);
+        mdb.setTitle(ROOT);
+        Bundle mdBundle = new Bundle();
+        mdBundle.putString(AvrcpControllerService.MEDIA_ITEM_UID_KEY, ROOT);
+        mdb.setExtras(mdBundle);
+        mBrowseMap.put(ROOT, new BrowseNode(new MediaItem(mdb.build(), MediaItem.FLAG_BROWSABLE)));
+        mCurrentBrowseNode = mBrowseMap.get(ROOT);
+    }
+
+    // Each node of the tree is represented by Folder ID, Folder Name and the children.
+    class BrowseNode {
+        // MediaItem to store the media related details.
+        MediaItem mItem;
+
+        // Type of this browse node.
+        // Since Media APIs do not define the player separately we define that
+        // distinction here.
+        boolean mIsPlayer = false;
+
+        // Result object if this node is not loaded yet. This result object will be used
+        // once loading is finished.
+        Result<List<MediaItem>> mResult = null;
+
+        // List of children.
+        final List<BrowseNode> mChildren = new ArrayList<BrowseNode>();
+
+        BrowseNode(MediaItem item) {
+            mItem = item;
+        }
+
+        BrowseNode(AvrcpPlayer player) {
+            mIsPlayer = true;
+
+            // Transform the player into a item.
+            MediaDescription.Builder mdb = new MediaDescription.Builder();
+            Bundle mdExtra = new Bundle();
+            String playerKey = PLAYER_PREFIX + player.getId();
+            mdExtra.putString(AvrcpControllerService.MEDIA_ITEM_UID_KEY, playerKey);
+            mdb.setExtras(mdExtra);
+            mdb.setMediaId(playerKey);
+            mdb.setTitle(player.getName());
+            mItem = new MediaBrowser.MediaItem(mdb.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE);
+        }
+
+        synchronized List<BrowseNode> getChildren() {
+            return mChildren;
+        }
+
+        synchronized boolean isChild(BrowseNode node) {
+            for (BrowseNode bn : mChildren) {
+                if (bn.equals(node)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        // Fetch the Unique UID for this item, this is unique across all elements in the tree.
+        synchronized String getID() {
+            return mItem.getDescription().getMediaId();
+        }
+
+        // Get the BT Player ID associated with this node.
+        synchronized int getPlayerID() {
+            return Integer.parseInt(getID().replace(PLAYER_PREFIX, ""));
+        }
+
+        // Fetch the Folder UID that can be used to fetch folder listing via bluetooth.
+        // This may not be unique hence this combined with direction will define the
+        // browsing here.
+        synchronized String getFolderUID() {
+            return mItem.getDescription().getExtras().getString(
+                AvrcpControllerService.MEDIA_ITEM_UID_KEY);
+        }
+
+        synchronized MediaItem getMediaItem() {
+            return mItem;
+        }
+
+        synchronized boolean isPlayer() {
+            return mIsPlayer;
+        }
+
+        synchronized boolean isNowPlaying() {
+            return getID().startsWith(NOW_PLAYING_PREFIX);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof BrowseNode)) {
+                return false;
+            }
+            BrowseNode otherNode = (BrowseNode) other;
+            return getID().equals(otherNode.getID());
+        }
+
+        @Override
+        public String toString() {
+            return "ID: " + getID() + " desc: " + mItem;
+        }
+    }
+
+    synchronized <E> void refreshChildren(String parentID, List<E> children) {
+        BrowseNode parent = findFolderByIDLocked(parentID);
+        if (parent == null) {
+            Log.w(TAG, "parent not found for parentID " + parentID);
+            return;
+        }
+        refreshChildren(parent, children);
+    }
+
+    synchronized <E> void refreshChildren(BrowseNode parent, List<E> children) {
+        if (children == null) {
+            Log.e(TAG, "children cannot be null ");
+            return;
+        }
+
+        List<BrowseNode> bnList = new ArrayList<BrowseNode>();
+        for (E child : children) {
+            if (child instanceof MediaItem) {
+                bnList.add(new BrowseNode((MediaItem) child));
+            } else if (child instanceof AvrcpPlayer) {
+                bnList.add(new BrowseNode((AvrcpPlayer) child));
+            }
+        }
+
+        String parentID = parent.getID();
+        // Make sure that the child list is clean.
+        if (DBG) {
+            Log.d(TAG, "parent " + parentID + " child list " + parent.getChildren());
+        }
+
+        addChildrenLocked(parent, bnList);
+        List<MediaItem> childrenList = new ArrayList<MediaItem>();
+        for (BrowseNode bn : parent.getChildren()) {
+            childrenList.add(bn.getMediaItem());
+        }
+    }
+
+    synchronized BrowseNode findBrowseNodeByID(String parentID) {
+        BrowseNode bn = mBrowseMap.get(parentID);
+        if (bn == null) {
+            Log.e(TAG, "folder " + parentID + " not found!");
+            return null;
+        }
+        if (DBG) {
+            Log.d(TAG, "Browse map: " + mBrowseMap);
+        }
+        return bn;
+    }
+
+    BrowseNode findFolderByIDLocked(String parentID) {
+        return mBrowseMap.get(parentID);
+    }
+
+    void addChildrenLocked(BrowseNode parent, List<BrowseNode> items) {
+        // Remove existing children and then add the new children.
+        for (BrowseNode c : parent.getChildren()) {
+            mBrowseMap.remove(c.getID());
+        }
+        parent.getChildren().clear();
+
+        for (BrowseNode bn : items) {
+            parent.getChildren().add(bn);
+            mBrowseMap.put(bn.getID(), bn);
+        }
+    }
+
+    synchronized int getDirection(String toUID) {
+        BrowseNode fromFolder = mCurrentBrowseNode;
+        BrowseNode toFolder = findFolderByIDLocked(toUID);
+        if (fromFolder == null || toFolder == null) {
+            Log.e(TAG, "from folder " + mCurrentBrowseNode + " or to folder " + toUID + " null!");
+        }
+
+        // Check the relationship.
+        if (fromFolder.isChild(toFolder)) {
+            return DIRECTION_DOWN;
+        } else if (toFolder.isChild(fromFolder)) {
+            return DIRECTION_UP;
+        } else {
+            Log.w(TAG, "from folder " + mCurrentBrowseNode + " children " +
+                fromFolder.getChildren() + "to folder " + toUID + " children " +
+                toFolder.getChildren());
+            return DIRECTION_UNKNOWN;
+        }
+    }
+
+    synchronized boolean setCurrentBrowsedFolder(String uid) {
+        BrowseNode bn = findFolderByIDLocked(uid);
+        if (bn == null) {
+            Log.e(TAG, "Setting an unknown browsed folder, ignoring bn " + uid);
+            return false;
+        }
+        mCurrentBrowseNode = bn;
+        return true;
+    }
+
+    synchronized BrowseNode getCurrentBrowsedFolder() {
+        return mCurrentBrowseNode;
+    }
+
+    @Override
+    public String toString() {
+        return mBrowseMap.toString();
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java b/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java
new file mode 100644
index 0000000..65d9966
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+/*
+ * Contains information Player Application Setting extended from BluetootAvrcpPlayerSettings
+ */
+class PlayerApplicationSettings {
+    private static final String TAG = "PlayerApplicationSettings";
+
+    /*
+     * Values for SetPlayerApplicationSettings from AVRCP Spec V1.6 Appendix F.
+     */
+    private static final byte JNI_ATTRIB_EQUALIZER_STATUS = 0x01;
+    private static final byte JNI_ATTRIB_REPEAT_STATUS = 0x02;
+    private static final byte JNI_ATTRIB_SHUFFLE_STATUS = 0x03;
+    private static final byte JNI_ATTRIB_SCAN_STATUS = 0x04;
+
+    private static final byte JNI_EQUALIZER_STATUS_OFF = 0x01;
+    private static final byte JNI_EQUALIZER_STATUS_ON = 0x02;
+
+    private static final byte JNI_REPEAT_STATUS_OFF = 0x01;
+    private static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02;
+    private static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03;
+    private static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04;
+
+    private static final byte JNI_SHUFFLE_STATUS_OFF = 0x01;
+    private static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02;
+    private static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03;
+
+    private static final byte JNI_SCAN_STATUS_OFF = 0x01;
+    private static final byte JNI_SCAN_STATUS_ALL_TRACK_SCAN = 0x02;
+    private static final byte JNI_SCAN_STATUS_GROUP_SCAN = 0x03;
+
+    private static final byte JNI_STATUS_INVALID = -1;
+
+
+    /*
+     * Hash map of current settings.
+     */
+    private Map<Integer, Integer> mSettings = new HashMap<Integer, Integer>();
+
+    /*
+     * Hash map of supported values, a setting should be supported by the remote in order to enable
+     * in mSettings.
+     */
+    private Map<Integer, ArrayList<Integer>> mSupportedValues =
+        new HashMap<Integer, ArrayList<Integer>>();
+
+    /* Convert from JNI array to Java classes. */
+    static PlayerApplicationSettings makeSupportedSettings(byte[] btAvrcpAttributeList) {
+        PlayerApplicationSettings newObj = new PlayerApplicationSettings();
+        try {
+            for (int i = 0; i < btAvrcpAttributeList.length; ) {
+                byte attrId = btAvrcpAttributeList[i++];
+                byte numSupportedVals = btAvrcpAttributeList[i++];
+                ArrayList<Integer> supportedValues = new ArrayList<Integer>();
+
+                for (int j = 0; j < numSupportedVals; j++) {
+                    // Yes, keep using i for array indexing.
+                    supportedValues.add(mapAttribIdValtoAvrcpPlayerSetting(attrId,
+                        btAvrcpAttributeList[i++]));
+                }
+                newObj.mSupportedValues.put(mapBTAttribIdToAvrcpPlayerSettings(attrId),
+                    supportedValues);
+            }
+        } catch (ArrayIndexOutOfBoundsException exception) {
+            Log.e(TAG,"makeSupportedSettings attributeList index error.");
+        }
+        return newObj;
+    }
+
+    public BluetoothAvrcpPlayerSettings getAvrcpSettings() {
+        int supportedSettings = 0;
+        for (Integer setting : mSettings.keySet()) {
+            supportedSettings |= setting;
+        }
+        BluetoothAvrcpPlayerSettings result = new BluetoothAvrcpPlayerSettings(supportedSettings);
+        for (Integer setting : mSettings.keySet()) {
+            result.addSettingValue(setting, mSettings.get(setting));
+        }
+        return result;
+    }
+
+    static PlayerApplicationSettings makeSettings(byte[] btAvrcpAttributeList) {
+        PlayerApplicationSettings newObj = new PlayerApplicationSettings();
+        try {
+            for (int i = 0; i < btAvrcpAttributeList.length; ) {
+                byte attrId = btAvrcpAttributeList[i++];
+
+                newObj.mSettings.put(mapBTAttribIdToAvrcpPlayerSettings(attrId),
+                    mapAttribIdValtoAvrcpPlayerSetting(attrId,
+                        btAvrcpAttributeList[i++]));
+            }
+        } catch (ArrayIndexOutOfBoundsException exception) {
+            Log.e(TAG,"makeSettings JNI_ATTRIButeList index error.");
+        }
+        return newObj;
+    }
+
+    public void setSupport(PlayerApplicationSettings updates) {
+        mSettings = updates.mSettings;
+        mSupportedValues = updates.mSupportedValues;
+    }
+
+    public void setValues(BluetoothAvrcpPlayerSettings updates) {
+        int supportedSettings = updates.getSettings();
+        for (int i = 1; i <= BluetoothAvrcpPlayerSettings.SETTING_SCAN; i++) {
+            if ((i & supportedSettings) > 0) {
+                mSettings.put(i, updates.getSettingValue(i));
+            }
+        }
+    }
+
+    /*
+     * Check through all settings to ensure that they are all available to be set and then check
+     * that the desired value is in fact supported by our remote player.
+     */
+    public boolean supportsSettings(BluetoothAvrcpPlayerSettings settingsToCheck) {
+        int settingSubset = settingsToCheck.getSettings();
+        int supportedSettings = 0;
+        for (Integer setting : mSupportedValues.keySet()) {
+            supportedSettings |= setting;
+        }
+        try {
+            if ((supportedSettings & settingSubset) == settingSubset) {
+                for (Integer settingId : mSettings.keySet()) {
+                    if ((settingId & settingSubset )== settingId &&
+                        (!mSupportedValues.get(settingId).contains(settingsToCheck.
+                            getSettingValue(settingId))))
+                        // The setting is in both settings to check and supported settings but the
+                        // value is not supported.
+                        return false;
+                }
+                return true;
+            }
+        } catch (NullPointerException e) {
+            Log.e(TAG,
+                "supportsSettings received a supported setting that has no supported values.");
+        }
+        return false;
+    }
+
+    // Convert currently desired settings into an attribute array to pass to the native layer to
+    // enable them.
+    public ArrayList<Byte> getNativeSettings() {
+        int i = 0;
+        ArrayList<Byte> attribArray = new ArrayList<Byte>();
+        for (Integer settingId : mSettings.keySet()) {
+            switch (settingId)
+            {
+                case BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER:
+                    attribArray.add(JNI_ATTRIB_EQUALIZER_STATUS);
+                    attribArray.add(mapAvrcpPlayerSettingstoBTattribVal(
+                        settingId, mSettings.get(settingId)));
+                    break;
+                case BluetoothAvrcpPlayerSettings.SETTING_REPEAT:
+                    attribArray.add(JNI_ATTRIB_REPEAT_STATUS);
+                    attribArray.add(mapAvrcpPlayerSettingstoBTattribVal(
+                        settingId, mSettings.get(settingId)));
+                    break;
+                case BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE:
+                    attribArray.add(JNI_ATTRIB_SHUFFLE_STATUS);
+                    attribArray.add(mapAvrcpPlayerSettingstoBTattribVal(
+                        settingId, mSettings.get(settingId)));
+                    break;
+                case BluetoothAvrcpPlayerSettings.SETTING_SCAN:
+                    attribArray.add(JNI_ATTRIB_SCAN_STATUS);
+                    attribArray.add(mapAvrcpPlayerSettingstoBTattribVal(
+                        settingId, mSettings.get(settingId)));
+                    break;
+                default:
+                    Log.w(TAG,"Unknown setting found in getNativeSettings: " + settingId);
+            }
+        }
+        return attribArray;
+    }
+
+    // Convert a native Attribute Id/Value pair into the AVRCP equivalent value.
+    private static int mapAttribIdValtoAvrcpPlayerSetting(byte attribId, byte attribVal) {
+        if (attribId == JNI_ATTRIB_EQUALIZER_STATUS) {
+            switch(attribVal) {
+                case JNI_EQUALIZER_STATUS_OFF:
+                    return BluetoothAvrcpPlayerSettings.STATE_OFF;
+                case JNI_EQUALIZER_STATUS_ON:
+                    return BluetoothAvrcpPlayerSettings.STATE_ON;
+            }
+        } else if (attribId == JNI_ATTRIB_REPEAT_STATUS) {
+            switch(attribVal) {
+                case JNI_REPEAT_STATUS_ALL_TRACK_REPEAT:
+                    return BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK;
+                case JNI_REPEAT_STATUS_GROUP_REPEAT:
+                    return BluetoothAvrcpPlayerSettings.STATE_GROUP;
+                case JNI_REPEAT_STATUS_OFF:
+                    return BluetoothAvrcpPlayerSettings.STATE_OFF;
+                case JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT:
+                    return BluetoothAvrcpPlayerSettings.STATE_SINGLE_TRACK;
+            }
+        } else if (attribId == JNI_ATTRIB_SCAN_STATUS) {
+            switch(attribVal) {
+                case JNI_SCAN_STATUS_ALL_TRACK_SCAN:
+                    return BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK;
+                case JNI_SCAN_STATUS_GROUP_SCAN:
+                    return BluetoothAvrcpPlayerSettings.STATE_GROUP;
+                case JNI_SCAN_STATUS_OFF:
+                    return BluetoothAvrcpPlayerSettings.STATE_OFF;
+            }
+        } else if (attribId == JNI_ATTRIB_SHUFFLE_STATUS) {
+            switch(attribVal) {
+                case JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE:
+                    return BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK;
+                case JNI_SHUFFLE_STATUS_GROUP_SHUFFLE:
+                    return BluetoothAvrcpPlayerSettings.STATE_GROUP;
+                case JNI_SHUFFLE_STATUS_OFF:
+                    return BluetoothAvrcpPlayerSettings.STATE_OFF;
+            }
+        }
+        return BluetoothAvrcpPlayerSettings.STATE_INVALID;
+    }
+
+    // Convert an AVRCP Setting/Value pair into the native equivalent value;
+    private static byte mapAvrcpPlayerSettingstoBTattribVal(int mSetting, int mSettingVal) {
+        if (mSetting == BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER) {
+            switch(mSettingVal) {
+                case BluetoothAvrcpPlayerSettings.STATE_OFF:
+                    return JNI_EQUALIZER_STATUS_OFF;
+                case BluetoothAvrcpPlayerSettings.STATE_ON:
+                    return JNI_EQUALIZER_STATUS_ON;
+            }
+        } else if (mSetting == BluetoothAvrcpPlayerSettings.SETTING_REPEAT) {
+            switch(mSettingVal) {
+                case BluetoothAvrcpPlayerSettings.STATE_OFF:
+                    return JNI_REPEAT_STATUS_OFF;
+                case BluetoothAvrcpPlayerSettings.STATE_SINGLE_TRACK:
+                    return JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT;
+                case BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK:
+                    return JNI_REPEAT_STATUS_ALL_TRACK_REPEAT;
+                case BluetoothAvrcpPlayerSettings.STATE_GROUP:
+                    return JNI_REPEAT_STATUS_GROUP_REPEAT;
+            }
+        } else if (mSetting == BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE) {
+            switch(mSettingVal) {
+                case BluetoothAvrcpPlayerSettings.STATE_OFF:
+                    return JNI_SHUFFLE_STATUS_OFF;
+                case BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK:
+                    return JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE;
+                case BluetoothAvrcpPlayerSettings.STATE_GROUP:
+                    return JNI_SHUFFLE_STATUS_GROUP_SHUFFLE;
+            }
+        } else if (mSetting == BluetoothAvrcpPlayerSettings.SETTING_SCAN) {
+            switch(mSettingVal) {
+                case BluetoothAvrcpPlayerSettings.STATE_OFF:
+                    return JNI_SCAN_STATUS_OFF;
+                case BluetoothAvrcpPlayerSettings.STATE_ALL_TRACK:
+                    return JNI_SCAN_STATUS_ALL_TRACK_SCAN;
+                case BluetoothAvrcpPlayerSettings.STATE_GROUP:
+                    return JNI_SCAN_STATUS_GROUP_SCAN;
+            }
+        }
+        return JNI_STATUS_INVALID;
+    }
+
+    // convert a native Attribute Id into the AVRCP Setting equivalent value;
+    private static int mapBTAttribIdToAvrcpPlayerSettings(byte attribId) {
+        switch(attribId) {
+            case JNI_ATTRIB_EQUALIZER_STATUS:
+                return BluetoothAvrcpPlayerSettings.SETTING_EQUALIZER;
+            case JNI_ATTRIB_REPEAT_STATUS:
+                return BluetoothAvrcpPlayerSettings.SETTING_REPEAT;
+            case JNI_ATTRIB_SHUFFLE_STATUS:
+                return BluetoothAvrcpPlayerSettings.SETTING_SHUFFLE;
+            case JNI_ATTRIB_SCAN_STATUS:
+                return BluetoothAvrcpPlayerSettings.SETTING_SCAN;
+            default:
+                return BluetoothAvrcpPlayerSettings.STATE_INVALID;
+        }
+    }
+
+}
+
diff --git a/src/com/android/bluetooth/avrcpcontroller/RemoteDevice.java b/src/com/android/bluetooth/avrcpcontroller/RemoteDevice.java
new file mode 100644
index 0000000..e535f92
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/RemoteDevice.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.bluetooth.BluetoothAvrcpPlayerSettings;
+import android.bluetooth.BluetoothDevice;
+import android.media.session.PlaybackState;
+
+import com.android.bluetooth.Utils;
+
+import java.util.ArrayList;
+import java.nio.ByteBuffer;
+
+/*
+ * Contains information about remote device specifically the player and features enabled on it along
+ * with an encapsulation of the current track and playlist information.
+ */
+class RemoteDevice {
+
+    /*
+     * Remote features from JNI
+     */
+    private static final int FEAT_NONE = 0;
+    private static final int FEAT_METADATA = 1;
+    private static final int FEAT_ABSOLUTE_VOLUME = 2;
+    private static final int FEAT_BROWSE = 4;
+
+    private static final int VOLUME_LABEL_UNDEFINED = -1;
+
+    final BluetoothDevice mBTDevice;
+    private int mRemoteFeatures;
+    private boolean mAbsVolNotificationRequested;
+    private boolean mFirstAbsVolCmdRecvd;
+    private int mNotificationLabel;
+
+    RemoteDevice(BluetoothDevice mDevice) {
+        mBTDevice = mDevice;
+        mRemoteFeatures = FEAT_NONE;
+        mAbsVolNotificationRequested = false;
+        mNotificationLabel = VOLUME_LABEL_UNDEFINED;
+        mFirstAbsVolCmdRecvd = false;
+    }
+
+    synchronized void setRemoteFeatures(int remoteFeatures) {
+        mRemoteFeatures = remoteFeatures;
+    }
+
+    synchronized public byte[] getBluetoothAddress() {
+        return Utils.getByteAddress(mBTDevice);
+    }
+
+    synchronized public void setNotificationLabel(int label) {
+        mNotificationLabel = label;
+    }
+
+    synchronized public int getNotificationLabel() {
+        return mNotificationLabel;
+    }
+
+    synchronized public void setAbsVolNotificationRequested(boolean request) {
+        mAbsVolNotificationRequested = request;
+    }
+
+    synchronized public boolean getAbsVolNotificationRequested() {
+        return mAbsVolNotificationRequested;
+    }
+
+    synchronized public void setFirstAbsVolCmdRecvd() {
+        mFirstAbsVolCmdRecvd = true;
+    }
+
+    synchronized public boolean getFirstAbsVolCmdRecvd() {
+        return mFirstAbsVolCmdRecvd;
+    }
+}
diff --git a/src/com/android/bluetooth/avrcpcontroller/TrackInfo.java b/src/com/android/bluetooth/avrcpcontroller/TrackInfo.java
new file mode 100644
index 0000000..033ea04
--- /dev/null
+++ b/src/com/android/bluetooth/avrcpcontroller/TrackInfo.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.bluetooth.avrcpcontroller;
+
+import android.media.MediaMetadata;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+/*
+ * Contains information about tracks that either currently playing or maintained in playlist
+ * This is used as a local repository for information that will be passed on as MediaMetadata to the
+ * MediaSessionServicve
+ */
+class TrackInfo {
+    private static final String TAG = "AvrcpTrackInfo";
+    private static final boolean DBG = true;
+
+    /*
+     * Default values for each of the items from JNI
+     */
+    private static final int TRACK_NUM_INVALID = -1;
+    private static final int TOTAL_TRACKS_INVALID = -1;
+    private static final int TOTAL_TRACK_TIME_INVALID = -1;
+    private static final String UNPOPULATED_ATTRIBUTE = "";
+
+    /*
+     *Element Id Values for GetMetaData  from JNI
+     */
+    private static final int MEDIA_ATTRIBUTE_TITLE = 0x01;
+    private static final int MEDIA_ATTRIBUTE_ARTIST_NAME = 0x02;
+    private static final int MEDIA_ATTRIBUTE_ALBUM_NAME = 0x03;
+    private static final int MEDIA_ATTRIBUTE_TRACK_NUMBER = 0x04;
+    private static final int MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER = 0x05;
+    private static final int MEDIA_ATTRIBUTE_GENRE = 0x06;
+    private static final int MEDIA_ATTRIBUTE_PLAYING_TIME = 0x07;
+
+
+    private final String mArtistName;
+    private final String mTrackTitle;
+    private final String mAlbumTitle;
+    private final String mGenre;
+    private final long mTrackNum; // number of audio file on original recording.
+    private final long mTotalTracks;// total number of tracks on original recording
+    private final long mTrackLen;// full length of AudioFile.
+
+    public TrackInfo() {
+        this(new ArrayList<Integer>(), new ArrayList<String>());
+    }
+
+    public TrackInfo(List<Integer> attrIds, List<String> attrMap) {
+        Map<Integer, String> attributeMap = new HashMap<>();
+        for (int i = 0; i < attrIds.size(); i++) {
+            attributeMap.put(attrIds.get(i), attrMap.get(i));
+        }
+
+        String attribute;
+        mTrackTitle = attributeMap.getOrDefault(MEDIA_ATTRIBUTE_TITLE, UNPOPULATED_ATTRIBUTE);
+
+        mArtistName = attributeMap.getOrDefault(MEDIA_ATTRIBUTE_ARTIST_NAME, UNPOPULATED_ATTRIBUTE);
+
+        mAlbumTitle = attributeMap.getOrDefault(MEDIA_ATTRIBUTE_ALBUM_NAME, UNPOPULATED_ATTRIBUTE);
+
+        attribute = attributeMap.get(MEDIA_ATTRIBUTE_TRACK_NUMBER);
+        mTrackNum = (attribute != null && !attribute.isEmpty()) ? Long.valueOf(attribute) : TRACK_NUM_INVALID;
+
+        attribute = attributeMap.get(MEDIA_ATTRIBUTE_TOTAL_TRACK_NUMBER);
+        mTotalTracks = (attribute != null && !attribute.isEmpty()) ? Long.valueOf(attribute) : TOTAL_TRACKS_INVALID;
+
+        mGenre = attributeMap.getOrDefault(MEDIA_ATTRIBUTE_GENRE, UNPOPULATED_ATTRIBUTE);
+
+        attribute = attributeMap.get(MEDIA_ATTRIBUTE_PLAYING_TIME);
+        mTrackLen = (attribute != null && !attribute.isEmpty()) ? Long.valueOf(attribute) : TOTAL_TRACK_TIME_INVALID;
+    }
+
+    public String toString() {
+        return "Metadata [artist=" + mArtistName + " trackTitle= " + mTrackTitle +
+                " albumTitle= " + mAlbumTitle + " genre= " +mGenre+" trackNum= "+
+                Long.toString(mTrackNum) + " track_len : "+ Long.toString(mTrackLen) +
+                " TotalTracks " + Long.toString(mTotalTracks) + "]";
+    }
+
+    public MediaMetadata getMediaMetaData() {
+        if (DBG) Log.d(TAG, " TrackInfo " + toString());
+        MediaMetadata.Builder mMetaDataBuilder = new MediaMetadata.Builder();
+        mMetaDataBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST,
+            mArtistName);
+        mMetaDataBuilder.putString(MediaMetadata.METADATA_KEY_TITLE,
+            mTrackTitle);
+        mMetaDataBuilder.putString(MediaMetadata.METADATA_KEY_ALBUM,
+            mAlbumTitle);
+        mMetaDataBuilder.putString(MediaMetadata.METADATA_KEY_GENRE,
+            mGenre);
+        mMetaDataBuilder.putLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER,
+            mTrackNum);
+        mMetaDataBuilder.putLong(MediaMetadata.METADATA_KEY_NUM_TRACKS,
+            mTotalTracks);
+        mMetaDataBuilder.putLong(MediaMetadata.METADATA_KEY_DURATION,
+            mTrackLen);
+        return mMetaDataBuilder.build();
+    }
+
+
+    public String displayMetaData() {
+        MediaMetadata metaData = getMediaMetaData();
+        StringBuffer sb = new StringBuffer();
+        /* getDescription only contains artist, title and album */
+        sb.append(metaData.getDescription().toString() + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_GENRE))
+            sb.append(metaData.getString(MediaMetadata.METADATA_KEY_GENRE) + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_MEDIA_ID))
+            sb.append(metaData.getString(MediaMetadata.METADATA_KEY_MEDIA_ID) + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER))
+            sb.append(Long.toString(metaData.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS))
+            sb.append(Long.toString(metaData.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS)) + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER))
+            sb.append(Long.toString(metaData.getLong(MediaMetadata.METADATA_KEY_DURATION)) + " ");
+        if(metaData.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER))
+            sb.append(Long.toString(metaData.getLong(MediaMetadata.METADATA_KEY_DURATION)) + " ");
+        return sb.toString();
+    }
+}
diff --git a/src/com/android/bluetooth/btservice/Config.java b/src/com/android/bluetooth/btservice/Config.java
index afb9d8d..6bae460 100644
--- a/src/com/android/bluetooth/btservice/Config.java
+++ b/src/com/android/bluetooth/btservice/Config.java
@@ -28,7 +28,7 @@
 import com.android.bluetooth.R;
 import com.android.bluetooth.a2dp.A2dpService;
 import com.android.bluetooth.a2dpsink.A2dpSinkService;
-import com.android.bluetooth.avrcp.AvrcpControllerService;
+import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
 import com.android.bluetooth.hdp.HealthService;
 import com.android.bluetooth.hfp.HeadsetService;
 import com.android.bluetooth.hfpclient.HeadsetClientService;
