am e9428c35: am 7677468e: am 884362fe: am ada9e950: am 727741cd: Merge "Use pathPrefix filter instead of path for /btopp content" into jb-mr1-dev

* commit 'e9428c35344af989f9e643964a81e2dc0ce1ffe1':
  Use pathPrefix filter instead of path for /btopp content
diff --git a/Android.mk b/Android.mk
index b0606df..4c24df9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -10,7 +10,7 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_JNI_SHARED_LIBRARIES := libbluetooth_jni
-LOCAL_JAVA_LIBRARIES := javax.obex
+LOCAL_JAVA_LIBRARIES := javax.obex telephony-common mms-common
 LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
 
 LOCAL_REQUIRED_MODULES := libbluetooth_jni bluetooth.default
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0c9857d..55c40a7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -50,6 +50,14 @@
     <uses-permission android:name="android.permission.MANAGE_USERS"/>
     <uses-permission android:name="com.google.android.gallery3d.permission.GALLERY_PROVIDER"/>
     <uses-permission android:name="com.android.gallery3d.permission.GALLERY_PROVIDER"/>
+    <uses-permission android:name="android.permission.MMS_SEND_OUTBOX_MSG"/>
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.READ_SMS" />
+    <uses-permission android:name="android.permission.WRITE_SMS" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
 
     <!-- For PBAP Owner Vcard Info -->
     <uses-permission android:name="android.permission.READ_PROFILE"/>
@@ -222,6 +230,14 @@
         </receiver>
         <service
             android:process="@string/process"
+            android:name=".map.BluetoothMapService"
+            android:enabled="@bool/profile_supported_map" >
+            <intent-filter>
+                <action android:name="android.bluetooth.IBluetoothMap" />
+            </intent-filter>
+        </service>
+        <service
+            android:process="@string/process"
             android:name = ".gatt.GattService"
             android:enabled="@bool/profile_supported_gatt">
             <intent-filter>
diff --git a/jni/com_android_bluetooth_avrcp.cpp b/jni/com_android_bluetooth_avrcp.cpp
index 6ff5cfa..c077bc6 100644
--- a/jni/com_android_bluetooth_avrcp.cpp
+++ b/jni/com_android_bluetooth_avrcp.cpp
@@ -26,9 +26,12 @@
 #include <string.h>
 
 namespace android {
+static jmethodID method_getRcFeatures;
 static jmethodID method_getPlayStatus;
 static jmethodID method_getElementAttr;
 static jmethodID method_registerNotification;
+static jmethodID method_volumeChangeCallback;
+static jmethodID method_handlePassthroughCmd;
 
 static const btrc_interface_t *sBluetoothAvrcpInterface = NULL;
 static jobject mCallbacksObj = NULL;
@@ -46,6 +49,26 @@
     return true;
 }
 
+static void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr, btrc_remote_features_t features) {
+    ALOGI("%s", __FUNCTION__);
+    jbyteArray addr;
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
+    if (!addr) {
+        ALOGE("Fail to new jbyteArray bd addr for connection state");
+        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+        return;
+    }
+
+    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
+    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features);
+    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+}
+
 static void btavrcp_get_play_status_callback() {
     ALOGI("%s", __FUNCTION__);
 
@@ -92,8 +115,35 @@
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
+static void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype) {
+    ALOGI("%s", __FUNCTION__);
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+
+    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_volumeChangeCallback, (jint)volume,
+                                                                             (jint)ctype);
+    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+}
+
+static void btavrcp_passthrough_command_callback(int id, int pressed) {
+    ALOGI("%s", __FUNCTION__);
+
+    if (!checkCallbackThread()) {
+        ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
+        return;
+    }
+
+    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughCmd, (jint)id,
+                                                                             (jint)pressed);
+    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+}
+
 static btrc_callbacks_t sBluetoothAvrcpCallbacks = {
     sizeof(sBluetoothAvrcpCallbacks),
+    btavrcp_remote_features_callback,
     btavrcp_get_play_status_callback,
     NULL,
     NULL,
@@ -102,10 +152,14 @@
     NULL,
     NULL,
     btavrcp_get_element_attr_callback,
-    btavrcp_register_notification_callback
+    btavrcp_register_notification_callback,
+    btavrcp_volume_change_callback,
+    btavrcp_passthrough_command_callback
 };
 
 static void classInitNative(JNIEnv* env, jclass clazz) {
+    method_getRcFeatures =
+        env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
     method_getPlayStatus =
         env->GetMethodID(clazz, "getPlayStatus", "()V");
 
@@ -115,6 +169,12 @@
     method_registerNotification =
         env->GetMethodID(clazz, "registerNotification", "(II)V");
 
+    method_volumeChangeCallback =
+        env->GetMethodID(clazz, "volumeChangeCallback", "(II)V");
+
+    method_handlePassthroughCmd =
+        env->GetMethodID(clazz, "handlePassthroughCmd", "(II)V");
+
     ALOGI("%s: succeeds", __FUNCTION__);
 }
 
@@ -318,6 +378,22 @@
     return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
 }
 
+static jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume) {
+    bt_status_t status;
+
+    //TODO: delete test code
+    ALOGI("%s: jint: %d, uint8_t: %u", __FUNCTION__, volume, (uint8_t) volume);
+
+    ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface);
+    if (!sBluetoothAvrcpInterface) return JNI_FALSE;
+
+    if ((status = sBluetoothAvrcpInterface->set_volume((uint8_t)volume)) != BT_STATUS_SUCCESS) {
+        ALOGE("Failed set_volume, status: %d", status);
+    }
+
+    return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
+}
+
 static JNINativeMethod sMethods[] = {
     {"classInitNative", "()V", (void *) classInitNative},
     {"initNative", "()V", (void *) initNative},
@@ -330,6 +406,8 @@
      (void *) registerNotificationRspTrackChangeNative},
     {"registerNotificationRspPlayPosNative", "(II)Z",
      (void *) registerNotificationRspPlayPosNative},
+    {"setVolumeNative", "(I)Z",
+     (void *) setVolumeNative}
 };
 
 int register_com_android_bluetooth_avrcp(JNIEnv* env)
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index f6dde86..28de5ea 100644
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -21,6 +21,7 @@
 #include "utils/misc.h"
 #include "cutils/properties.h"
 #include "android_runtime/AndroidRuntime.h"
+#include "android_runtime/Log.h"
 
 #include <string.h>
 #include <pthread.h>
@@ -904,6 +905,20 @@
     return -1;
 }
 
+static jboolean configHciSnoopLogNative(JNIEnv* env, jobject obj, jboolean enable) {
+    ALOGV("%s:",__FUNCTION__);
+
+    jboolean result = JNI_FALSE;
+
+    if (!sBluetoothInterface) return result;
+
+    int ret = sBluetoothInterface->config_hci_snoop_log(enable);
+
+    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
+
+    return result;
+}
+
 static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
     {"classInitNative", "()V", (void *) classInitNative},
@@ -926,7 +941,8 @@
     {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
     {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
     {"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
-     (void*) createSocketChannelNative}
+     (void*) createSocketChannelNative},
+    {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative}
 };
 
 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index 207e643..854a925 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -44,14 +44,14 @@
 #define UUID_PARAMS(uuid_ptr) \
     uuid_lsb(uuid_ptr),  uuid_msb(uuid_ptr)
 
-#define CHAR_ID_PARAMS(char_ptr) \
-    char_ptr->inst_id, \
-    UUID_PARAMS((&char_ptr->uuid))
+#define GATT_ID_PARAMS(attr_ptr) \
+    attr_ptr->inst_id, \
+    UUID_PARAMS((&attr_ptr->uuid))
 
 #define SRVC_ID_PARAMS(srvc_ptr) \
     (srvc_ptr->is_primary ? \
     BTGATT_SERVICE_TYPE_PRIMARY : BTGATT_SERVICE_TYPE_SECONDARY), \
-    CHAR_ID_PARAMS((&srvc_ptr->id))
+    GATT_ID_PARAMS((&srvc_ptr->id))
 
 
 static void set_uuid(uint8_t* uuid, jlong uuid_msb, jlong uuid_lsb)
@@ -158,6 +158,7 @@
 static jmethodID method_onGetIncludedService;
 static jmethodID method_onRegisterForNotifications;
 static jmethodID method_onReadRemoteRssi;
+static jmethodID method_onClientListen;
 
 /**
  * Server callback methods
@@ -273,24 +274,24 @@
 }
 
 void btgattc_get_characteristic_cb(int conn_id, int status,
-                btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id,
+                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
                 int char_prop)
 {
     CHECK_CALLBACK_ENV
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetCharacteristic
-        , conn_id, status, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id)
+        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
         , char_prop);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
 void btgattc_get_descriptor_cb(int conn_id, int status,
-                btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id,
-                bt_uuid_t *descr_id)
+                btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
+                btgatt_gatt_id_t *descr_id)
 {
     CHECK_CALLBACK_ENV
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetDescriptor
-        , conn_id, status, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id)
-        , UUID_PARAMS(descr_id));
+        , conn_id, status, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id)
+        , GATT_ID_PARAMS(descr_id));
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
@@ -304,11 +305,11 @@
 }
 
 void btgattc_register_for_notification_cb(int conn_id, int registered, int status,
-                                          btgatt_srvc_id_t *srvc_id, btgatt_char_id_t *char_id)
+                                          btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id)
 {
     CHECK_CALLBACK_ENV
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications
-        , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), CHAR_ID_PARAMS(char_id));
+        , conn_id, status, registered, SRVC_ID_PARAMS(srvc_id), GATT_ID_PARAMS(char_id));
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
@@ -327,7 +328,7 @@
 
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify
         , conn_id, address, SRVC_ID_PARAMS((&p_data->srvc_id))
-        , CHAR_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);
+        , GATT_ID_PARAMS((&p_data->char_id)), p_data->is_notify, jb);
 
     sCallbackEnv->DeleteLocalRef(address);
     sCallbackEnv->DeleteLocalRef(jb);
@@ -352,7 +353,7 @@
 
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic
         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
-        , CHAR_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
+        , GATT_ID_PARAMS((&p_data->char_id)), p_data->value_type, jb);
     sCallbackEnv->DeleteLocalRef(jb);
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
@@ -362,7 +363,7 @@
     CHECK_CALLBACK_ENV
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic
         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
-        , CHAR_ID_PARAMS((&p_data->char_id)));
+        , GATT_ID_PARAMS((&p_data->char_id)));
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
@@ -390,7 +391,7 @@
 
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor
         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
-        , CHAR_ID_PARAMS((&p_data->char_id)), UUID_PARAMS((&p_data->descr_id))
+        , GATT_ID_PARAMS((&p_data->char_id)), GATT_ID_PARAMS((&p_data->descr_id))
         , p_data->value_type, jb);
 
     sCallbackEnv->DeleteLocalRef(jb);
@@ -402,7 +403,8 @@
     CHECK_CALLBACK_ENV
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor
         , conn_id, status, SRVC_ID_PARAMS((&p_data->srvc_id))
-        , CHAR_ID_PARAMS((&p_data->char_id)), UUID_PARAMS((&p_data->descr_id)));
+        , GATT_ID_PARAMS((&p_data->char_id))
+        , GATT_ID_PARAMS((&p_data->descr_id)));
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
@@ -421,6 +423,14 @@
     checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
 }
 
+void btgattc_listen_cb(int status, int client_if)
+{
+    CHECK_CALLBACK_ENV
+    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientListen
+        , status, client_if);
+    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+}
+
 static const btgatt_client_callbacks_t sGattClientCallbacks = {
     btgattc_register_app_cb,
     btgattc_scan_result_cb,
@@ -438,7 +448,8 @@
     btgattc_read_descriptor_cb,
     btgattc_write_descriptor_cb,
     btgattc_execute_write_cb,
-    btgattc_remote_rssi_cb
+    btgattc_remote_rssi_cb,
+    btgattc_listen_cb
 };
 
 
@@ -645,11 +656,11 @@
     method_onExecuteCompleted = env->GetMethodID(clazz, "onExecuteCompleted",  "(II)V");
     method_onSearchCompleted = env->GetMethodID(clazz, "onSearchCompleted",  "(II)V");
     method_onSearchResult = env->GetMethodID(clazz, "onSearchResult", "(IIIJJ)V");
-    method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJJJI[B)V");
-    method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJJJ)V");
+    method_onReadDescriptor = env->GetMethodID(clazz, "onReadDescriptor", "(IIIIJJIJJIJJI[B)V");
+    method_onWriteDescriptor = env->GetMethodID(clazz, "onWriteDescriptor", "(IIIIJJIJJIJJ)V");
     method_onNotify = env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IIJJIJJZ[B)V");
     method_onGetCharacteristic = env->GetMethodID(clazz, "onGetCharacteristic", "(IIIIJJIJJI)V");
-    method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJJJ)V");
+    method_onGetDescriptor = env->GetMethodID(clazz, "onGetDescriptor", "(IIIIJJIJJIJJ)V");
     method_onGetIncludedService = env->GetMethodID(clazz, "onGetIncludedService", "(IIIIJJIIJJ)V");
     method_onRegisterForNotifications = env->GetMethodID(clazz, "onRegisterForNotifications", "(IIIIIJJIJJ)V");
     method_onReadRemoteRssi = env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
@@ -669,6 +680,7 @@
     method_onAttributeRead= env->GetMethodID(clazz, "onAttributeRead", "(Ljava/lang/String;IIIIZ)V");
     method_onAttributeWrite= env->GetMethodID(clazz, "onAttributeWrite", "(Ljava/lang/String;IIIIIZZ[B)V");
     method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
+    method_onClientListen = env->GetMethodID(clazz, "onClientListen", "(II)V");
 
     info("classInitNative: Success!");
 }
@@ -816,7 +828,7 @@
 
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
@@ -834,6 +846,7 @@
     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
     jint  char_id_inst_id,
     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
+    jint descr_id_inst_id,
     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb)
 {
     if (!sGattIf) return;
@@ -843,12 +856,13 @@
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
-    bt_uuid_t descr_id;
-    set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
+    btgatt_gatt_id_t descr_id;
+    descr_id.inst_id = (uint8_t) descr_id_inst_id;
+    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
 
     if (descr_id_uuid_lsb == 0)
     {
@@ -898,7 +912,7 @@
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
@@ -910,6 +924,7 @@
     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
     jint  char_id_inst_id,
     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
+    jint descr_id_inst_id,
     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
     jint authReq)
 {
@@ -920,12 +935,13 @@
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
-    bt_uuid_t descr_id;
-    set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
+    btgatt_gatt_id_t descr_id;
+    descr_id.inst_id = (uint8_t) descr_id_inst_id;
+    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
 
     sGattIf->client->read_descriptor(conn_id, &srvc_id, &char_id, &descr_id, authReq);
 }
@@ -944,7 +960,7 @@
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
@@ -969,22 +985,29 @@
     jlong service_id_uuid_lsb, jlong service_id_uuid_msb,
     jint char_id_inst_id,
     jlong char_id_uuid_lsb, jlong char_id_uuid_msb,
+    jint descr_id_inst_id,
     jlong descr_id_uuid_lsb, jlong descr_id_uuid_msb,
     jint write_type, jint auth_req, jbyteArray value)
 {
     if (!sGattIf) return;
 
+    if (value == NULL) {
+        warn("gattClientWriteDescriptorNative() ignoring NULL array");
+        return;
+    }
+
     btgatt_srvc_id_t srvc_id;
     srvc_id.id.inst_id = (uint8_t) service_id_inst_id;
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
-    bt_uuid_t descr_id;
-    set_uuid(descr_id.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
+    btgatt_gatt_id_t descr_id;
+    descr_id.inst_id = (uint8_t) descr_id_inst_id;
+    set_uuid(descr_id.uuid.uu, descr_id_uuid_msb, descr_id_uuid_lsb);
 
     uint16_t len = (uint16_t) env->GetArrayLength(value);
     jbyte *p_value = env->GetByteArrayElements(value, NULL);
@@ -1010,7 +1033,7 @@
     srvc_id.is_primary = (service_type == BTGATT_SERVICE_TYPE_PRIMARY ? 1 : 0);
     set_uuid(srvc_id.id.uuid.uu, service_id_uuid_msb, service_id_uuid_lsb);
 
-    btgatt_char_id_t char_id;
+    btgatt_gatt_id_t char_id;
     char_id.inst_id = (uint8_t) char_id_inst_id;
     set_uuid(char_id.uuid.uu, char_id_uuid_msb, char_id_uuid_lsb);
 
@@ -1035,6 +1058,27 @@
     sGattIf->client->read_remote_rssi(clientif, &bda);
 }
 
+static void gattClientListenNative(JNIEnv *env, jobject object,
+        jint client_if, jboolean start)
+{
+    if (!sGattIf) return;
+    sGattIf->client->listen(client_if, start);
+}
+
+static void gattSetAdvDataNative(JNIEnv *env, jobject object, jint client_if, jboolean setScanRsp,
+        jboolean inclName, jboolean inclTxPower, jint minInterval, jint maxInterval, jint appearance,
+        jbyteArray manufacturerData)
+{
+    if (!sGattIf) return;
+    jbyte* arr_data = env->GetByteArrayElements(manufacturerData, 0);
+    uint16_t arr_len = (uint16_t) env->GetArrayLength(manufacturerData);
+
+    sGattIf->client->set_adv_data(client_if, setScanRsp, inclName, inclTxPower,
+        minInterval, maxInterval, appearance, arr_len, (char*)arr_data);
+
+    env->ReleaseByteArrayElements(manufacturerData, arr_data, JNI_ABORT);
+}
+
 
 /**
  * Native server functions
@@ -1239,15 +1283,16 @@
     {"gattClientRefreshNative", "(ILjava/lang/String;)V", (void *) gattClientRefreshNative},
     {"gattClientSearchServiceNative", "(IZJJ)V", (void *) gattClientSearchServiceNative},
     {"gattClientGetCharacteristicNative", "(IIIJJIJJ)V", (void *) gattClientGetCharacteristicNative},
-    {"gattClientGetDescriptorNative", "(IIIJJIJJJJ)V", (void *) gattClientGetDescriptorNative},
+    {"gattClientGetDescriptorNative", "(IIIJJIJJIJJ)V", (void *) gattClientGetDescriptorNative},
     {"gattClientGetIncludedServiceNative", "(IIIJJIIJJ)V", (void *) gattClientGetIncludedServiceNative},
     {"gattClientReadCharacteristicNative", "(IIIJJIJJI)V", (void *) gattClientReadCharacteristicNative},
-    {"gattClientReadDescriptorNative", "(IIIJJIJJJJI)V", (void *) gattClientReadDescriptorNative},
+    {"gattClientReadDescriptorNative", "(IIIJJIJJIJJI)V", (void *) gattClientReadDescriptorNative},
     {"gattClientWriteCharacteristicNative", "(IIIJJIJJII[B)V", (void *) gattClientWriteCharacteristicNative},
-    {"gattClientWriteDescriptorNative", "(IIIJJIJJJJII[B)V", (void *) gattClientWriteDescriptorNative},
+    {"gattClientWriteDescriptorNative", "(IIIJJIJJIJJII[B)V", (void *) gattClientWriteDescriptorNative},
     {"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
     {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
     {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
+    {"gattClientListenNative", "(IZ)V", (void *) gattClientListenNative},
 
     {"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
     {"gattServerUnregisterAppNative", "(I)V", (void *) gattServerUnregisterAppNative},
@@ -1264,6 +1309,7 @@
     {"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
     {"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},
 
+    {"gattSetAdvDataNative", "(IZZZIII[B)V", (void *) gattSetAdvDataNative},
     {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
 };
 
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index be51cc5..d51b94e 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Kanselleer"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Skakel aan"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Lêeroordrag"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" wil <xliff:g id="FILE">%2$s</xliff:g> vir jou stuur (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Aanvaar die lêer?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" wil <xliff:g id="FILE">%2$s</xliff:g> vir jou stuur (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Aanvaar die lêer?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Wys af"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aanvaar"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Maak toe"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Onbekende lêer"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Daar is geen program om hierdie tipe lêer te hanteer nie. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Daar is geen program om hierdie tipe lêer te hanteer nie. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Geen lêers nie"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Die lêer bestaan nie. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Die lêer bestaan nie. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Wag asseblief…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Skakel tans Bluetooth aan…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Die lêer sal ontvang word. Kontroleer vordering in die Kennisgewings-paneel."</string>
diff --git a/res/values-af/strings_map.xml b/res/values-af/strings_map.xml
new file mode 100644
index 0000000..0ac25e1
--- /dev/null
+++ b/res/values-af/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Tik sessiesleutel in vir %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-sessiesleutel word benodig"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Die tyd het verstryk om verbinding met %1$s te aanvaar"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Die tyd om die sessiesleutel vir %1$s in te tik, het uitgetel"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex-stawingsversoek"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sessiesleutel"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Tik sessiesleutel in vir %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Motortoebehore"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Onbekende naam"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"My naam"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 914854b..82222ba 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -30,10 +30,10 @@
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
     <string name="bt_enable_line1" msgid="7203551583048149">"የብሉቱዝ አገልግሎት ለመጠቀም፣ መጀመሪያ ብሉቱዝን ያብሩ።"</string>
     <string name="bt_enable_line2" msgid="4341936569415937994">"ብሉቱዝ አሁን ይብራ?"</string>
-    <string name="bt_enable_cancel" msgid="1988832367505151727">"ይቅር"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"ሰርዝ"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"አብራ"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ፋይልሰደዳ"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>) ሊልኩልዎ ይፈልጋሉ፡ "\n\n" ፋይል ይቀበሉ?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>) ሊልኩልዎ ይፈልጋሉ፡ \n\n ፋይል ይቀበሉ?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"አትቀበል"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"ተቀበል"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"እሺ"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"ዝጋ"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"እሺ"</string>
     <string name="unknown_file" msgid="6092727753965095366">"ያልታወቀ ፋይል"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"ይህን ዓይነቱን ፋይል ለማስተናገድ የሚችል መተግበሪያ የለም:: "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"ይህን ዓይነቱን ፋይል ለማስተናገድ የሚችል መተግበሪያ የለም:: \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"ምንም ፋይሎች የሉም፡፡"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"ፋይል የለም:: "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"ፋይል የለም:: \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"እባክዎ ይጠብቁ…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"ብሉቱዝ በማብራት ላይ..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"ፋይሉ ይደርሳል።በማሳወቂያ ውስን ቦታ ውስጥ ሂደቱን ይመልከቱ።"</string>
diff --git a/res/values-am/strings_map.xml b/res/values-am/strings_map.xml
new file mode 100644
index 0000000..064a88e
--- /dev/null
+++ b/res/values-am/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"ለ%1$s የክፍለ ጊዜ ቁልፍ ይተይቡ"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"የብሉቱዝ  ክፍለ ጊዜ ቁልፍ ያስፈልጋል"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"ከ%1$s ግንኙነት ለመቀበል ጊዜው አብቅቶ ነበር።"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"ከ%1$s ጋር የክፍለ ጊዜ ቁልፍ ለማስገባት ጊዜው አለቆ ነበር።"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex ማረጋገጫ ጥያቄ"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"የክፍለ ጊዜ ቁልፍ"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"ለ%1$s የክፍለ ጊዜ ቁልፍ ይተይቡ"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"የመኪና መሣሪያ"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"ያልታወቀ ስም"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"የእኔ ስም"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 537e8fa..a98dda7 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"الدخول إلى إدارة التنزيل."</string>
-    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"للسماح للتطبيق بالدخول إلى إدارة BluetoothShare واستخدامها لنقل الملفات."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"‏للسماح للتطبيق بالدخول إلى إدارة BluetoothShare واستخدامها لنقل الملفات."</string>
     <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"إضافة وصول جهاز بلوتوث إلى القائمة البيضاء."</string>
     <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"يسمح للتطبيق مؤقتًا بإضافة جهاز بلوتوث إلى القائمة البيضاء مما يتيح لذلك الجهاز إرسال ملفات إلى هذا الجهاز بدون تأكيد المستخدم."</string>
     <string name="permlab_handoverStatus" msgid="7316032998801933554">"استلام عمليات البث المتعلقة بنقل إمكانية التحكم عبر البلوتوث."</string>
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"إلغاء"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"تشغيل"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"نقل الملف"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"يريد \"<xliff:g id="SENDER">%1$s</xliff:g>\" إرسال <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) لك. "\n\n" هل تقبل الملف؟"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"يريد \"<xliff:g id="SENDER">%1$s</xliff:g>\" إرسال <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) لك. \n\n هل تقبل الملف؟"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"رفض"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"قبول"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"موافق"</string>
@@ -73,19 +73,19 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"إغلاق"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"موافق"</string>
     <string name="unknown_file" msgid="6092727753965095366">"ملف غير معروف"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"ليس هناك تطبيق لمعالجة هذا النوع من الملفات. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"ليس هناك تطبيق لمعالجة هذا النوع من الملفات. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"ليست هناك أية ملفات"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"الملف غير موجود. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"الملف غير موجود. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"يرجى الانتظار…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"جارٍ تشغيل البلوتوث..."</string>
-    <string name="bt_toast_1" msgid="972182708034353383">"سيتم استلام الملف. تحقق من التقدم في لوحة التنبيهات."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"سيتم استلام الملف. تحقق من التقدم في لوحة الإشعارات."</string>
     <string name="bt_toast_2" msgid="8602553334099066582">"لا يمكن تلقي الملف."</string>
     <string name="bt_toast_3" msgid="6707884165086862518">"تم إيقاف استلام الملف من \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
     <string name="bt_toast_4" msgid="4678812947604395649">"إرسال الملف إلى \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
     <string name="bt_toast_5" msgid="2846870992823019494">"إرسال <xliff:g id="NUMBER">%1$s</xliff:g> من الملفات إلى \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
     <string name="bt_toast_6" msgid="1855266596936622458">"تم إيقاف إرسال الملف إلى \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
-    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"لا توجد مساحة كافية على وحدة تخزين USB لحفظ الملف من \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
-    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"لا توجد مساحة كافية على بطاقة SD لحفظ الملف من \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"‏لا توجد مساحة كافية على وحدة تخزين USB لحفظ الملف من \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"‏لا توجد مساحة كافية على بطاقة SD لحفظ الملف من \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
     <string name="bt_sm_2_2" msgid="2965243265852680543">"المساحة اللازمة: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="ErrorTooManyRequests" msgid="8578277541472944529">"تتم حاليًا معالجة طلبات كثيرة جدًا. حاول مرة أخرى لاحقًا."</string>
     <string name="status_pending" msgid="2503691772030877944">"لم يبدأ نقل الملف بعد."</string>
@@ -95,8 +95,8 @@
     <string name="status_forbidden" msgid="613956401054050725">"تم حظر النقل بواسطة الجهاز الهدف."</string>
     <string name="status_canceled" msgid="6664490318773098285">"تم إلغاء النقل بواسطة المستخدم."</string>
     <string name="status_file_error" msgid="3671917770630165299">"مشكلة في وحدة التخزين."</string>
-    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"ليس هناك وحدة تخزين USB."</string>
-    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"ليس هناك بطاقة SD. أدرج بطاقة SD لحفظ الملفات المنقولة."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"‏ليس هناك وحدة تخزين USB."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"‏ليس هناك بطاقة SD. أدرج بطاقة SD لحفظ الملفات المنقولة."</string>
     <string name="status_connection_error" msgid="947681831523219891">"لم يتم الاتصال بنجاح."</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"لا يمكن معالجة الطلب بشكل صحيح."</string>
     <string name="status_unknown_error" msgid="8156660554237824912">"خطأ غير معروف."</string>
diff --git a/res/values-ar/strings_map.xml b/res/values-ar/strings_map.xml
new file mode 100644
index 0000000..baed8c0
--- /dev/null
+++ b/res/values-ar/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"اكتب مفتاح الجلسة لـ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"يلزم مفتاح جلسة البلوتوث"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"انتهت مهلة قبول الاتصال مع %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"انتهت مهلة إدخال مفتاح الجلسة مع %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"طلب مصادقة Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"مفتاح الجلسة"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"اكتب مفتاح الجلسة لـ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"مجموعة أدوات السيارة"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"اسم غير معروف"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"اسمي"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ar/strings_pbap.xml b/res/values-ar/strings_pbap.xml
index c41a2b1..7dee306 100644
--- a/res/values-ar/strings_pbap.xml
+++ b/res/values-ar/strings_pbap.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"اكتب مفتاح الجلسة لـ %1$s"</string>
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"‏اكتب مفتاح الجلسة لـ %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"يلزم مفتاح جلسة البلوتوث"</string>
-    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"انتهت مهلة قبول الاتصال مع %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"انتهت مهلة إدخال مفتاح الجلسة مع %1$s"</string>
-    <string name="auth_notif_ticker" msgid="1575825798053163744">"طلب مصادقة Obex"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"‏انتهت مهلة قبول الاتصال مع %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"‏انتهت مهلة إدخال مفتاح الجلسة مع %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"‏طلب مصادقة Obex"</string>
     <string name="auth_notif_title" msgid="7599854855681573258">"مفتاح الجلسة"</string>
-    <string name="auth_notif_message" msgid="6667218116427605038">"اكتب مفتاح الجلسة لـ %1$s"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"‏اكتب مفتاح الجلسة لـ %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"مجموعة أدوات السيارة"</string>
     <string name="unknownName" msgid="2841414754740600042">"اسم غير معروف"</string>
     <string name="localPhoneName" msgid="2349001318925409159">"اسمي"</string>
diff --git a/res/values-ar/test_strings.xml b/res/values-ar/test_strings.xml
index 6f5d316..1b2b49c 100644
--- a/res/values-ar/test_strings.xml
+++ b/res/values-ar/test_strings.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="hello" msgid="1740533743008967039">"مرحبًا بالضيوف، TestActivity"</string>
+    <string name="hello" msgid="1740533743008967039">"‏مرحبًا بالضيوف، TestActivity"</string>
     <string name="app_name" msgid="1203877025577761792">"مشاركة البلوتوث"</string>
     <string name="insert_record" msgid="1450997173838378132">"إدراج سجل"</string>
     <string name="update_record" msgid="2480425402384910635">"تأكيد السجل"</string>
-    <string name="ack_record" msgid="6716152390978472184">"سجل Ack"</string>
+    <string name="ack_record" msgid="6716152390978472184">"‏سجل Ack"</string>
     <string name="deleteAll_record" msgid="4383349788485210582">"حذف السجل كله"</string>
     <string name="ok_button" msgid="6519033415223065454">"موافق"</string>
     <string name="delete_record" msgid="4645040331967533724">"حذف السجل"</string>
-    <string name="start_server" msgid="9034821924409165795">"بدء الخادم TCP"</string>
-    <string name="notify_server" msgid="4369106744022969655">"إعلام الخادم TCP"</string>
+    <string name="start_server" msgid="9034821924409165795">"‏بدء الخادم TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"‏إعلام الخادم TCP"</string>
 </resources>
diff --git a/res/values-az-rAZ/strings_map.xml b/res/values-az-rAZ/strings_map.xml
new file mode 100644
index 0000000..0b8584e
--- /dev/null
+++ b/res/values-az-rAZ/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s üçün seans açarı daxil edin"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth seans açarı tələb olunur"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s ilə bağlantı qəbul edərkən fasilə yarandı"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s ilə seans açarını daxil edərkən fasilə yarandı"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex təsdiqləmə sorğusu"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Seans Açarı"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s üçün seans açarı daxil edin"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Maşın dəsti"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Naməlum ad"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mənim adım"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-az/strings_map.xml b/res/values-az/strings_map.xml
new file mode 100644
index 0000000..0b8584e
--- /dev/null
+++ b/res/values-az/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s üçün seans açarı daxil edin"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth seans açarı tələb olunur"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s ilə bağlantı qəbul edərkən fasilə yarandı"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s ilə seans açarını daxil edərkən fasilə yarandı"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex təsdiqləmə sorğusu"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Seans Açarı"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s üçün seans açarı daxil edin"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Maşın dəsti"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Naməlum ad"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mənim adım"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 74b93e7..7b3810b 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Адмяніць"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Уключыць"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Перадача файлаў"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Адпраўнік \"<xliff:g id="SENDER">%1$s</xliff:g>\" хоча адправіць вам файл <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Прыняць?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Адпраўнік \"<xliff:g id="SENDER">%1$s</xliff:g>\" хоча адправіць вам файл <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Прыняць?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Адхіліць"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Прыняць"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ОК"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Закрыць"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"ОК"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Невядомы файл"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Няма прыкладанняў для апрацоўкі файлаў гэтага тыпу. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Няма прыкладанняў для апрацоўкі файлаў гэтага тыпу. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"няма файла"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не існуе. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не існуе. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Чакайце..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Уключэнне Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Файл будзе атрыманы. Сачыце за прагрэсам на панэлі апавяшчэнняў."</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 62e2e0f..216ad2e 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Отказ"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Включване"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Прехвърляне на файл"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ иска да ви изпрати <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Приемате ли файла?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ иска да ви изпрати <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Приемате ли файла?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Отхвърляне"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Приемане"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Затваряне"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Неизвестен файл"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Няма приложение, което работи с този тип файлове. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Няма приложение, което работи с този тип файлове. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Няма файл"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файлът не съществува. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файлът не съществува. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Моля, изчакайте…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth се включва..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Файлът ще бъде получен. Проверете хода в панела за известия."</string>
diff --git a/res/values-bg/strings_map.xml b/res/values-bg/strings_map.xml
new file mode 100644
index 0000000..7e7250a
--- /dev/null
+++ b/res/values-bg/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Въведете ключ за сесия за %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Изисква се ключ за сесия с Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Времето за изчакване за приемане на връзката с/ъс %1$s изтече"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Времето за изчакване за въвеждане на ключ за сесия със %1$s изтече"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Заявка за удостоверяване на Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ключ за сесия"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Въведете ключ за сесия за %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Комплект за автомобил"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Неизвестно име"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Моето име"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index e585b94..b922e64 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel·la"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activa"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferència del fitxer"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" et vol enviar <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Acceptes el fitxer?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" et vol enviar <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Acceptes el fitxer?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rebutja"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accepta"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"D\'acord"</string>
@@ -42,7 +42,7 @@
     <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Vols rebre aquest fitxer?"</string>
     <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Està entrant un fitxer d\'un altre dispositiu. Confirma que vols rebre el fitxer."</string>
     <string name="notification_receiving" msgid="4674648179652543984">"Ús compartit de Bluetooth: s\'està rebent <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_received" msgid="3324588019186687985">"Ús compartit de Bluetooth: s\'ha rebut <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Compartir amb Bluetooth: <xliff:g id="FILE">%1$s</xliff:g> rebut"</string>
     <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth compartit: fitxer <xliff:g id="FILE">%1$s</xliff:g> no rebut"</string>
     <string name="notification_sending" msgid="3035748958534983833">"Ús compartit de Bluetooth: s\'està enviant <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="notification_sent" msgid="9218710861333027778">"Ús compartit de Bluetooth: s\'ha enviat <xliff:g id="FILE">%1$s</xliff:g>"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Tanca"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"D\'acord"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Fitxer desconegut"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"No hi ha cap aplicació per gestionar aquest tipus de fitxer. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"No hi ha cap aplicació per gestionar aquest tipus de fitxer. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Cap fitxer"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"El fitxer no existeix. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"El fitxer no existeix. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Espereu…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"S\'està activant el Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"El fitxer es rebrà. Comproveu-ne el progrés al tauler de notificacions."</string>
@@ -100,7 +100,7 @@
     <string name="status_connection_error" msgid="947681831523219891">"Connexió incorrecta."</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"La sol·licitud no es pot processar correctament."</string>
     <string name="status_unknown_error" msgid="8156660554237824912">"Error desconegut."</string>
-    <string name="btopp_live_folder" msgid="7967791481444474554">"S\'ha rebut Bluetooth"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Rebut per Bluetooth"</string>
     <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g>: recepció completa."</string>
     <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g>: enviament complet."</string>
     <string name="inbound_history_title" msgid="6940914942271327563">"Transferències d\'entrada"</string>
diff --git a/res/values-ca/strings_map.xml b/res/values-ca/strings_map.xml
new file mode 100644
index 0000000..e63faa2
--- /dev/null
+++ b/res/values-ca/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Introdueix la clau de sessió per a %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Es necessita la clau de sessió Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"S\'ha esgotat el temps per acceptar la connexió amb %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"S\'ha esgotat el temps per a l\'entrada de la clau de sessió amb %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Sol·licitud d\'autenticació Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Clau de sessió"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Introdueix la clau de sessió per a %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Equip per a l\'automòbil"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nom desconegut"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"El meu nom"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 8805e2a..50e5da8 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Zrušit"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Zapnout"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Přenos souborů"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Uživatel <xliff:g id="SENDER">%1$s</xliff:g> se vám pokouší odeslat soubor <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Chcete soubor přijmout?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Uživatel <xliff:g id="SENDER">%1$s</xliff:g> se vám pokouší odeslat soubor <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Chcete soubor přijmout?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Odmítnout"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Přijmout"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Zavřít"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Neznámý soubor"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Žádná aplikace nedokáže s tímto typem souboru pracovat. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Žádná aplikace nedokáže s tímto typem souboru pracovat. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Žádný soubor"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Soubor neexistuje. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Soubor neexistuje. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Čekejte prosím..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Zapínání Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Proběhne přijímání souboru. Průběh můžete sledovat na panelu Oznámení."</string>
diff --git a/res/values-cs/strings_map.xml b/res/values-cs/strings_map.xml
new file mode 100644
index 0000000..f8ee413
--- /dev/null
+++ b/res/values-cs/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Zadejte klíč relace pro zařízení %1$s."</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Je požadován klíč relace Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Časový limit pro přijetí spojení se zařízením %1$s vypršel."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Časový limit zadání klíče relace pro %1$s vypršel."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Požadavek ověření Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Klíč relace"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Zadejte klíč relace pro zařízení %1$s."</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Sada handsfree do auta"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Neznámý název"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mé jméno"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index ae13ba5..ef515d3 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Annuller"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Slå til"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Filoverførsel"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vil sende <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) til dig. "\n\n" Vil du modtage filen?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vil sende <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) til dig. \n\n Vil du modtage filen?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Afvis"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accepter"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,12 +73,12 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Luk"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Ukendt fil"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Der er ingen app til at håndtere denne filtype. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Der er ingen app til at håndtere denne filtype. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ingen fil"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen findes ikke. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen findes ikke. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Vent..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Aktiverer Bluetooth..."</string>
-    <string name="bt_toast_1" msgid="972182708034353383">"Filen modtages. Se status i meddelelsespanelet."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"Filen modtages. Se status i underretningspanelet."</string>
     <string name="bt_toast_2" msgid="8602553334099066582">"Filen kan ikke modtages."</string>
     <string name="bt_toast_3" msgid="6707884165086862518">"Modtagelse af fil fra \"<xliff:g id="SENDER">%1$s</xliff:g>\" stoppet"</string>
     <string name="bt_toast_4" msgid="4678812947604395649">"Sender filen til \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
diff --git a/res/values-da/strings_map.xml b/res/values-da/strings_map.xml
new file mode 100644
index 0000000..3adec1c
--- /dev/null
+++ b/res/values-da/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Indtast sessionsnøgle til %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-sessionsnøgle kræves"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Der var timeout ved forbindelsen med %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Der opstod timeout i indgangssessionnøgle med %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Anmodning om Obex-godkendelse"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sessionstast"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Indtast sessionsnøgle til %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Bilsæt"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Ukendt navn"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mit navn"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 8d01f8e..fe1194f 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -18,8 +18,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Auf Download-Manager zugreifen"</string>
     <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Ermöglicht der App, auf den Bluetooth-Weiterleitungs-Manager zuzugreifen und diesen für die Übertragung von Dateien zu verwenden."</string>
-    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Bluetooth-Gerät für Zugriff zur Whitelist hinzufügen"</string>
-    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Ermöglicht der App, ein Bluetooth-Gerät vorübergehend zur Whitelist hinzuzufügen, sodass es ohne Bestätigung des Nutzers Dateien an dieses Gerät senden kann"</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Bluetooth-Gerät für Zugriff zur weißen Liste hinzufügen"</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Ermöglicht der App, ein Bluetooth-Gerät vorübergehend zur weißen Liste hinzuzufügen, sodass es ohne Bestätigung des Nutzers Dateien an dieses Gerät senden kann"</string>
     <string name="permlab_handoverStatus" msgid="7316032998801933554">"Bluetooth-Broadcasts zur Übertragung empfangen"</string>
     <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Ermöglicht den Empfang von Statusinformationen zur Übertragung per Bluetooth"</string>
     <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Abbrechen"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Aktivieren"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Dateiübertragung"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" möchte Ihnen <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) senden. "\n\n" Datei annehmen?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" möchte Ihnen <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) senden. \n\n Datei annehmen?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Ablehnen"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Akzeptieren"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Schließen"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Unbekannte Datei"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Dieser Dateityp kann von keiner App verarbeitet werden. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Dieser Dateityp kann von keiner App verarbeitet werden. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Keine Datei"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Die Datei ist nicht vorhanden. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Die Datei ist nicht vorhanden. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Bitte warten..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth wird aktiviert..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Die Datei wird empfangen. Überprüfen Sie den Fortschritt in der Benachrichtigungskonsole."</string>
diff --git a/res/values-de/strings_map.xml b/res/values-de/strings_map.xml
new file mode 100644
index 0000000..ed6f4ed
--- /dev/null
+++ b/res/values-de/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Sitzungsschlüssel für %1$s eingeben"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-Sitzungsschlüssel erforderlich"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Die Zeit zum Verbindungsaufbau mit %1$s ist abgelaufen."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Die Zeit zur Eingabe des Sitzungsschlüssels bei %1$s ist abgelaufen."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"OBEX-Authentifizierungsanfrage"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sitzungsschlüssel"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Sitzungsschlüssel für %1$s eingeben"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Unbekannter Name"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mein Name"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 3f3c834..014756c 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Ακύρωση"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Ενεργοποίηση"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Μεταφορά αρχείου"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Ο αποστολέας \"<xliff:g id="SENDER">%1$s</xliff:g>\" θέλει να σας στείλει το <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Αποδοχή του αρχείου;"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Ο αποστολέας \"<xliff:g id="SENDER">%1$s</xliff:g>\" θέλει να σας στείλει το <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Αποδοχή του αρχείου;"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Απόρριψη"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Αποδοχή"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Κλείσιμο"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"ΟΚ"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Άγνωστο αρχείο"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Δεν υπάρχει καμία εφαρμογή για τη διαχείριση αυτού του τύπου αρχείου. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Δεν υπάρχει καμία εφαρμογή για τη διαχείριση αυτού του τύπου αρχείου. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Κανένα αρχείο"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Το αρχείο δεν υπάρχει. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Το αρχείο δεν υπάρχει. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Περιμένετε..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Ενεργοποίηση Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Θα γίνει λήψη του αρχείου. Ελέγξτε την πρόοδο στο πλαίσιο \"Ειδοποιήσεις\"."</string>
diff --git a/res/values-el/strings_map.xml b/res/values-el/strings_map.xml
new file mode 100644
index 0000000..62cf54d
--- /dev/null
+++ b/res/values-el/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Πληκτρολογήστε το κλειδί περιόδου σύνδεσης για %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Απαιτείται κλειδί περιόδου σύνδεσης Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Έγινε λήξη χρονικού ορίου για την αποδοχή της σύνδεσης με %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Έγινε λήξη χρονικού ορίου για την εισαγωγή κλειδιού περιόδου σύνδεσης με %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Αίτημα ελέγχου ταυτότητας Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Κλειδί περιόδου σύνδεσης"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Πληκτρολογήστε το κλειδί περιόδου σύνδεσης για %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Κιτ αυτοκινήτου"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Άγνωστο όνομα"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Το όνομά μου"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 47ebdee..6141acf 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Turn on"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"File transfer"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" wants to send you <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Accept the file?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" wants to send you <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Accept the file?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Decline"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accept"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Close"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Unknown file"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"There\'s no app to handle this type of file. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"There\'s no app to handle this type of file. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"No file"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"The file doesn\'t exist. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"The file doesn\'t exist. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Please wait…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Turning on Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"The file will be received. Check progress in the Notifications panel."</string>
diff --git a/res/values-en-rGB/strings_map.xml b/res/values-en-rGB/strings_map.xml
new file mode 100644
index 0000000..0807e6e
--- /dev/null
+++ b/res/values-en-rGB/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Type session key for %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth session key required"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"There was time out to accept connection with %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"There was time out to input session key with %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex authentication request"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Session Key"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Type session key for %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Car Kit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Unknown name"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"My name"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..6141acf
--- /dev/null
+++ b/res/values-en-rIN/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Access download manager."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Allows the application to access the Bluetooth Share manager and to use it to transfer files."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Whitelist bluetooth device access."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Allows the app to temporarily whitelist a Bluetooth device, allowing that device to send files to this device without user confirmation."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"Receive BT handover transfer broadcasts."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Allows receiving handover transfer status information from Bluetooth."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Unknown device"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Unknown"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Aeroplane mode"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"You can\'t use Bluetooth in Aeroplane mode."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"To use Bluetooth services, you must first turn on Bluetooth."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Turn on Bluetooth now?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Turn on"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"File transfer"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" wants to send you <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Accept the file?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Decline"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accept"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"There was a timeout while accepting an incoming file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth share: Incoming file"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Do you want to receive this file?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Incoming file from another device. Confirm that you want to receive this file."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth share: Receiving <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Bluetooth share: Received <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not received"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Bluetooth share: Sending <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Bluetooth share: Sent <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100% complete"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth share: File <xliff:g id="FILE">%1$s</xliff:g> not sent"</string>
+    <string name="download_title" msgid="3353228219772092586">"File transfer"</string>
+    <string name="download_line1" msgid="4926604799202134144">"From: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"File size: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Receiving file…"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Stop"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Hide"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"File not received"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Reason: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"File received"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Open"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"To: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"File type: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Sending file…"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"File sent"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"The file wasn\'t sent to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\"."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"File: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Try again"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Close"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Unknown file"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"There\'s no app to handle this type of file. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"No file"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"The file doesn\'t exist. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Please wait…"</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Turning on Bluetooth…"</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"The file will be received. Check progress in the Notifications panel."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"The file can\'t be received."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"Stopped receiving file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"Sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"Sending <xliff:g id="NUMBER">%1$s</xliff:g> files to \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"Stopped sending file to \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"There isn\'t enough space in USB storage to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"There isn\'t enough space on the SD card to save the file from \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Space needed: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Too many requests are being processed. Try again later."</string>
+    <string name="status_pending" msgid="2503691772030877944">"File transfer not started yet"</string>
+    <string name="status_running" msgid="6562808920311008696">"File transfer is ongoing."</string>
+    <string name="status_success" msgid="239573225847565868">"File transfer completed successfully."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Content isn\'t supported."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"Transfer forbidden by target device."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Transfer cancelled by user."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Storage issue"</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"No USB storage."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"No SD card. Insert an SD card to save transferred files."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Connection unsuccessful."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Request can\'t be handled correctly."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Unknown error."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth received"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Received complete."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Sent complete."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Inbound transfers"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Outbound transfers"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"Browser history is empty."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"All items will be cleared from the list."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth share: Sent files"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth share: Received files"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> successful, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> unsuccessful."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Clear list"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"Open"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Clear from list"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Clear"</string>
+</resources>
diff --git a/res/values-en-rIN/strings_map.xml b/res/values-en-rIN/strings_map.xml
new file mode 100644
index 0000000..0807e6e
--- /dev/null
+++ b/res/values-en-rIN/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Type session key for %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth session key required"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"There was time out to accept connection with %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"There was time out to input session key with %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex authentication request"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Session Key"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Type session key for %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Car Kit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Unknown name"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"My name"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-en-rIN/strings_pbap.xml b/res/values-en-rIN/strings_pbap.xml
new file mode 100644
index 0000000..e22854e
--- /dev/null
+++ b/res/values-en-rIN/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Type session key for %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth session key required"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"There was time out to accept connection with %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was time out to input session key with %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Session Key"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"Type session key for %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Car Kit"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"My name"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-en-rIN/test_strings.xml b/res/values-en-rIN/test_strings.xml
new file mode 100644
index 0000000..5eea26e
--- /dev/null
+++ b/res/values-en-rIN/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Hello World, TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"Bluetooth Share"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Insert record"</string>
+    <string name="update_record" msgid="2480425402384910635">"Confirm record"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Ack record"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Delete all record"</string>
+    <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Delete record"</string>
+    <string name="start_server" msgid="9034821924409165795">"Start TCP server"</string>
+    <string name="notify_server" msgid="4369106744022969655">"Notify TCP server"</string>
+</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index c44c55e..ad6130f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancelar"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activar"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferencia de archivo"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" desea enviarte <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" ¿Aceptas el archivo?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" desea enviarte <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n ¿Aceptas el archivo?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rechazar"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aceptar"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Aceptar"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Cerrar"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Aceptar"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Archivo desconocido"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"No hay ninguna aplicación que pueda procesar este tipo de archivo. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"No hay ninguna aplicación que pueda procesar este tipo de archivo. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"No hay archivos"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"El archivo no existe. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"El archivo no existe. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Por favor, espera..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Activando Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"El archivo será recibido. Verifica el progreso en el panel de notificaciones."</string>
diff --git a/res/values-es-rUS/strings_map.xml b/res/values-es-rUS/strings_map.xml
new file mode 100644
index 0000000..cb57328
--- /dev/null
+++ b/res/values-es-rUS/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Escribe la clave de la sesión para %1$s."</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Se requiere la clave de la sesión de Bluetooth."</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Se agotó el tiempo de espera para aceptar la conexión con %1$s."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Se agotó el tiempo de espera para ingresar la clave de la sesión con %1$s."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Solicitud de autenticación de Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Clave de la sesión"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Escribe la clave de la sesión para %1$s."</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit de automóvil"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nombre desconocido"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mi nombre"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 5921493..eec8148 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancelar"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activar"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferencia de archivos"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" quiere enviarte <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" ¿Aceptas el archivo?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" quiere enviarte <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>). \n\n ¿Aceptas el archivo?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rechazar"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aceptar"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Aceptar"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Cerrar"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Aceptar"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Archivo desconocido"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"No hay ninguna aplicación que pueda procesar este tipo de archivo. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"No hay ninguna aplicación que pueda procesar este tipo de archivo. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"No hay archivos."</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"El archivo no existe. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"El archivo no existe. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Por favor, espera..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Activando Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Se recibirá el archivo. Comprueba el progreso en la barra de notificaciones."</string>
diff --git a/res/values-es/strings_map.xml b/res/values-es/strings_map.xml
new file mode 100644
index 0000000..cae85e1
--- /dev/null
+++ b/res/values-es/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Introducir clave de sesión para %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Se necesita la clave de sesión de Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Se ha agotado el tiempo para aceptar la conexión con %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Se ha agotado el tiempo para introducir la clave de sesión con %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Solicitud de autenticación de Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Clave de sesión"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Introducir clave de sesión para %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nombre desconocido"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mi nombre"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..a762536
--- /dev/null
+++ b/res/values-et-rEE/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Pääs allalaadimishalduri juurde."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Võimaldab rakendusel pääseda BluetoothShare\'i haldurisse ja kasutada seda failide edastamiseks."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Lubage Bluetooth-seadme juurdepääs."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Lubab rakendusel lisada Bluetooth-seadme ajutiselt lubatud seadmete loendisse, mis võimaldab seadmel saata faile sellesse seadmesse ilma kasutaja kinnituseta."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"Võta vastu BT-üleandmise edastusi."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Võimaldab võtta vastu Bluetoothi üleandmise olekuteavet."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Tundmatu seade"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Tundmatu"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Lennurežiim"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Te ei saa Bluetoothi lennukirežiimis kasutada."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Bluetoothi teenuste kasutamiseks peate esmalt Bluetoothi sisse lülitama."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Lülitan Bluetoothi kohe sisse?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Tühista"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Lülita sisse"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Failiedastus"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> soovib teile saata faili <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Võtan faili vastu?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Keeldu"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Nõustun"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"Esines ajalõpp sissetuleva faili aktsepteerimisel saatjalt „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetoothi jagamine: sissetulev fail"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Kas soovite selle faili vastu võtta?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Sissetulev fail teisest seadmest. Kinnitage, et soovite selle faili vastu võtta."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Bluetoothi jagamine: faili <xliff:g id="FILE">%1$s</xliff:g> vastuvõtmine"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Bluetoothi jagamine: <xliff:g id="FILE">%1$s</xliff:g> vastu võetud"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Bluetoothi jagamine: faili <xliff:g id="FILE">%1$s</xliff:g> pole saadud"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Bluetoothi jagamine: faili <xliff:g id="FILE">%1$s</xliff:g> saatmine"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Bluetoothi jagamine: fail <xliff:g id="FILE">%1$s</xliff:g> saadetud"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100% lõpetatud"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetoothi jagamine: faili <xliff:g id="FILE">%1$s</xliff:g> ei saadetud"</string>
+    <string name="download_title" msgid="3353228219772092586">"Failiedastus"</string>
+    <string name="download_line1" msgid="4926604799202134144">"Saatja: „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
+    <string name="download_line2" msgid="5876973543019417712">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"Faili suurus: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Faili vastuvõtmine ..."</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Peata"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Peida"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"Faili ei saadud"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Põhjus: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"Fail vastu võetud"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Ava"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"Saaja: „<xliff:g id="RECIPIENT">%1$s</xliff:g>”"</string>
+    <string name="upload_line3" msgid="4920689672457037437">"Faili tüüp: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Faili saatmine ..."</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"Fail saadetud"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"Faili ei saadetud kasutajale „<xliff:g id="RECIPIENT">%1$s</xliff:g>”."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Proovige uuesti"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Sulge"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Tundmatu fail"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Seda tüüpi faili käsitlemiseks pole sobivat rakendust. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"Fail puudub"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Faili ei ole olemas. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Palun oodake ..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetoothi sisselülitamine ..."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"Fail võetakse vastu. Vaadake edenemist teatiste paneelil."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"Faili ei saa vastu võtta."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"Faili vastuvõtmine saatjalt „<xliff:g id="SENDER">%1$s</xliff:g>” peatatud"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"Faili saatmine saajale „<xliff:g id="RECIPIENT">%1$s</xliff:g>”"</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"<xliff:g id="NUMBER">%1$s</xliff:g> faili saatmine saajale „<xliff:g id="RECIPIENT">%2$s</xliff:g>”"</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"Faili saatmine saajale „<xliff:g id="RECIPIENT">%1$s</xliff:g>” peatatud"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"USB-mäluseadmes pole saatjalt „<xliff:g id="SENDER">%1$s</xliff:g>” saadud faili salvestamiseks piisavalt ruumi"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"SD-kaardil pole saatjalt „<xliff:g id="SENDER">%1$s</xliff:g>” saadud faili salvestamiseks piisavalt ruumi"</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Vajalik ruum: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Liiga palju taotlusi on töötlemisel. Proovige hiljem uuesti."</string>
+    <string name="status_pending" msgid="2503691772030877944">"Failiedastust pole veel käivitatud."</string>
+    <string name="status_running" msgid="6562808920311008696">"Failiedastus on pooleli."</string>
+    <string name="status_success" msgid="239573225847565868">"Failiedastuse lõpuleviimine õnnestus."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Sisu ei toetata."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"Sihtseade on edastuse keelanud."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Kasutaja tühistas edastuse."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Probleem talletamisega."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"USB-mäluseadet ei leita."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD-kaart puudub. Edastatud failide salvestamiseks sisestage SD-kaart."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Ühendus ebaõnnestus."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Taotlust ei saa õigesti käsitleda."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Tundmatu viga."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth vastu võetud"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> vastuvõtmine lõpetatud."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> saatmine lõpetatud."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Sissetulevad edastused"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Väljuvad edastused"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"Edastusajalugu on tühi."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Kõik üksused eemaldatakse loendist."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetoothi jagamine: saadetud failid"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetoothi jagamine: vastuvõetud failid"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> õnnestus, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> ebaõnnestus."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Tühjendage loend"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"Ava"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Eemaldage loendist"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Kustuta"</string>
+</resources>
diff --git a/res/values-et-rEE/strings_map.xml b/res/values-et-rEE/strings_map.xml
new file mode 100644
index 0000000..8fe1642
--- /dev/null
+++ b/res/values-et-rEE/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Sisestage seansivõti seadmele %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Vajalik Bluetoothi seansivõti"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Esines ajalõpp ühenduse aktsepteerimiseks seadmega %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Esines ajalõpp seansivõtme sisestamiseks seadmele %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obexi autentimise taotlus"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Seansivõti"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Sisestage seansivõti seadmele %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Autokomplekt"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Tundmatu nimi"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Minu nimi"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-et-rEE/strings_pbap.xml b/res/values-et-rEE/strings_pbap.xml
new file mode 100644
index 0000000..0346c28
--- /dev/null
+++ b/res/values-et-rEE/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Sisestage seansivõti failile %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Vajalik Bluetoothi seansivõti"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"Esines ajalõpp ühenduse aktsepteerimiseks seadmega %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"Esines ajalõpp sisendseansivõtmele failiga %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Obexi autentimise taotlus"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Seansivõti"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"Sisestage seansivõti failile %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Autokomplekt"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Tundmatu nimi"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"Minu nimi"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-et-rEE/test_strings.xml b/res/values-et-rEE/test_strings.xml
new file mode 100644
index 0000000..9da0688
--- /dev/null
+++ b/res/values-et-rEE/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Tere, maailm, TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"Bluetoothi jagamine"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Sisestage kirje"</string>
+    <string name="update_record" msgid="2480425402384910635">"Kinnita kirje"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Acki kirje"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Kustuta kõik kirjed"</string>
+    <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Kustuta kirje"</string>
+    <string name="start_server" msgid="9034821924409165795">"Käivita TCP-server"</string>
+    <string name="notify_server" msgid="4369106744022969655">"Teavita TCP-serverit"</string>
+</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 13ef94a..a762536 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Tühista"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Lülita sisse"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Failiedastus"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> soovib teile saata faili <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Võtan faili vastu?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> soovib teile saata faili <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Võtan faili vastu?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Keeldu"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Nõustun"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Sulge"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Tundmatu fail"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Seda tüüpi faili käsitlemiseks pole sobivat rakendust. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Seda tüüpi faili käsitlemiseks pole sobivat rakendust. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Fail puudub"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Faili ei ole olemas. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Faili ei ole olemas. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Palun oodake ..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetoothi sisselülitamine ..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Fail võetakse vastu. Vaadake edenemist teatiste paneelil."</string>
diff --git a/res/values-et/strings_map.xml b/res/values-et/strings_map.xml
new file mode 100644
index 0000000..8fe1642
--- /dev/null
+++ b/res/values-et/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Sisestage seansivõti seadmele %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Vajalik Bluetoothi seansivõti"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Esines ajalõpp ühenduse aktsepteerimiseks seadmega %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Esines ajalõpp seansivõtme sisestamiseks seadmele %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obexi autentimise taotlus"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Seansivõti"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Sisestage seansivõti seadmele %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Autokomplekt"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Tundmatu nimi"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Minu nimi"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index bf30321..7fc53fa 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"دسترسی به Download Manager."</string>
-    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"به برنامه برای دسترسی به مدیر BluetoothShare و استفاده از آن برای انتقال فایل‌ها اجازه می‌دهد."</string>
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"‏دسترسی به Download Manager."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"‏به برنامه برای دسترسی به مدیر BluetoothShare و استفاده از آن برای انتقال فایل‌ها اجازه می‌دهد."</string>
     <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"دسترسی دستگاه موجود در لیست سفید بلوتوث."</string>
     <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"به برنامه اجازه می‌دهد تا موقتاً یک دستگاه بلوتوث را در لیست سفید وارد کند، و به آن دستگاه اجازه می‌دهد بدون تأیید کاربر به این دستگاه فایل ارسال کند."</string>
     <string name="permlab_handoverStatus" msgid="7316032998801933554">"دریافت پخش‌های عمومی انتقالی از بلوتوث."</string>
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"لغو"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"روشن کردن"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"انتقال فایل"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" می‌خواهد <xliff:g id="FILE">%2$s</xliff:g> را به شما ارسال کند. (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" فایل را می‌پذیرید؟"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" می‌خواهد <xliff:g id="FILE">%2$s</xliff:g> را به شما ارسال کند. (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n فایل را می‌پذیرید؟"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"عدم پذیرش"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"پذیرش"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"تأیید"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"بستن"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"تأیید"</string>
     <string name="unknown_file" msgid="6092727753965095366">"فایل ناشناس"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"هیچ برنامه‌ای برای کار با این نوع فایل وجود ندارد."\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"هیچ برنامه‌ای برای کار با این نوع فایل وجود ندارد.\n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"فایلی وجود ندارد"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"فایل موجود نیست. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"فایل موجود نیست. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"لطفاً منتظر بمانید…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"روشن کردن بلوتوث..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"فایل دریافت می‌شود: پیشرفت دریافت را در پانل اعلان‌ها بررسی کنید."</string>
@@ -84,8 +84,8 @@
     <string name="bt_toast_4" msgid="4678812947604395649">"ارسال فایل به \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
     <string name="bt_toast_5" msgid="2846870992823019494">"ارسال <xliff:g id="NUMBER">%1$s</xliff:g> فایل به \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
     <string name="bt_toast_6" msgid="1855266596936622458">"ارسال فایل به \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" متوقف شد"</string>
-    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"برای ذخیره فایل از \"<xliff:g id="SENDER">%1$s</xliff:g>\" فضای کافی در حافظهٔ USB موجود نیست"</string>
-    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"برای ذخیره فایل \"<xliff:g id="SENDER">%1$s</xliff:g>\" فضای کافی در کارت SD موجود نیست"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"‏برای ذخیره فایل از \"<xliff:g id="SENDER">%1$s</xliff:g>\" فضای کافی در حافظهٔ USB موجود نیست"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"‏برای ذخیره فایل \"<xliff:g id="SENDER">%1$s</xliff:g>\" فضای کافی در کارت SD موجود نیست"</string>
     <string name="bt_sm_2_2" msgid="2965243265852680543">"فضای مورد نیاز: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="ErrorTooManyRequests" msgid="8578277541472944529">"درخواست‌های بسیاری در حال انجام هستند. بعداً دوباره امتحان کنید."</string>
     <string name="status_pending" msgid="2503691772030877944">"انتقال فایل هنوز شروع نشده است."</string>
@@ -95,8 +95,8 @@
     <string name="status_forbidden" msgid="613956401054050725">"انتقال توسط دستگاه مقصد ممنوع شده است."</string>
     <string name="status_canceled" msgid="6664490318773098285">"انتقال توسط کاربر لغو شد."</string>
     <string name="status_file_error" msgid="3671917770630165299">"مشکل ذخیره."</string>
-    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"حافظهٔ USB وجود ندارد."</string>
-    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"هیچ کارت SD موجود نیست. برای ذخیره فایل‌های منتقل شده، یک کارت SD در گوشی قرار دهید."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"‏حافظهٔ USB وجود ندارد."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"‏هیچ کارت SD موجود نیست. برای ذخیره فایل‌های منتقل شده، یک کارت SD در گوشی قرار دهید."</string>
     <string name="status_connection_error" msgid="947681831523219891">"اتصال ناموفق بود."</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"درخواست به درستی انجام نمی‌شود."</string>
     <string name="status_unknown_error" msgid="8156660554237824912">"خطای ناشناخته."</string>
diff --git a/res/values-fa/strings_map.xml b/res/values-fa/strings_map.xml
new file mode 100644
index 0000000..30cce9d
--- /dev/null
+++ b/res/values-fa/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"کلید جلسه را برای %1$s تایپ کنید"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"کلید جلسه بلوتوث مورد نیاز است"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"زمان پذیرش اتصال به %1$s به پایان رسید"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"زمان وارد کردن کلید جلسه با %1$s به پایان رسید"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"درخواست تأیید اعتبار Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"کلید جلسه"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"کلید جلسه را برای %1$s تایپ کنید"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"کیت خودرو"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"نام ناشناس"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"نام من"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-fa/strings_pbap.xml b/res/values-fa/strings_pbap.xml
index cd434d7..bc68a89 100644
--- a/res/values-fa/strings_pbap.xml
+++ b/res/values-fa/strings_pbap.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"تایپ کلید جلسه برای %1$s"</string>
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"‏تایپ کلید جلسه برای %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"به کلید جلسه بلوتوث نیاز است"</string>
-    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"هنگام پذیرش اتصال به %1$s وقفه زمانی ایجاد شده است"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"هنگام ورود کلید جلسه با %1$s وقفه زمانی ایجاد شده است"</string>
-    <string name="auth_notif_ticker" msgid="1575825798053163744">"درخواست تأیید اعتبار Obex"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"‏هنگام پذیرش اتصال به %1$s وقفه زمانی ایجاد شده است"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"‏هنگام ورود کلید جلسه با %1$s وقفه زمانی ایجاد شده است"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"‏درخواست تأیید اعتبار Obex"</string>
     <string name="auth_notif_title" msgid="7599854855681573258">"کلید جلسه"</string>
-    <string name="auth_notif_message" msgid="6667218116427605038">"تایپ کلید جلسه برای %1$s"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"‏تایپ کلید جلسه برای %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"کیت خودرو"</string>
     <string name="unknownName" msgid="2841414754740600042">"نام ناشناس"</string>
     <string name="localPhoneName" msgid="2349001318925409159">"نام من"</string>
diff --git a/res/values-fa/test_strings.xml b/res/values-fa/test_strings.xml
index 49670e5..000f3f7 100644
--- a/res/values-fa/test_strings.xml
+++ b/res/values-fa/test_strings.xml
@@ -5,10 +5,10 @@
     <string name="app_name" msgid="1203877025577761792">"اشتراک بلوتوث"</string>
     <string name="insert_record" msgid="1450997173838378132">"درج سابقه"</string>
     <string name="update_record" msgid="2480425402384910635">"تأیید سابقه"</string>
-    <string name="ack_record" msgid="6716152390978472184">"سابقه Ack"</string>
+    <string name="ack_record" msgid="6716152390978472184">"‏سابقه Ack"</string>
     <string name="deleteAll_record" msgid="4383349788485210582">"حذف همه سابقه"</string>
     <string name="ok_button" msgid="6519033415223065454">"تأیید"</string>
     <string name="delete_record" msgid="4645040331967533724">"حذف سابقه"</string>
-    <string name="start_server" msgid="9034821924409165795">"راه‌اندازی سرور TCP"</string>
-    <string name="notify_server" msgid="4369106744022969655">"اعلان سرور TCP"</string>
+    <string name="start_server" msgid="9034821924409165795">"‏راه‌اندازی سرور TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"‏اعلان سرور TCP"</string>
 </resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 455df83..051d66c 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Peruuta"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Ota käyttöön"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Tiedostonsiirto"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> haluaa lähettää sinulle tiedoston <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Haluatko vastaanottaa tiedoston?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> haluaa lähettää sinulle tiedoston <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Haluatko vastaanottaa tiedoston?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Hylkää"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Hyväksy"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Sulje"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Tuntematon tiedosto"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Tämän tyyppisten tiedostojen käsittelyyn sopivaa sovellusta ei ole asennettu. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Tämän tyyppisten tiedostojen käsittelyyn sopivaa sovellusta ei ole asennettu. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ei tiedostoa"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Tiedostoa ei ole olemassa. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Tiedostoa ei ole olemassa. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Odota…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Otetaan Bluetooth käyttöön..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Tiedosto otetaan vastaan. Näet siirron tilan Ilmoitukset-paneelissa."</string>
diff --git a/res/values-fi/strings_map.xml b/res/values-fi/strings_map.xml
new file mode 100644
index 0000000..288e115
--- /dev/null
+++ b/res/values-fi/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Kirjoita kohteen %1$s istunnon avain"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-istunnon avain vaaditaan"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Kohteen %1$s yhteyspyyntö aikakatkaistiin"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Kohteen %1$s istunnon avaimen syöttö aikakatkaistiin"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex-todennuspyyntö"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Istunnon avain"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Kirjoita kohteen %1$s istunnon avain"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Autosarja"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Tuntematon nimi"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Oma nimi"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..1b17ae8
--- /dev/null
+++ b/res/values-fr-rCA/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Accéder au gestionnaire de téléchargement."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Permet à l\'application d\'accéder au gestionnaire BluetoothShare et de l\'utiliser pour le transfert de fichiers."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Ajouter des appareils Bluetooth à la liste blanche."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Permet à l\'application d\'ajouter temporairement un appareil Bluetooth à la liste blanche. Ainsi, celui-ci peut envoyer des fichiers à cet appareil sans que la confirmation de l\'utilisateur soit nécessaire."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"Recevoir des messages concernant les transferts Bluetooth."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Permet la réception d\'information concernant l\'état du transfert par Bluetooth."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Périphérique inconnu"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Inconnu"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Mode Avion"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Bluetooth ne peut être utilisé en mode Avion."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Vous devez activer la fonction Bluetooth pour pouvoir utiliser les services Bluetooth."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Activer Bluetooth maintenant?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Annuler"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Activer"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfert de fichier"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" souhaite vous envoyer <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Accepter le fichier?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Refuser"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accepter"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"Expiration du délai de réception du fichier de \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Partage Bluetooth : réception de fichier"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Voulez-vous recevoir ce fichier?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Fichier entrant provenant d\'un autre appareil. Confirmez que vous souhaitez recevoir ce fichier."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Partage Bluetooth : réception de <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Partage Bluetooth : <xliff:g id="FILE">%1$s</xliff:g> reçu(s)"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Partage Bluetooth : fichier <xliff:g id="FILE">%1$s</xliff:g> non reçu"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Partage Bluetooth : envoi de <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Partage Bluetooth : <xliff:g id="FILE">%1$s</xliff:g> envoyé"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100 % effectués"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Partage Bluetooth : fichier <xliff:g id="FILE">%1$s</xliff:g> non envoyé"</string>
+    <string name="download_title" msgid="3353228219772092586">"Transfert de fichier"</string>
+    <string name="download_line1" msgid="4926604799202134144">"De : \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"Fichier : <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"Taille du fichier : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Réception de fichier en cours"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Arrêter"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Masquer"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"Fichier non reçu"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"Fichier : <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Motif : <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"Fichier reçu"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Ouvrir"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"À : \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"Type de fichier : <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Envoi de fichier en cours"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"Fichier envoyé"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"Le fichier n\'a pas été envoyé à <xliff:g id="RECIPIENT">%1$s</xliff:g>."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"Fichier : <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Réessayer"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Fermer"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Fichier inconnu"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Aucune application ne permet de gérer ce type de fichier. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"Aucun fichier"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Le fichier n\'existe pas. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Veuillez patienter…"</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Activation de Bluetooth…"</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"La réception du fichier va commencer. La progression va s\'afficher dans le panneau de notification."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"Impossible de recevoir le fichier."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"Réception du fichier de \"<xliff:g id="SENDER">%1$s</xliff:g>\" interrompue"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"Envoi du fichier à \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"Envoi de <xliff:g id="NUMBER">%1$s</xliff:g> fichiers à \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"Envoi du fichier à \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" interrompu"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"Espace insuffisant sur la mémoire de stockage USB pour l\'enregistrement du fichier de \"<xliff:g id="SENDER">%1$s</xliff:g>\"."</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"Espace insuffisant sur la carte SD pour l\'enregistrement du fichier de \"<xliff:g id="SENDER">%1$s</xliff:g>\"."</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Espace requis : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Trop de requêtes sont en cours de traitement. Veuillez réessayer plus tard."</string>
+    <string name="status_pending" msgid="2503691772030877944">"Le transfert de fichier n\'a pas encore commencé."</string>
+    <string name="status_running" msgid="6562808920311008696">"Le transfert de fichier est en cours."</string>
+    <string name="status_success" msgid="239573225847565868">"Le transfert de fichiers s\'est déroulé correctement."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Le contenu n\'est pas compatible."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"L\'appareil cible n\'autorise pas le transfert."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Le transfert a été annulé par l\'utilisateur."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Problème de mémoire."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"Aucune mémoire de stockage USB"</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"Aucune carte SD trouvée. Insérez une carte SD pour enregistrer les fichiers transférés."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Échec de la connexion."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Impossible de traiter la demande correctement."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Erreur inconnue."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Reçu par Bluetooth"</string>
+    <string name="download_success" msgid="7036160438766730871">"Réception de <xliff:g id="FILE_SIZE">%1$s</xliff:g> terminée"</string>
+    <string name="upload_success" msgid="4014469387779648949">"Envoi de <xliff:g id="FILE_SIZE">%1$s</xliff:g> terminé"</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Transferts entrants"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Transferts sortants"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"L\'historique des transferts est vide."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Tous les éléments de la liste seront effacés."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Partage Bluetooth : fichiers envoyés"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Partage Bluetooth : fichiers reçus"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> succès, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> échoué."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Effacer la liste"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"ouvrir"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Effacer de la liste"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Effacer"</string>
+</resources>
diff --git a/res/values-fr-rCA/strings_map.xml b/res/values-fr-rCA/strings_map.xml
new file mode 100644
index 0000000..39f72cf
--- /dev/null
+++ b/res/values-fr-rCA/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Entrez la clé de session de %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Clé de session Bluetooth requise"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Délai d\'attente dépassé pour l\'acceptation de connexion à %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Délai d\'attente dépassé pour l\'entrée de la clé de session avec %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Demande d\'authentification Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Clé de session"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Entrez la clé de session de %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Trousse mains libres"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nom inconnu"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mon nom"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-fr-rCA/strings_pbap.xml b/res/values-fr-rCA/strings_pbap.xml
new file mode 100644
index 0000000..0c4c601
--- /dev/null
+++ b/res/values-fr-rCA/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Entrer la clé de session de %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Clé de session Bluetooth requise"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"Délai d\'attente dépassé pour l\'acceptation de connexion à \"%1$s\""</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"Délai d\'attente dépassé pour la saisie de la clé de session avec %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Demande d\'authentification Obex"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Clé de session"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"Entrer la clé de session de %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Trousse mains libres"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Nom inconnu"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"Mon nom"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-fr-rCA/test_strings.xml b/res/values-fr-rCA/test_strings.xml
new file mode 100644
index 0000000..e8d36ae
--- /dev/null
+++ b/res/values-fr-rCA/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Bonjour à tous, TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"Partage Bluetooth"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Insérer l\'enregistrement"</string>
+    <string name="update_record" msgid="2480425402384910635">"Confirmer l\'enregistrement"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Enregistrement accusé de réception"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Supprimer tout l\'enregistrement"</string>
+    <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Supprimer l\'enregistrement"</string>
+    <string name="start_server" msgid="9034821924409165795">"Démarrer le serveur TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"Avertir le serveur TCP"</string>
+</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f3fb8ce..5d26fc4 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Annuler"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activer"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfert de fichier"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" souhaite vous envoyer <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Accepter le fichier ?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" souhaite vous envoyer <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Accepter le fichier ?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Refuser"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accepter"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Fermer"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Fichier inconnu"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Aucune application ne permet de gérer ce type de fichier. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Aucune application ne permet de gérer ce type de fichier. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Aucun fichier"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Le fichier n\'existe pas. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Le fichier n\'existe pas. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Veuillez patienter..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Activation Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"La réception du fichier va commencer. La progression va s\'afficher dans le panneau de notification."</string>
diff --git a/res/values-fr/strings_map.xml b/res/values-fr/strings_map.xml
new file mode 100644
index 0000000..16985d6
--- /dev/null
+++ b/res/values-fr/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Saisir la clé de session pour \"%1$s\""</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Clé de session Bluetooth requise"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Délai d\'attente dépassé pour l\'acceptation de connexion à \"%1$s\"."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Délai d\'attente dépassé pour la saisie de la clé de session avec \"%1$s\"."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Demande d\'authentification Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Clé de session"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Saisir la clé de session pour \"%1$s\""</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit mains libres"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nom inconnu."</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mon nom"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 2f73312..b4d16fa 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -17,9 +17,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"डाउनलोड प्रबंधक में पहुंच प्राप्त करें."</string>
-    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"एप्लिकेशन को BluetoothShare प्रबंधक में पहुंच प्राप्त करने और फ़ाइलों को स्थानांतरित करने के लिए उसका उपयोग करने देता है."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"ऐप्स  को BluetoothShare प्रबंधक में पहुंच प्राप्त करने और फ़ाइलों को स्थानांतरित करने के लिए उसका उपयोग करने देता है."</string>
     <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"श्वेतसूची bluetooth उपकरण पहुंच."</string>
-    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"एप्‍लिकेशन को Bluetooth उपकरण को इस उपकरण पर फ़ाइल भेजने की‍ अनुमति देकर, उपयोगकर्ता की पुष्टि के बिना अस्‍थायी रूप से श्वेतसूची में शामिल करने देता है."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ऐप्स को Bluetooth उपकरण को इस उपकरण पर फ़ाइल भेजने की‍ अनुमति देकर, उपयोगकर्ता की पुष्टि के बिना अस्‍थायी रूप से श्वेतसूची में शामिल करने देता है."</string>
     <string name="permlab_handoverStatus" msgid="7316032998801933554">"BT हस्तांतरण के स्थानांतरण प्रसारण प्राप्त करें."</string>
     <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Bluetooth से हस्तांतरण के स्थानांतरण की स्थिति को प्राप्त करने देता है."</string>
     <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
@@ -33,10 +33,10 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"रद्द करें"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"चालू करें"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"फ़ाइल स्थानांतरण"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" द्वारा आपको <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) भेजी जा रही है. "\n\n" फ़ाइल स्वीकार करनी है?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" द्वारा आपको <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) भेजी जा रही है. \n\n फ़ाइल स्वीकार करनी है?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"अस्वीकारें"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"स्वीकारें"</string>
-    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ठीक"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ठीक है"</string>
     <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" से आने वाली फ़ाइल स्वीकार करते समय समयबाह्य हुआ."</string>
     <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth शेयर: आने वाली फ़ाइल"</string>
     <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"क्या आप यह फ़ाइल प्राप्त करना चाहते हैं?"</string>
@@ -59,23 +59,23 @@
     <string name="download_fail_line1" msgid="3846450148862894552">"फ़ाइल प्राप्त नहीं हुई"</string>
     <string name="download_fail_line2" msgid="8950394574689971071">"फ़ाइल: <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="download_fail_line3" msgid="3451040656154861722">"कारण: <xliff:g id="REASON">%1$s</xliff:g>"</string>
-    <string name="download_fail_ok" msgid="1521733664438320300">"ठीक"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"ठीक है"</string>
     <string name="download_succ_line5" msgid="4509944688281573595">"फ़ाइल प्राप्त की गई"</string>
     <string name="download_succ_ok" msgid="7053688246357050216">"खोलें"</string>
     <string name="upload_line1" msgid="2055952074059709052">"प्रति: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
     <string name="upload_line3" msgid="4920689672457037437">"फ़ाइल प्रकार: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
     <string name="upload_line5" msgid="7759322537674229752">"फ़ाइल भेज रहा है…"</string>
     <string name="upload_succ_line5" msgid="5687317197463383601">"फ़ाइल भेजी गई"</string>
-    <string name="upload_succ_ok" msgid="7705428476405478828">"ठीक"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"ठीक है"</string>
     <string name="upload_fail_line1" msgid="7899394672421491701">"फ़ाइल \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" को नहीं भेजी गई थी."</string>
     <string name="upload_fail_line1_2" msgid="2108129204050841798">"फ़ाइल: <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="upload_fail_ok" msgid="5807702461606714296">"पुन: प्रयास करें"</string>
     <string name="upload_fail_cancel" msgid="9118496285835687125">"बंद करें"</string>
-    <string name="bt_error_btn_ok" msgid="5965151173011534240">"ठीक"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"ठीक है"</string>
     <string name="unknown_file" msgid="6092727753965095366">"अज्ञात फ़ाइल"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"इस प्रकार की फ़ाइल प्रबंधित करने के लिए कोई एप्‍लिकेशन नहीं है. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"इस प्रकार की फ़ाइल प्रबंधित करने के लिए कोई ऐप्स नहीं है. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"कोई फ़ाइल नहीं"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"फ़ाइल मौजूद नहीं है. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"फ़ाइल मौजूद नहीं है. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"कृपया प्रतीक्षा करें..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth चालू कर रहा है…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"फ़ाइल प्राप्त होगी. सूचनाएं फलक में प्रगति देखें."</string>
diff --git a/res/values-hi/strings_map.xml b/res/values-hi/strings_map.xml
new file mode 100644
index 0000000..85db1a5
--- /dev/null
+++ b/res/values-hi/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s के लिए सत्र कुंजी लिखें"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth सत्र कुंजी आवश्यक"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s के साथ कनेक्शन स्वीकार करने में समयबाह्य हो गया था"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s के साथ सत्र कुंजी इनपुट करने में समयबाह्य हो गया था"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex प्रमाणीकरण अनुरोध"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"सत्र कुंजी"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s के लिए सत्र कुंजी लिखें"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"कार किट"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"अज्ञात नाम"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"मेरा नाम"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-hi/test_strings.xml b/res/values-hi/test_strings.xml
index aa134ee..e6889e7 100644
--- a/res/values-hi/test_strings.xml
+++ b/res/values-hi/test_strings.xml
@@ -7,7 +7,7 @@
     <string name="update_record" msgid="2480425402384910635">"रिकॉर्ड की पुष्टि करें"</string>
     <string name="ack_record" msgid="6716152390978472184">"रिकॉर्ड अभिस्वीकृत करें"</string>
     <string name="deleteAll_record" msgid="4383349788485210582">"सभी रिकॉर्ड हटाएं"</string>
-    <string name="ok_button" msgid="6519033415223065454">"ठीक"</string>
+    <string name="ok_button" msgid="6519033415223065454">"ठीक है"</string>
     <string name="delete_record" msgid="4645040331967533724">"रिकॉर्ड हटाएं"</string>
     <string name="start_server" msgid="9034821924409165795">"TCP सर्वर प्रारंभ करें"</string>
     <string name="notify_server" msgid="4369106744022969655">"TCP सर्वर को सूचित करें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 36a1440..db7bf5d 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Odustani"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Uključi"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Prijenos datoteke"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vam želi poslati <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Prihvaćate li datoteku?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vam želi poslati <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Prihvaćate li datoteku?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Odbaci"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Prihvaćam"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"U redu"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Zatvori"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"U redu"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Nepoznata datoteka"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Nema aplikacija za obradu ove vrste datoteke. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Nema aplikacija za obradu ove vrste datoteke. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nema datoteke"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Datoteka ne postoji. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Datoteka ne postoji. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Pričekajte…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Uključivanje Bluetootha…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Datoteka će biti primljena. Napredak provjerite na ploči Obavijesti."</string>
diff --git a/res/values-hr/strings_map.xml b/res/values-hr/strings_map.xml
new file mode 100644
index 0000000..a31ba2c
--- /dev/null
+++ b/res/values-hr/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Upišite šifru sesije za %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Potrebna je šifra za Bluetooth sesiju"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Došlo je do prekoračenja vremena za prihvat povezivanja s korisnikom %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Došlo je do prekoračenja vremena za unos šifre sesije s korisnikom %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Zahtjev za provjeru autentičnosti Obex protokola"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Šifra sesije"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Upišite šifru sesije za %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Komplet za auto"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nepoznati naziv"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Moje ime"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 36786bf..f9aceab 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Mégse"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Bekapcsolás"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Fájlátvitel"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" a következő fájlt szeretné elküldeni: <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Fogadja?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" a következő fájlt szeretné elküldeni: <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Fogadja?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Elutasítás"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Elfogadás"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Bezárás"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Ismeretlen fájl"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Nincs alkalmazás a fájltípus kezeléséhez. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Nincs alkalmazás a fájltípus kezeléséhez. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nincs fájl"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"A fájl nem létezik. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"A fájl nem létezik. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Kérjük, várjon..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth bekapcsolása..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"A fájl fogadható. Az átvitel haladását az Értesítések párbeszédpanelen kísérheti figyelemmel."</string>
diff --git a/res/values-hu/strings_map.xml b/res/values-hu/strings_map.xml
new file mode 100644
index 0000000..2f7a0e4
--- /dev/null
+++ b/res/values-hu/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Írja be a munkamenetkulcsot a(z) %1$s eszközhöz"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Meg kell adni egy Bluetooth-munkamenetkulcsot"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Időtúllépés történt a(z) %1$s eszközhöz történő kapcsolódás során"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Időtúllépés történt a(z) %1$s programfolyamat-kulcsának bevitele során"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex azonosítási kérelem"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Munkamenetkulcs"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Írja be a munkamenetkulcsot a(z) %1$s eszközhöz"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Autós készlet"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Ismeretlen név"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Saját név"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..3ecae6b
--- /dev/null
+++ b/res/values-hy-rAM/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Օգտվել ներբեռնման կառավարչից:"</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Թույլ է տալիս, որ ծրագիրը մատչի BluetoothShare կառավարչին և այն օգտագործի ֆայլեր փոխանցելու համար:"</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Մուտք bluetooth սարքի ցուցակին:"</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Թույլ է տալիս, որ ծրագիրը ժամանակավորապես մաքրի Bluetooth սարքի ցուցակը, ինչը թույլ է տալիս, որ այդ սարքը կարողանա ֆայլեր ուղարկել տվյալ սարքին առանց օգտվողի հաստատման:"</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"Ստանալ BT փոխանցումների հեռարձակումները:"</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Թույլ է տալիս Bluetooth-ից տեղեկատվություն ստանալ փոխանցման կարգավիճակի մասին:"</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Անհայտ սարք"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Անհայտ"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Ինքնաթիռային ռեժիմ"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Դուք չեք կարող օգտվել Bluetooth-ից ինքնաթիռային ռեժիմում:"</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Bluetooth ծառայություններից օգտվելու համար նախ պետք է միացնեք Bluetooth-ը:"</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Միացնե՞լ Bluetooth-ը հիմա:"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Չեղարկել"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Միացնել"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Ֆայլերի փոխանցում"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"«<xliff:g id="SENDER">%1$s</xliff:g>»-ը ցանկանում է ձեզ ուղարկել <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>): \n\n Ընդունե՞լ ֆայլը:"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Մերժել"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Ընդունել"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Լավ"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"«<xliff:g id="SENDER">%1$s</xliff:g>»-ից մուտքային ֆայլի ընդունման ժամանակը սպառվեց"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth համօգտագործում՝ մուտքային ֆայլ"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Ցանկանո՞ւմ եք ստանալ այս ֆայլը:"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Առկա է մուտքային ֆայլ այլ սարքից: Հաստատեք, որ ցանկանում եք ստանալ այս ֆայլը:"</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth համօգտագործում՝ <xliff:g id="FILE">%1$s</xliff:g>-ը ստացվում է"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Bluetooth համօգտագործում՝ ստացվեց <xliff:g id="FILE">%1$s</xliff:g>-ը"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth համօգտագործում՝ <xliff:g id="FILE">%1$s</xliff:g> ֆայլը չի ստացվել"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Bluetooth համօգտագործում՝ ուղարկվում է <xliff:g id="FILE">%1$s</xliff:g>-ը"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Bluetooth համօգտագործում՝ <xliff:g id="FILE">%1$s</xliff:g>-ն ուղարկված է"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100% ավարտուն"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth համօգտագործում՝ <xliff:g id="FILE">%1$s</xliff:g> ֆայլը չի ուղարկվել"</string>
+    <string name="download_title" msgid="3353228219772092586">"Ֆայլերի փոխանցում"</string>
+    <string name="download_line1" msgid="4926604799202134144">"Ումից՝ «<xliff:g id="SENDER">%1$s</xliff:g>»"</string>
+    <string name="download_line2" msgid="5876973543019417712">"Ֆայլ՝ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"Ֆայլի չափը՝ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Ֆայլը ստացվում է..."</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Դադարեցնել"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Թաքցնել"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"Ֆայլը չհաջողվեց ստանալ"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"Ֆայլ՝ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Պատճառը՝ <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"Լավ"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"Ֆայլը ստացվել է"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Բացել"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"Ում՝ «<xliff:g id="RECIPIENT">%1$s</xliff:g>»"</string>
+    <string name="upload_line3" msgid="4920689672457037437">"Ֆայլի տեսակը՝ <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Ֆայլն ուղարկվում է..."</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"Ֆայլն ուղարկված է"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"Լավ"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"Ֆայլը չի ուղարկվել «<xliff:g id="RECIPIENT">%1$s</xliff:g>»-ին:"</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"Ֆայլ՝ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Կրկին փորձել"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Փակել"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"Լավ"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Անհայտ ֆայլ"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Ֆայլի այս տեսակի համար գործող ծրագիր չկա: \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"Ֆայլեր չկան"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Ֆայլը գոյություն չունի: \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Խնդրում ենք սպասել..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth-ը միանում է..."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"Դուք կստանաք ֆայլը: Առաջընթացի մասին տեղեկացեք Ծանուցումների վահանակից:"</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"Հնարավոր չէ ստանալ ֆայլը:"</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"Դադարեցվեց «<xliff:g id="SENDER">%1$s</xliff:g>»-ից ֆայլի ստացումը"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"Ֆայլն ուղարկվում է «<xliff:g id="RECIPIENT">%1$s</xliff:g>»-ին"</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"<xliff:g id="NUMBER">%1$s</xliff:g> ֆայլեր ուղարկվում են «<xliff:g id="RECIPIENT">%2$s</xliff:g>»-ին"</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"Դադարեցվեց ֆայլի ուղարկումը «<xliff:g id="RECIPIENT">%1$s</xliff:g>»-ին"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"USB կրիչի վրա բավարար տեղ չկա «<xliff:g id="SENDER">%1$s</xliff:g>»-ի ֆայլի պահպանման համար"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"SD քարտի վրա բավարար տեղ չկա «<xliff:g id="SENDER">%1$s</xliff:g>»-ի ֆայլի պահպանման համար"</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Անհրաժեշտ տեղը՝ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Չափից շատ հարցումներ են մշակվում: Կրկին փորձեք ավելի ուշ:"</string>
+    <string name="status_pending" msgid="2503691772030877944">"Ֆայլի փոխանցումը դեռ չի մեկնարկել:"</string>
+    <string name="status_running" msgid="6562808920311008696">"Ֆայլի փոխանցումն ընթացքի մեջ է:"</string>
+    <string name="status_success" msgid="239573225847565868">"Ֆայլերի փոխանցումը հաջողությամբ ավարտվել է:"</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Բովանդակությունը չի աջակցվում:"</string>
+    <string name="status_forbidden" msgid="613956401054050725">"Փոխանցումն արգելված է նպատակային սարքի կողմից:"</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Փոխանցումը չեղարկվել է օգտվողի կողմից:"</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Կրիչի խնդիր:"</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"USB կրիչ չկա:"</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD քարտ չկա: Տեղադրեք SD քարտ` փոխանցված ֆայլերը պահպանելու համար:"</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Միացումը անհաջող էր:"</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Հարցումը հնարավոր չէ ճշգրտորեն մշակել:"</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Անհայտ սխալ:"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth-ը ստացված է"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> ստացումն ավարտված է:"</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> ուղարկումն ավարտված է:"</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Մուտքային փոխանցումներ"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Ելքային փոխանցումներ"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"Փոխանցումների պատմությունը դատարկ է:"</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Ցուցակի բոլոր տվյալները կջնջվեն:"</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth համօգտագործում՝ ֆայլերն ուղարկված են"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth համօգտագործում՝ ֆայլերը ստացված են"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> հաջողված, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> չհաջողված:"</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Ջնջել ցուցակը"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"Բաց"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Ջնջել ցուցակից"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Ջնջել"</string>
+</resources>
diff --git a/res/values-hy-rAM/strings_map.xml b/res/values-hy-rAM/strings_map.xml
new file mode 100644
index 0000000..91f2078
--- /dev/null
+++ b/res/values-hy-rAM/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Պահանջվում է Bluetooth-ի աշխատաշրջանի բանալի"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-ի հետ կապի ընդունման ժամանակը սպառվեց"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-ով աշխատաշրջանի բանալու մուտքագրման ժամանակը սպառվեց"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Կասեցնել նույնականացման հարցումը"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Աշխատաշրջանի բանալի"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Անհայտ անուն"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Իմ անունը"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-hy-rAM/strings_pbap.xml b/res/values-hy-rAM/strings_pbap.xml
new file mode 100644
index 0000000..18a22be
--- /dev/null
+++ b/res/values-hy-rAM/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Պահանջվում է Bluetooth-ի աշխատաշրջանի բանալի"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"«%1$s»-ի հետ կապի ընդունման ժամանակը սպառվեց"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s-ով աշխատաշրջանի բանալու մուտքագրման ժամանակը սպառվեց"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Կասեցնել նույնականացման հարցումը"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Աշխատաշրջանի բանալի"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"Մուտքագրեք աշխատաշրջանի բանալի %1$s-ի համար"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Carkit"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Անհայտ անուն"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"Իմ անունը"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-hy-rAM/test_strings.xml b/res/values-hy-rAM/test_strings.xml
new file mode 100644
index 0000000..ffcd2c0
--- /dev/null
+++ b/res/values-hy-rAM/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Բարև աշխարհ, փորձնական գործողություն"</string>
+    <string name="app_name" msgid="1203877025577761792">"Bluetooth համօգտագործում"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Կատարեք գրառում"</string>
+    <string name="update_record" msgid="2480425402384910635">"Հաստատել գրառումը"</string>
+    <string name="ack_record" msgid="6716152390978472184">"ACK գրառում"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Ջնջել բոլոր գրառումները"</string>
+    <string name="ok_button" msgid="6519033415223065454">"Լավ"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Ջնջել գրառումը"</string>
+    <string name="start_server" msgid="9034821924409165795">"Մեկնարկել TCP սերվերը"</string>
+    <string name="notify_server" msgid="4369106744022969655">"Ծանուցել TCP սերվերին"</string>
+</resources>
diff --git a/res/values-hy/strings_map.xml b/res/values-hy/strings_map.xml
new file mode 100644
index 0000000..91f2078
--- /dev/null
+++ b/res/values-hy/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Պահանջվում է Bluetooth-ի աշխատաշրջանի բանալի"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-ի հետ կապի ընդունման ժամանակը սպառվեց"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-ով աշխատաշրջանի բանալու մուտքագրման ժամանակը սպառվեց"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Կասեցնել նույնականացման հարցումը"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Աշխատաշրջանի բանալի"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Անհայտ անուն"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Իմ անունը"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index f67d9ba..11d3f6a 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Batal"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Hidupkan"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfer file"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" Ingin mengirimi Anda <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Terima file?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" Ingin mengirimi Anda <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Terima file?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Tolak"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Terima"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Oke"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Tutup"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Oke"</string>
     <string name="unknown_file" msgid="6092727753965095366">"File tidak diketahui"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Tidak ada apl untuk menangani file jenis ini. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Tidak ada apl untuk menangani file jenis ini. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Tidak ada file"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"File tidak ada. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"File tidak ada. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Harap tunggu…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Menghidupkan Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"File akan diterima. Periksa kemajuan dalam panel Pemberitahuan."</string>
diff --git a/res/values-in/strings_map.xml b/res/values-in/strings_map.xml
new file mode 100644
index 0000000..3daabd9
--- /dev/null
+++ b/res/values-in/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Ketikkan kunci sesi untuk %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Perlu kunci sesi bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Waktu habis untuk menerima sambungan dengan %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Waktu habis untuk memasukkan kunci sesi dengan %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Permintaan autentikasi Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Kunci Sesi"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Ketik kunci sesi untuk %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nama tidak diketahui"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Nama saya"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7b11df6..1f6236b 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Annulla"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Attiva"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Trasferimento file"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vuole inviarti <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Accetti il file?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" vuole inviarti <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Accetti il file?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rifiuta"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accetta"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Chiudi"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"File sconosciuto"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Non sono disponibili applicazioni in grado di gestire questo tipo di file. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Non sono disponibili applicazioni in grado di gestire questo tipo di file. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nessun file"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Il file non esiste. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Il file non esiste. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Attendi..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Attivazione Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Il file verrà ricevuto. Controlla l\'avanzamento nel pannello Notifiche."</string>
diff --git a/res/values-it/strings_map.xml b/res/values-it/strings_map.xml
new file mode 100644
index 0000000..079267b
--- /dev/null
+++ b/res/values-it/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Digita la chiave di sessione per %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Chiave sessione Bluetooth necessaria"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Timeout per l\'accettazione della connessione con %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Timeout dell\'ingresso della chiave di sessione con %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Richiesta di autenticazione Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Chiave sessione"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Digita la chiave di sessione per %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit auto"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nome sconosciuto"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Il mio nome"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 5d615af..92e898a 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -17,37 +17,37 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"גישה למנהל ההורדות."</string>
-    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"מאפשר ליישום לגשת למנהל BluetoothShare ולהשתמש בו להעברת קבצים."</string>
-    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"הכנס מכשיר Bluetooth לרשימה הלבנה."</string>
-    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"מאפשר ליישום להכניס מכשיר Bluetooth באופן זמני לרשימה הלבנה, ובכך לאפשר למכשיר לשלוח קבצים למכשיר זה ללא אישור משתמש."</string>
-    <string name="permlab_handoverStatus" msgid="7316032998801933554">"קבל שידורי העברת מסירה של Bluetooth."</string>
-    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"מאפשר קבלת מידע סטטוס של העברת מסירה מ-Bluetooth."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"‏מאפשר לאפליקציה לגשת למנהל BluetoothShare ולהשתמש בו להעברת קבצים."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"‏הכנס מכשיר Bluetooth לרשימה הלבנה."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"‏מאפשר לאפליקציה להכניס מכשיר Bluetooth באופן זמני לרשימה הלבנה, ובכך לאפשר למכשיר לשלוח קבצים למכשיר זה ללא אישור משתמש."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"‏קבל שידורי העברת מסירה של Bluetooth."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"‏מאפשר קבלת מידע סטטוס של העברת מסירה מ-Bluetooth."</string>
     <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
     <string name="unknown_device" msgid="9221903979877041009">"מכשיר לא ידוע"</string>
     <string name="unknownNumber" msgid="4994750948072751566">"לא ידוע"</string>
     <string name="airplane_error_title" msgid="2683839635115739939">"מצב טיסה"</string>
-    <string name="airplane_error_msg" msgid="8698965595254137230">"לא ניתן להשתמש ב-Bluetooth במצב טיסה."</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"‏לא ניתן להשתמש ב-Bluetooth במצב טיסה."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
-    <string name="bt_enable_line1" msgid="7203551583048149">"כדי להשתמש בשירותי Bluetooth, עליך להפעיל תחילה את Bluetooth."</string>
-    <string name="bt_enable_line2" msgid="4341936569415937994">"להפעיל Bluetooth כעת?"</string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"‏כדי להשתמש בשירותי Bluetooth, עליך להפעיל תחילה את Bluetooth."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"‏להפעיל Bluetooth כעת?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"ביטול"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"הפעל"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"העברת קבצים"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" מעוניין לשלוח לך את <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" לקבל את הקובץ?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" מעוניין לשלוח לך את <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n לקבל את הקובץ?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"דחה"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"קבל"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"אישור"</string>
     <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"תם הזמן הקצוב לקבלת קובץ נכנס מאת \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
-    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"שיתוף Bluetooth: קובץ נכנס"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"‏שיתוף Bluetooth: קובץ נכנס"</string>
     <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"האם ברצונך לקבל קובץ זה?"</string>
     <string name="incoming_file_toast_msg" msgid="1733710749992901811">"מכשיר אחר שולח אליך קובץ. אשר את קבלת הקובץ."</string>
-    <string name="notification_receiving" msgid="4674648179652543984">"שיתוף Bluetooth: מקבל את <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_received" msgid="3324588019186687985">"שיתוף Bluetooth‏: התקבל <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_received_fail" msgid="3619350997285714746">"שיתוף Bluetooth: הקובץ <xliff:g id="FILE">%1$s</xliff:g> לא התקבל"</string>
-    <string name="notification_sending" msgid="3035748958534983833">"שיתוף Bluetooth: שולח את <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_sent" msgid="9218710861333027778">"שיתוף Bluetooth‏: נשלח <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_sent_complete" msgid="302943281067557969">"הושלם ב-‎100%‎"</string>
-    <string name="notification_sent_fail" msgid="6696082233774569445">"שיתוף Bluetooth: הקובץ <xliff:g id="FILE">%1$s</xliff:g> לא נשלח"</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"‏שיתוף Bluetooth: מקבל את <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"‏שיתוף Bluetooth‏: התקבל <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"‏שיתוף Bluetooth: הקובץ <xliff:g id="FILE">%1$s</xliff:g> לא התקבל"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"‏שיתוף Bluetooth: שולח את <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"‏שיתוף Bluetooth‏: נשלח <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"‏הושלם ב-‎100%‎"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"‏שיתוף Bluetooth: הקובץ <xliff:g id="FILE">%1$s</xliff:g> לא נשלח"</string>
     <string name="download_title" msgid="3353228219772092586">"העברת קבצים"</string>
     <string name="download_line1" msgid="4926604799202134144">"מאת: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
     <string name="download_line2" msgid="5876973543019417712">"קובץ: <xliff:g id="FILE">%1$s</xliff:g>"</string>
@@ -73,19 +73,19 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"סגור"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"אישור"</string>
     <string name="unknown_file" msgid="6092727753965095366">"קובץ לא ידוע"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"אין יישום המתאים לטיפול בקבצים מסוג זה. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"אין אפליקציה המתאימה לטיפול בקבצים מסוג זה. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"אין קובץ"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"הקובץ לא קיים. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"הקובץ לא קיים. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"המתן..."</string>
-    <string name="enabling_progress_content" msgid="4601542238119927904">"מפעיל Bluetooth…"</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"‏מפעיל Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"הקובץ יתקבל. בדוק את ההתקדמות בחלונית \'התראות\'."</string>
     <string name="bt_toast_2" msgid="8602553334099066582">"לא ניתן לקבל את הקובץ."</string>
     <string name="bt_toast_3" msgid="6707884165086862518">"הופסקה קבלת קובץ מאת \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
     <string name="bt_toast_4" msgid="4678812947604395649">"שולח קובץ אל \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
     <string name="bt_toast_5" msgid="2846870992823019494">"שולח <xliff:g id="NUMBER">%1$s</xliff:g> קבצים אל \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
     <string name="bt_toast_6" msgid="1855266596936622458">"שליחת קובץ אל \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" הופסקה"</string>
-    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"אין מספיק שטח פנוי באחסון ה-USB לשמירת הקובץ מאת <xliff:g id="SENDER">%1$s</xliff:g>"</string>
-    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"אין מספיק שטח אחסון בכרטיס ה-SD לשמירת הקובץ מאת <xliff:g id="SENDER">%1$s</xliff:g>"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"‏אין מספיק שטח פנוי באחסון ה-USB לשמירת הקובץ מאת <xliff:g id="SENDER">%1$s</xliff:g>"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"‏אין מספיק שטח אחסון בכרטיס ה-SD לשמירת הקובץ מאת <xliff:g id="SENDER">%1$s</xliff:g>"</string>
     <string name="bt_sm_2_2" msgid="2965243265852680543">"שטח דרוש: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="ErrorTooManyRequests" msgid="8578277541472944529">"בקשות רבות מדי הועברו לעיבוד. נסה שוב מאוחר יותר."</string>
     <string name="status_pending" msgid="2503691772030877944">"העברת הקובץ עדיין לא החלה."</string>
@@ -95,20 +95,20 @@
     <string name="status_forbidden" msgid="613956401054050725">"מכשיר היעד לא התיר את ההעברה."</string>
     <string name="status_canceled" msgid="6664490318773098285">"ההעברה בוטלה על ידי המשתמש."</string>
     <string name="status_file_error" msgid="3671917770630165299">"בעיית אחסון."</string>
-    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"אין אחסון USB."</string>
-    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"אין כרטיס SD. הכנס כרטיס SD כדי לשמור קבצים שהועברו."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"‏אין אחסון USB."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"‏אין כרטיס SD. הכנס כרטיס SD כדי לשמור קבצים שהועברו."</string>
     <string name="status_connection_error" msgid="947681831523219891">"החיבור נכשל."</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"לא ניתן לטפל בבקשה כהלכה."</string>
     <string name="status_unknown_error" msgid="8156660554237824912">"שגיאה לא ידועה."</string>
-    <string name="btopp_live_folder" msgid="7967791481444474554">"התקבל באמצעות Bluetooth"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"‏התקבל באמצעות Bluetooth"</string>
     <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> שהתקבלו הושלמו."</string>
     <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> שנשלחו הושלמו."</string>
     <string name="inbound_history_title" msgid="6940914942271327563">"העברות נכנסות"</string>
     <string name="outbound_history_title" msgid="4279418703178140526">"העברות יוצאות"</string>
     <string name="no_transfers" msgid="3482965619151865672">"היסטוריית ההעברות ריקה."</string>
     <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"כל הפריטים ינוקו מהרשימה."</string>
-    <string name="outbound_noti_title" msgid="8051906709452260849">"שיתוף Bluetooth: נשלחו קבצים"</string>
-    <string name="inbound_noti_title" msgid="4143352641953027595">"שיתוף Bluetooth: התקבלו קבצים"</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"‏שיתוף Bluetooth: נשלחו קבצים"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"‏שיתוף Bluetooth: התקבלו קבצים"</string>
     <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> הושלמו בהצלחה, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> לא הושלמו בהצלחה."</string>
     <string name="transfer_menu_clear_all" msgid="790017462957873132">"נקה רשימה"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"פתח"</string>
diff --git a/res/values-iw/strings_map.xml b/res/values-iw/strings_map.xml
new file mode 100644
index 0000000..0ec79be
--- /dev/null
+++ b/res/values-iw/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"הקלד קוד הפעלה עבור %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"דרוש קוד הפעלה של Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"תם הזמן הקצוב לתפוגה של הסכמה לחיבור עם %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"תם הזמן הקצוב להזנת קוד הפעלה עם %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"בקשת אימות של Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"קוד הפעלה"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"הקלד קוד הפעלה עבור %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"דיבורית לרכב"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"שם לא ידוע"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"השם שלי"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-iw/strings_pbap.xml b/res/values-iw/strings_pbap.xml
index b4c1193..6e1e932 100644
--- a/res/values-iw/strings_pbap.xml
+++ b/res/values-iw/strings_pbap.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"הקלד קוד הפעלה עבור %1$s"</string>
-    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"דרוש קוד הפעלת Bluetooth"</string>
-    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"תם הזמן שהוקצב להסכמה לחיבור עם %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"תם הזמן הקצוב להזנת קוד הפעלה עם %1$s"</string>
-    <string name="auth_notif_ticker" msgid="1575825798053163744">"בקשת אימות של Obex"</string>
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"‏הקלד קוד הפעלה עבור %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"‏דרוש קוד הפעלת Bluetooth"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"‏תם הזמן שהוקצב להסכמה לחיבור עם %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"‏תם הזמן הקצוב להזנת קוד הפעלה עם %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"‏בקשת אימות של Obex"</string>
     <string name="auth_notif_title" msgid="7599854855681573258">"קוד הפעלה"</string>
-    <string name="auth_notif_message" msgid="6667218116427605038">"הקלד קוד הפעלה עבור %1$s"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"‏הקלד קוד הפעלה עבור %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"דיבורית לרכב"</string>
     <string name="unknownName" msgid="2841414754740600042">"שם לא ידוע"</string>
     <string name="localPhoneName" msgid="2349001318925409159">"השם שלי"</string>
diff --git a/res/values-iw/test_strings.xml b/res/values-iw/test_strings.xml
index d37e421..3406186 100644
--- a/res/values-iw/test_strings.xml
+++ b/res/values-iw/test_strings.xml
@@ -1,14 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="hello" msgid="1740533743008967039">"שלום לעולם, TestActivity"</string>
-    <string name="app_name" msgid="1203877025577761792">"שיתוף Bluetooth"</string>
+    <string name="hello" msgid="1740533743008967039">"‏שלום לעולם, TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"‏שיתוף Bluetooth"</string>
     <string name="insert_record" msgid="1450997173838378132">"הוסף רשומה"</string>
     <string name="update_record" msgid="2480425402384910635">"אשר רשומה"</string>
     <string name="ack_record" msgid="6716152390978472184">"אשר רשומה"</string>
     <string name="deleteAll_record" msgid="4383349788485210582">"מחק את כל הרשומות"</string>
     <string name="ok_button" msgid="6519033415223065454">"אישור"</string>
     <string name="delete_record" msgid="4645040331967533724">"מחק רשומה"</string>
-    <string name="start_server" msgid="9034821924409165795">"הפעל שרת TCP"</string>
-    <string name="notify_server" msgid="4369106744022969655">"שלח התראה לשרת TCP"</string>
+    <string name="start_server" msgid="9034821924409165795">"‏הפעל שרת TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"‏שלח התראה לשרת TCP"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index aa6bc3e..fb1a134 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"キャンセル"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"ONにする"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ファイル転送"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"「<xliff:g id="SENDER">%1$s</xliff:g>」が<xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>)を送信しようとしています。"\n\n"ファイルを受信しますか?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"「<xliff:g id="SENDER">%1$s</xliff:g>」が<xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>)を送信しようとしています。\n\nファイルを受信しますか?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"拒否"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"承諾"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"閉じる"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"不明なファイル"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"この形式のファイルを処理するアプリがありません。"\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"この形式のファイルを処理するアプリがありません。\n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"ファイルがありません"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"そのファイルは存在しません。"\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"そのファイルは存在しません。\n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"お待ちください..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"BluetoothをONにしています..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"ファイルを受信します。進行状況は[通知]パネルでご確認ください。"</string>
diff --git a/res/values-ja/strings_map.xml b/res/values-ja/strings_map.xml
new file mode 100644
index 0000000..e23017c
--- /dev/null
+++ b/res/values-ja/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$sのセッションキーを入力してください"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetoothセッションキーが必要です"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$sとの接続の承諾がタイムアウトになりました"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$sでのセッションキーの入力がタイムアウトになりました"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"OBEX認証リクエスト"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"セッションキー"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$sのセッションキーを入力してください"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"カーキット"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"不明な名前"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"名前"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..b87ec2f
--- /dev/null
+++ b/res/values-ka-rGE/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ჩამოტვირთვების მენეჯერზე წვდომა."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"ანიჭებს აპს BluetoothShare მენეჯერზე წვდომას და მისი გამოყენების უფლებას ფაილების გასაგზავნად."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Bluetooth მოწყობილობის წვდომის თეთრ სიაში შეყვანა."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"საშუალებას აძლევს აპს, რომ დროებით თეთრ სიაში შეიყვანოს Bluetooth მოწყობილობა, რაც ამ მოწყობილობას საშუალებას მიცემს ფაილები ამ მოწყობილობაზე მომხმარებლის დასტურის გარეშე გამოაგზავნოს."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"BT ჰენდოვერის ტრანსფერის მაუწყებლობების მიღება."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"იძლევა Bluetooth-დან ჰენდოვერის ტრანსფერის სტატუსის მიღების საშუალებას."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"უცნობი მოწყობილობა"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"უცნობი"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"თვითმფრინავის რეჟიმი"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"თვითმფრინავის რეჟიმში Bluetooth-ს ვერ გამოიყენებთ."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Bluetooth სერვისების გამოსაყენებლად ჯერ Bluetooth უნდა ჩართოთ."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"გსურთ Bluetooth-ის ახლა ჩართვა?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"გაუქმება"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"ჩართვა"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ფაილის ტრანსფერი"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ გიგზავნით <xliff:g id="FILE">%2$s</xliff:g>-ს (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n გსურთ ფაილის მიღება?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"უარყოფა"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"მიღება"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"კარგი"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"„<xliff:g id="SENDER">%1$s</xliff:g>“-გან ფაილის შემომავალი ფაილის მიღების დრო ამოიწურა"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth გაზიარება: შემომავალი ფაილი"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"გსურთ ამ ფაილის მიღება?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"შემომავალი ფაილი სხვა მოწყობილობიდან. დაადასტურეთ, რომ გსურთ ფაილის მიღება."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth გაზიარება: <xliff:g id="FILE">%1$s</xliff:g> ფაილის მიღება"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Bluetooth გაზიარება: მიღებულია <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth გაზიარება: ფაილი <xliff:g id="FILE">%1$s</xliff:g> არ მიღებულა"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Bluetooth გაზიარება: <xliff:g id="FILE">%1$s</xliff:g>-ის გაგზავნა"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Bluetooth გაზიარება: გაიგზავნა <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"დასრულდა 100%"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth გაზიარება: ფაილი <xliff:g id="FILE">%1$s</xliff:g> არ გაიგზავნა"</string>
+    <string name="download_title" msgid="3353228219772092586">"ფაილის ტრანსფერი"</string>
+    <string name="download_line1" msgid="4926604799202134144">"გამგზავნი: „<xliff:g id="SENDER">%1$s</xliff:g>“"</string>
+    <string name="download_line2" msgid="5876973543019417712">"ფაილი: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"ფაილის ზომა: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"მიმდინარეობს ფაილის მიღება…"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"შეწყვეტა"</string>
+    <string name="download_ok" msgid="5000360731674466039">"დამალვა"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"ფაილი არ მიღებულა"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"ფაილი: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"მიზეზი: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"კარგი"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"ფაილი მიღებულია"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"გახსნა"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"მიმღები: „<xliff:g id="RECIPIENT">%1$s</xliff:g>“"</string>
+    <string name="upload_line3" msgid="4920689672457037437">"ფაილის ტიპი: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"ფაილი იგზავნება…"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"ფაილი გაიგზავნა"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"კარგი"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"ფაილი არ გაიგზავნა „<xliff:g id="RECIPIENT">%1$s</xliff:g>“-თან."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"ფაილი: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"კიდევ სცადეთ"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"დახურვა"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"კარგი"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"უცნობი ფაილი"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"არ არსებობს აპი, რომელიც ამ ფაილის ტიპის დაამუშავებს. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"ფაილი არ არის"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"ფაილი არ არსებობს. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"გთხოვთ, მოითმინოთ..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth-ის ჩართვა…"</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"ფაილი მიღებული იქნება. შეამოწმეთ პროგრესი შეტყობინებების დაფაზე."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"ფაილის მიღება ვერ ხერხდება."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"„<xliff:g id="SENDER">%1$s</xliff:g>“-დან ფაილის მიღება შეჩერდა"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"„<xliff:g id="RECIPIENT">%1$s</xliff:g>“-თან ფაილის გაგზავნა"</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"<xliff:g id="NUMBER">%1$s</xliff:g> ფაილის „<xliff:g id="RECIPIENT">%2$s</xliff:g>“-თან გაგზავნა"</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"„<xliff:g id="RECIPIENT">%1$s</xliff:g>“-თან ფაილის გაგზავნა შეჩერდა"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"ფაილის „<xliff:g id="SENDER">%1$s</xliff:g>“-იდან შესანახად USB მეხსიერებაზე საკმარისი თავისუფალი სივრცე არ არის."</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"„<xliff:g id="SENDER">%1$s</xliff:g>“-იდან ფაილის შესანახად SD ბარათზე საკმარისი ისვრცე არ არის."</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"საჭირო სივრცე: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"მუშავდება ძალიან ბევრი პროცესი. შეეცადეთ მოგვიანებით."</string>
+    <string name="status_pending" msgid="2503691772030877944">"ფაილის ტრანსფერი ჯერ არ დაწყებულა."</string>
+    <string name="status_running" msgid="6562808920311008696">"მიმდინარეობს ფაილის ტრანსფერი."</string>
+    <string name="status_success" msgid="239573225847565868">"ფაილის ტრანსფერი წარმატებით დასრულდა."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"კონტენტი მხარდაჭერილი არ არის."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"ტრანსფერი აკრძალულია სამიზნე მოწყობილობის მიერ."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"ტრანსფერი გაუქმდა მომხმარებლის მიერ."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"მეხსიერების შეცდომა."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"USB მეხსიერება არ არის."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD ბარათი არ არის. ჩადეთ SD ბარათი გადმოგზავნილი ფაილების შესანახად."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"კავშირი ვერ განხორციელდა."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"მოთხოვნის სწორად დამუშავება ვერ ხერხდება."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"უცნობი შეცდომა."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth-ით მიღებული"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> მიღება დასრულდა."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> გაგზავნა დასრულდა."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"შემომავალი ტრანსფერები"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"გამავალი ტრანსფერები"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"ტრანსფერების ისტორია ცარიელია."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"სიიდან ყველა ერთეული ამოიშლება."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth გაზიარება: გაგზავნილი ფაილები"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth გაზიარება: მიღებული ფაილები"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> წარმატებით გადაიწერა, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> ვერ განხორციელდა."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"სიის გასუფთავება"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"გახსნა"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"სიიდან ამოშლა"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"ამოშლა"</string>
+</resources>
diff --git a/res/values-ka-rGE/strings_map.xml b/res/values-ka-rGE/strings_map.xml
new file mode 100644
index 0000000..8e645c4
--- /dev/null
+++ b/res/values-ka-rGE/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"სესიის გასაღები %1$s-ისთვის"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"აუცილებელია Bluetooth სესიის გასაღები"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-თან კავშირის მიღების დრო ამოიწურა"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-თან სესიის გასაღების შეყვანის დრო ამოიწურა"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex ავთენტიფიკაციის მოთხოვნა"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"სესიის გასაღები"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"სესიის გასაღები %1$s-ისთვის"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"მანქანის ნაკრები"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"უცნობი სახელი"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ჩემი სახელი"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ka-rGE/strings_pbap.xml b/res/values-ka-rGE/strings_pbap.xml
new file mode 100644
index 0000000..f160d08
--- /dev/null
+++ b/res/values-ka-rGE/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"სესსის გასაღები %1$s-ისთვის"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"აუცილებელია Bluetooth სესიის გასაღები"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"%1$s-თან კავშირის მიღების დრო ამოიწურა"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s-თან სესიის გასაღების შეყვანის დრო ამოიწურა"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex ავტენთიფიკაციის მოთხოვნა"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"სესიის გასაღები"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"სესსის გასაღები %1$s-ისთვის"</string>
+    <string name="defaultname" msgid="4821590500649090078">"მანქანის ნაკრები"</string>
+    <string name="unknownName" msgid="2841414754740600042">"უცნობი სახელი"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"ჩემი სახელი"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-ka-rGE/test_strings.xml b/res/values-ka-rGE/test_strings.xml
new file mode 100644
index 0000000..8723056
--- /dev/null
+++ b/res/values-ka-rGE/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"გაუმარჯოს! TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"Bluetooth გაზიარება"</string>
+    <string name="insert_record" msgid="1450997173838378132">"ჩანაწერის ჩასმა"</string>
+    <string name="update_record" msgid="2480425402384910635">"ჩანაწერის დადასტურება"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Ack ჩანაწერი"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"ყველა ჩანაწერის წაშლა"</string>
+    <string name="ok_button" msgid="6519033415223065454">"კარგი"</string>
+    <string name="delete_record" msgid="4645040331967533724">"ჩანაწერის წაშლა"</string>
+    <string name="start_server" msgid="9034821924409165795">"TCP სერვერის დაწყება"</string>
+    <string name="notify_server" msgid="4369106744022969655">"TCP სერვერის შეტყობინება"</string>
+</resources>
diff --git a/res/values-ka/strings_map.xml b/res/values-ka/strings_map.xml
new file mode 100644
index 0000000..8e645c4
--- /dev/null
+++ b/res/values-ka/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"სესიის გასაღები %1$s-ისთვის"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"აუცილებელია Bluetooth სესიის გასაღები"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-თან კავშირის მიღების დრო ამოიწურა"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-თან სესიის გასაღების შეყვანის დრო ამოიწურა"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex ავთენტიფიკაციის მოთხოვნა"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"სესიის გასაღები"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"სესიის გასაღები %1$s-ისთვის"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"მანქანის ნაკრები"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"უცნობი სახელი"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ჩემი სახელი"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..83a8fb2
--- /dev/null
+++ b/res/values-km-rKH/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ចូល​ដំណើរ​ការ​កម្មវិធី​គ្រប់គ្រង​ការ​ទាញ​យក​។"</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ត្រូវ​​ចូល​ដំណើរការ​កម្មវិធី​គ្រប់គ្រង BluetoothShare ហើយ​​ប្រើ​វា​ដើម្បី​ផ្ទេរ​ឯកសារ។"</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"បញ្ជី​ស​ការ​ចូល​ដំណើរការ​ប៊្លូធូស។"</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"​ឲ្យ​កម្មវិធី​ដាក់​ឧបករណ៍​ប៊្លូធូស​ក្នុង​បញ្ជី​បណ្ដោះអាសន្ន​ ដែល​អនុញ្ញាត​ឲ្យ​ឧបករណ៍​​នោះ ​ផ្ញើ​ឯកសារ​ទៅ​​កាន់​ឧបករណ៍​​​ដោយ​មិន​ចាំបាច់​ការ​បញ្ជាក់​​អ្នក​ប្រើ។"</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"ទទួល​ការ​ផ្សព្វផ្សាយ​ការ​ផ្ទេរ BT ។"</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"​ឲ្យ​ទទួល​ព័ត៌មាន​ស្ថានភាព​ការ​​ផ្ទេរ​ពី​ប៊្លូធូស។"</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"ប៊្លូធូស"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"មិន​ស្គាល់​ឧបករណ៍"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"មិន​ស្គាល់"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"ពេល​ជិះ​យន្តហោះ"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"អ្នក​មិន​អាច​ប្រើ​ប៊្លូ​ធូ​ស​ក្នុង​​​​​ពេល​ជិះ​យន្តហោះ​បាន​ទេ"</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"ដើម្បី​ប្រើ​​សេវា​ប៊្លូ​ធូ​ស ​ជា​ដំបូង​អ្នក​ត្រូវ​តែ​បើក​​ប៊្លូ​ធូ​ស​សិន​។"</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"បើក​ប៊្លូធូស​ឥឡូវ​នេះ?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"បោះ​បង់"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"បើក"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ការ​ផ្ទេរ​ឯកសារ"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ចង់​ផ្ញើ <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) ឲ្យ​អ្នក។ \n\n ទទួល​ឯកសារ?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"បោះបង់"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"ទទួល"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"យល់​ព្រម"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"អស់​ពេល​ទទួល​​ឯកសារ​ចូល​ពី \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ឯកសារ​ចូល"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"តើ​អ្នក​ចង់​ទទួល​ឯកសារ​នេះ​ឬ​?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"ឯកសារ​ចូល​ពី​ឧបករណ៍​ផ្សេងទៀត។ បញ្ជាក់​ថា​អ្នក​ចង់​ទទួល​បាន​ឯកសារ​នេះ។"</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ទទួល <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ទទួល​ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ មិន​បាន​ទទួល​ឯកសារ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ផ្ញើ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ផ្ញើ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"​បញ្ចប់ 100​%"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ មិន​បាន​ផ្ញើ​ឯកសារ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_title" msgid="3353228219772092586">"ការ​ផ្ទេរ​ឯកសារ"</string>
+    <string name="download_line1" msgid="4926604799202134144">"ពី៖ \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"ឯកសារ៖ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"ទំហំ​ឯកសារ៖ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"កំពុង​ទទួល​ឯកសារ…"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"បញ្ឈប់"</string>
+    <string name="download_ok" msgid="5000360731674466039">"លាក់"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"មិន​​បាន​ទទួល​​​ឯកសារ"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"ឯកសារ៖ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"មូលហេតុ៖ <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"យល់​ព្រម"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"បាន​ទទួល​​ឯកសារ"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"បើក"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"ទៅ៖ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"ប្រភេទ​ឯកសារ៖ <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"កំពុង​ផ្ញើ​ឯកសារ…"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"បាន​ផ្ញើ​ឯកសារ"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"យល់​ព្រម"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"មិន​បាន​ផ្ញើ​ឯកសារ​ទៅ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" ។"</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"ឯកសារ៖ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"ព្យាយាម​ម្ដង​ទៀត"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"បិទ"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"យល់​ព្រម"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"មិន​ស្គាល់​ឯកសារ"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"គ្មាន​កម្មវិធី​​សម្រាប់​គ្រប់គ្រង​ប្រភេទ​ឯកសារ​នេះ​ទេ។ \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"គ្មាន​ឯកសារ"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"គ្មាន​ឯកសារ។ \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"សូម​រង់ចាំ..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"កំពុង​បើក​ប៊្លូធូស…"</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"នឹង​​​​បាន​ទទួល​​​ឯកសារ។ ពិនិត្យមើល​វឌ្ឍនភាព​នៅ​ក្នុង​ផ្ទាំង​ជូនដំណឹង។"</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"មិន​អាច​ទទួល​​ឯកសារ។"</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"បាន​បញ្ឈប់​ការ​ទទួល​​ឯកសារ​ពី \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"ផ្ញើ​ឯកសារ​ទៅ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"ផ្ញើ​ឯកសារ <xliff:g id="NUMBER">%1$s</xliff:g> ទៅ \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"បាន​បញ្ឈប់​ការ​ផ្ញើ​ឯកសារ​ទៅ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"ឧបករណ៍​ផ្ទុក​យូអេសប៊ី​មិន​មាន​ទំហំ​គ្រប់គ្រាន់ ដើម្បី​រក្សាទុក​ឯកសារ​ពី \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"កាត​អេសឌី​មិន​មាន​ទំហំ​គ្រប់គ្រាន់ ដើម្បី​រក្សាទុក​ឯកសារ​ពី \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"ទំហំ​ដែល​ត្រូវ​ការ៖ <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"កំពុង​ដំណើរការ​សំណើ​ជា​ច្រើន​​។ សូម​ព្យាយាម​ម្ដង​ទៀត​នៅ​ពេល​ក្រោយ​។"</string>
+    <string name="status_pending" msgid="2503691772030877944">"មិន​ទាន់​បាន​ចាប់ផ្ដើម​ផ្ទេរ​ឯកសារ​នៅ​ឡើយ​ទេ។"</string>
+    <string name="status_running" msgid="6562808920311008696">"កំពុង​បន្ត​ការ​ផ្ទេរ​ឯកសារ។"</string>
+    <string name="status_success" msgid="239573225847565868">"​ការ​ផ្ទេរ​ឯកសារ​​​បាន​បញ្ចប់​ដោយ​ជោគជ័យ​។"</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"មិន​បាន​គាំទ្រ​មាតិកា។"</string>
+    <string name="status_forbidden" msgid="613956401054050725">"ឧបករណ៍​គោលដៅ​បាន​ហាមឃាត់​ការ​ផ្ទេរ​។"</string>
+    <string name="status_canceled" msgid="6664490318773098285">"អ្នក​ប្រើ​បាន​បោះបង់​ការ​ផ្ទេរ។"</string>
+    <string name="status_file_error" msgid="3671917770630165299">"បញ្ហា​​ឧបករណ៍​ផ្ទុក​។"</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"គ្មាន​ឧបករណ៍​​ផ្ទុក​យូអេសប៊ី។"</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"គ្មាន​កាត​អេសឌី។ បញ្ចូល​កាត​អេសឌី ដើម្បី​រក្សាទុក​ឯកសារ​ដែល​បាន​ផ្ទេរ។"</string>
+    <string name="status_connection_error" msgid="947681831523219891">"ការ​តភ្ជាប់​​មិន​ជោគជ័យ​។"</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"មិន​អាច​ដោះស្រាយ​សំណើ​​​​ដោយ​ត្រឹមត្រូវ​ទេ។"</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"មិន​ស្គាល់​កំហុស។"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"​បាន​ទទួល​​ប៊្លូ​ធូ​ស"</string>
+    <string name="download_success" msgid="7036160438766730871">"បាន​ទទួល​ពេញ​លេញ <xliff:g id="FILE_SIZE">%1$s</xliff:g> ។"</string>
+    <string name="upload_success" msgid="4014469387779648949">"បាន​ផ្ញើ​ពេញ​លេញ <xliff:g id="FILE_SIZE">%1$s</xliff:g> ។"</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"ការ​ផ្ទេរ​ចូល"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"ការ​ផ្ទេរ​ចេញ"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"មិន​មាន​ប្រវត្តិ​​ផ្ទេរ​។"</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"នឹង​សម្អាត​ធាតុ​ទាំងអស់​ពី​បញ្ជី។"</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ផ្ញើ​ឯកសារ"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ទទួល​​​ឯកសារ"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"ជោគជ័យ <xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g>  បរាជ័យ <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> ។"</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"សម្អាត​បញ្ជី"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"បើក"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"សម្អាត​ពី​បញ្ជី"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"សម្អាត"</string>
+</resources>
diff --git a/res/values-km-rKH/strings_map.xml b/res/values-km-rKH/strings_map.xml
new file mode 100644
index 0000000..8118669
--- /dev/null
+++ b/res/values-km-rKH/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"បាន​ទាមទារ​សោ​សម័យ​ប៊្លូធូស"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"អស់​ពេល​វេលា​ក្នុង​ការ​ទទួល​យក​ការ​តភ្ជាប់​ជាមួយ %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"អស់​ពេល​​ដើម្បី​បញ្ចូល​សោ​សម័យ​ជាមួយ %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"សំណើ​ការ​ផ្ទៀងផ្ទាត់ Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"សោ​សម័យ"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"មិន​ស្គាល់​ឈ្មោះ"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ឈ្មោះ​របស់​ខ្ញុំ"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-km-rKH/strings_pbap.xml b/res/values-km-rKH/strings_pbap.xml
new file mode 100644
index 0000000..b175936
--- /dev/null
+++ b/res/values-km-rKH/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"បាន​ទាមទារ​សោ​សម័យ​ប៊្លូធូស"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"អស់​ពេល​វេលា​ក្នុង​ការ​ទទួល​យក​ការ​តភ្ជាប់​ជាមួយ %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"អស់​ពេល​​ដើម្បី​បញ្ចូល​សោ​សម័យ​ជាមួយ %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"សំណើ​ការ​ផ្ទៀងផ្ទាត់ Obex"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"សោ​សម័យ"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Carkit"</string>
+    <string name="unknownName" msgid="2841414754740600042">"មិន​ស្គាល់​ឈ្មោះ"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"ឈ្មោះ​របស់​ខ្ញុំ"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-km-rKH/test_strings.xml b/res/values-km-rKH/test_strings.xml
new file mode 100644
index 0000000..f35bc4a
--- /dev/null
+++ b/res/values-km-rKH/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"សួស្ដី  TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"ការ​ចែករំលែក​ប៊្លូ​ធូ​ស"</string>
+    <string name="insert_record" msgid="1450997173838378132">"បញ្ចូល​កំណត់ត្រា"</string>
+    <string name="update_record" msgid="2480425402384910635">"បញ្ជាក់​កំណត់ត្រា"</string>
+    <string name="ack_record" msgid="6716152390978472184">"កំណត់ត្រា​ការ​ទទួល​ស្គាល់"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"លុប​កំណត់​ត្រា​ទាំងអស់"</string>
+    <string name="ok_button" msgid="6519033415223065454">"យល់​ព្រម"</string>
+    <string name="delete_record" msgid="4645040331967533724">"លុប​កំណត់​ត្រា"</string>
+    <string name="start_server" msgid="9034821924409165795">"ចាប់ផ្ដើម​​ម៉ាស៊ីន​មេ TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"ជូន​ដំណឹង​ម៉ាស៊ីន​មេ TCP"</string>
+</resources>
diff --git a/res/values-km/strings_map.xml b/res/values-km/strings_map.xml
new file mode 100644
index 0000000..8118669
--- /dev/null
+++ b/res/values-km/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"បាន​ទាមទារ​សោ​សម័យ​ប៊្លូធូស"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"អស់​ពេល​វេលា​ក្នុង​ការ​ទទួល​យក​ការ​តភ្ជាប់​ជាមួយ %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"អស់​ពេល​​ដើម្បី​បញ្ចូល​សោ​សម័យ​ជាមួយ %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"សំណើ​ការ​ផ្ទៀងផ្ទាត់ Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"សោ​សម័យ"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"បញ្ចូល​សោ​សម័យ​សម្រាប់ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"មិន​ស្គាល់​ឈ្មោះ"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ឈ្មោះ​របស់​ខ្ញុំ"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index f8c73be..31270de 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"취소"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"사용"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"파일 전송"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\'<xliff:g id="SENDER">%1$s</xliff:g>\'님이 <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>)을(를) 보내려고 합니다. "\n\n" 파일을 수락하시겠습니까?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\'<xliff:g id="SENDER">%1$s</xliff:g>\'님이 <xliff:g id="FILE">%2$s</xliff:g>(<xliff:g id="SIZE">%3$s</xliff:g>)을(를) 보내려고 합니다. \n\n 파일을 수락하시겠습니까?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"거부"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"수락"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"확인"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"닫기"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"확인"</string>
     <string name="unknown_file" msgid="6092727753965095366">"알 수 없는 파일"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"이러한 형식의 파일을 처리할 앱이 없습니다. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"이러한 형식의 파일을 처리할 앱이 없습니다. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"파일 없음"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"파일이 없습니다. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"파일이 없습니다. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"잠시 기다려 주세요."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"블루투스 켜는 중..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"파일이 수신됩니다. 알림 패널에서 진행률을 확인하세요."</string>
diff --git a/res/values-ko/strings_map.xml b/res/values-ko/strings_map.xml
new file mode 100644
index 0000000..2789943
--- /dev/null
+++ b/res/values-ko/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s의 세션 키 입력"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"블루투스 세션 키 필요"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s 연결 수락 제한 시간이 초과되었습니다."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s에 세션 키 입력 제한 시간이 초과되었습니다."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex 인증 요청"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"세션 키"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s의 세션 키 입력"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"알 수 없는 이름"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"내 이름"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..61c1233
--- /dev/null
+++ b/res/values-lo-rLA/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ເຂົ້າເຖິງໂຕຈັດການການດາວໂຫລດ​."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"ອະນຸຍາດໃຫ້ແອັບຯນີ້ເຂົາເຖິງໂຕຈັດການ BluetoothShare ແລະໃຊ້ມັນເພື່ອສົ່ງໄຟລ໌."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"ເຮັດບັນຊີອະນຸຍາດການເຂົ້າເຖິງອຸປະກອນ bluetooth."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວຕັ້ງບັນຊີຂາວໃຫ້ກັບອຸປະກອນ Bluetooth ຊົ່ວຄາວ, ການອະນຸຍາດໃຫ້ອຸປະກອນນັ້ນສົ່ງໄຟລ໌ມາທີ່ອຸປະກອນນີ້ໂດຍທີ່ບໍ່ຈຳເປັນຕ້ອງມີການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"ຮັບສັນຍານການໂອນໄຟລ໌ BT handover."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"ອະນຸຍາດການຮັບຂໍ້ມູນສະຖານະການໂອນຈາກ Bluetooth."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"ອຸປະກອນທີ່ບໍ່ຮູ້ຈັກ"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"ໂໝດຢູ່ເທິງຍົນ"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"ທ່ານບໍ່ສາມາດໃຊ້ Bluetooth ໃນໂໝດຢູ່ເທິງຍົນໄດ້."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"ໃນການນຳໃຊ້ບໍລິການ Bluetooth, ທ່ານຕ້ອງເປີດ Bluetooth ກ່ອນ."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"ເປີດ Bluetooth ດຽວນີ້ບໍ່?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"ຍົກເລີກ"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"ເປີດ"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ການໂອນໄຟລ໌"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ຕ້ອງການທີ່ຈະສົ່ງ <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) ໃຫ້ທ່ານ. \n\n ຮັບເອົາໄຟລ໌ດັ່ງກ່າວບໍ່?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"ປະຕິເສດ"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"ຮັບເອົາ"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ຕົກລົງ"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"ເກີດມີການໝົດເວລາໃນລະຫວ່າງທີ່ກຳລັງຮັບເອົາໄຟລ໌ທີ່ເຂົ້າມາຈາກ \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"ແບ່ງປັນໃນ Bluetooth: ມີໄຟລ໌ເຂົ້າມາ"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"ທ່ານຕ້ອງການທີ່ຮັບເອົາໄຟລ໌ນີ້ບໍ່?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"ມີໄຟລ໌ກຳລັງເຂົ້າມາຈາກອຸປະກອນອື່ນ. ຢືນຢັນວ່າທ່ານຕ້ອງການຮັບເອົາໄຟລ໌ນີ້."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"ແບ່ງປັນໃນ Bluetooth: ກຳລັງຮັບເອົາ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"ແບ່ງປັນໃນ Bluetooth: ໄດ້ຮັບ <xliff:g id="FILE">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"ແບ່ງປັນໃນ Bluetooth: ບໍ່ໄດ້ຮັບ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"ແບ່ງປັນໃນ Bluetooth: ກຳລັງສົ່ງ <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"ແບ່ງປັນໃນ Bluetooth: ສົ່ງ <xliff:g id="FILE">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100​% ສໍາ​ເລັດແລ້ວ"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"ແບ່ງປັນໃນ Bluetooth: ໄຟລ໌<xliff:g id="FILE">%1$s</xliff:g> ບໍ່ໄດ້ຖືກສົ່ງ"</string>
+    <string name="download_title" msgid="3353228219772092586">"ໂອນໄຟລ໌"</string>
+    <string name="download_line1" msgid="4926604799202134144">"ຈາກ: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"ໄຟລ໌: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"ຂະໜາດໄຟລ໌: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"ກຳລັງຮັບເອົາໄຟລ໌..."</string>
+    <string name="download_cancel" msgid="9177305996747500768">"ຢຸດ"</string>
+    <string name="download_ok" msgid="5000360731674466039">"ເຊື່ອງ"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"ໄຟລ໌ບໍ່ໄດ້ຮັບ"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"ໄຟລ໌: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"ເຫດ​ຜົນ​: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"ຕົກລົງ"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"ໄດ້ຮັບໄຟລ໌ແລ້ວ"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"ເປີດ"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"ເຖິງ: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"ປະເພດຂອງໄຟລ໌: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"ກຳລັງສົ່ງໄຟລ໌..."</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"ໄຟລ໌ຖືກສົ່ງແລ້ວ"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"ຕົກລົງ"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"ໄຟລ໌ດັ່ງກ່າວບໍ່ໄດ້ຖືກສົ່ງໄປທີ່ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"ໄຟລ໌​: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"ລອງອີກຄັ້ງ"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"ປິດ"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"ໄຟລ໌ທີ່ບໍ່ຮູ້ຈັກ"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"ບໍ່ມີແອັບຯໃດຈັດການໄຟລ໌ປະເພດນີ້ໄດ້. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"ບໍ່ມີໄຟລ໌"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"ໄຟລ໌ດັ່ງກ່າວບໍ່ມີຢູ່ \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"ກະລຸນາລໍຖ້າ..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"ກຳລັງເປີດ Bluetooth..."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"ຈະໄດ້ຮັບໄຟລ໌ດັ່ງກ່າວ. ກວດສອບການດຳເນີນການໃນແຜງການແຈ້ງເຕືອນ."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"ບໍ່ສາມາດຮັບໄຟລ໌ໄດ້."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"ຢຸດການຮັບໄຟລ໌ຈາກ \"<xliff:g id="SENDER">%1$s</xliff:g>\" ແລ້ວ"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"ກຳລັງສົ່ງໄຟລ໌ໄປຫາ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"ກຳລັງສົ່ງ <xliff:g id="NUMBER">%1$s</xliff:g> ໄຟລ​໌​ໄປຫາ \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"ຢຸດການສົ່ງໄຟລ໌ໄປຫາ \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" ແລ້ວ"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"ບ່ອນຈັດເກັບຂໍ້ມູນ USB  ບໍ່ພຽງພໍທີ່ຈະບັນທຶກໄຟລ໌ດັ່ງກ່າວຈາກ \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"ບ່ອນຈັດເກັບຂໍ້ມູນ SD card ບໍ່ພຽງພໍທີ່ຈະບັນທຶກໄຟລ໌ດັ່ງກ່າວຈາກ \"<xliff:g id="SENDER">%1$s</xliff:g>\" ໄດ້"</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"ພື້ນທີ່ທີ່ຕ້ອງການ​: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"ມີການຮ້ອງຂໍຫຼາຍເກີນໄປ, ກະລຸນາລອງໃໝ່ພາຍຫຼັງ."</string>
+    <string name="status_pending" msgid="2503691772030877944">"ການໂອນໄຟລ໌ຍັງບໍ່ທັນໄດ້ເລີ່ມເທື່ອ."</string>
+    <string name="status_running" msgid="6562808920311008696">"ການໂອນໄຟລ໌ກຳລັງດຳເນີນຢູ່."</string>
+    <string name="status_success" msgid="239573225847565868">"ການໂອນໄຟລ໌ສຳເລັດແລ້ວ."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"ເນື້ອຫາບໍ່ໄດ້ຖືກຮອງຮັບ."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"ການໂອນໄຟລ໌ຖືກປິດກັ້ນໂດຍອຸປະກອນປາຍທາງ."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"ການໂອນຖືກຍົກເລີກໂດຍຜູ່ໃຊ້."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"ປັນຫາພື້ນທີ່ເກັບຂໍ້ມູນ."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"ບໍ່ມີບ່ອນຈັດເກັບຂໍ້ມູນ USB."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"ບໍ່ມີ SD card. ໃສ່ SD card ເພື່ອບັນທຶກໄຟລ໌ທີ່ໂອນມາ."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"ການເຊື່ອມຕໍ່ບໍ່ສຳເລັດຜົນ"</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"ການຮ້ອງຂໍບໍ່ສາມາດຖືກຈັດການໄດ້ຢ່າງຖືກຕ້ອງ."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"ຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກ."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"ໄຟລ໌ທີ່ໄດ້ຮັບແລ້ວຈາກ Bluetooth"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> ໄດ້ຮັບຮຽບຮ້ອຍແລ້ວ."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> ຖືກສົ່ງສຳເລັດແລ້ວ."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"ການໂອນເຂົ້າ"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"ການໂອນອອກ"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"ປະຫວັດການໂອນຫວ່າງເປົ່າ."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"ລາຍການທັງໝົດຈະຖືກລຶບອອກຈາກລາຍການດັ່ງກ່າວ."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"ແບ່ງປັນໃນ Bluetooth: ໄຟລ໌ສົ່ງແລ້ວ"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"ແບ່ງປັນໃນ Bluetooth: ໄຟລ໌ໄດ້ຮັບແລ້ວ"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> ສຳເລັດແລ້ວ, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> ບໍ່ສຳເລັດ."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"ລຶບລາຍການ"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"ເປີດ"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"ລຶບອອກຈາກລາຍການ"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"ລຶບ"</string>
+</resources>
diff --git a/res/values-lo-rLA/strings_map.xml b/res/values-lo-rLA/strings_map.xml
new file mode 100644
index 0000000..dd3a288
--- /dev/null
+++ b/res/values-lo-rLA/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"ຕ້ອງມີ Bluetooth ລະຫັດເຊສຊັນ"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"ໝົດເວລາທີ່ຈະຮັບການເຊື່ອມຕໍ່ກັບ %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"ເກີດໝົດເວລາກ່ອນທີ່ຈະໃສ່ລະຫັດເຊສຊັນກັບ %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"ການຮ້ອງຂໍພິສູດຢືນຢັນໂຕ Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"ກະແຈເຊສຊັສ"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"ບໍ່ຮູ້ຊື່"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ຊື່ຂອງຂ້ອຍ"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-lo-rLA/strings_pbap.xml b/res/values-lo-rLA/strings_pbap.xml
new file mode 100644
index 0000000..0ccdd49
--- /dev/null
+++ b/res/values-lo-rLA/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"ຕ້ອງມີ Bluetooth ລະຫັດເຊສຊັນ"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"ໝົດເວລາທີ່ຈະຮັບການເຊື່ອມຕໍ່ກັບ %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"ເກີດໝົດເວລາກ່ອນທີ່ຈະໃສ່ລະຫັດເຊສຊັນກັບ %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"ການຮ້ອງຂໍພິສູດຢືນຢັນໂຕ Obex"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"ກະແຈເຊສຊັນ"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Carkit"</string>
+    <string name="unknownName" msgid="2841414754740600042">"ບໍ່ຮູ້ຊື່"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"ຊື່ຂອງຂ້ອຍ"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-lo-rLA/test_strings.xml b/res/values-lo-rLA/test_strings.xml
new file mode 100644
index 0000000..778583b
--- /dev/null
+++ b/res/values-lo-rLA/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"ສະບາຍດີ, ການເຮັດວຽກທົດສອບ"</string>
+    <string name="app_name" msgid="1203877025577761792">"ແບ່ງປັນໃນ Bluetooth"</string>
+    <string name="insert_record" msgid="1450997173838378132">"ໃສ່ບັນທຶກ"</string>
+    <string name="update_record" msgid="2480425402384910635">"ຢືນຢັນການບັນທຶກ"</string>
+    <string name="ack_record" msgid="6716152390978472184">"ບັນທຶກ Ack"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"ລຶບບັນທຶກທັງໝົດ"</string>
+    <string name="ok_button" msgid="6519033415223065454">"ຕົກລົງ"</string>
+    <string name="delete_record" msgid="4645040331967533724">"ລຶບການບັນທຶກ"</string>
+    <string name="start_server" msgid="9034821924409165795">"ເລີ່ມ TCP ເຊີບເວີ"</string>
+    <string name="notify_server" msgid="4369106744022969655">"ແຈ້ງເຕືອນ TCP ເຊີບເວີ"</string>
+</resources>
diff --git a/res/values-lo/strings_map.xml b/res/values-lo/strings_map.xml
new file mode 100644
index 0000000..dd3a288
--- /dev/null
+++ b/res/values-lo/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"ຕ້ອງມີ Bluetooth ລະຫັດເຊສຊັນ"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"ໝົດເວລາທີ່ຈະຮັບການເຊື່ອມຕໍ່ກັບ %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"ເກີດໝົດເວລາກ່ອນທີ່ຈະໃສ່ລະຫັດເຊສຊັນກັບ %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"ການຮ້ອງຂໍພິສູດຢືນຢັນໂຕ Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"ກະແຈເຊສຊັສ"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"ບໍ່ຮູ້ຊື່"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ຊື່ຂອງຂ້ອຍ"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 4c3c44b..86ba0c4 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Atšaukti"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Įjungti"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Failo perkėlimas"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> nori jums atsiųsti <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Priimti failą?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> nori jums atsiųsti <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Priimti failą?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Atmesti"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Priimti"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Gerai"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Uždaryti"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Gerai"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Nežinomas failas"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Nėra programos, kurią naudojant būtų galima tvarkyti šio tipo failą. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Nėra programos, kurią naudojant būtų galima tvarkyti šio tipo failą. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nėra failų"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Failas neegzistuoja. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Failas neegzistuoja. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Palaukite..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Įjungiamas „Bluetooth“…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Failas bus gautas. Patikrinkite eigą skydelyje „Pranešimai“."</string>
diff --git a/res/values-lt/strings_map.xml b/res/values-lt/strings_map.xml
new file mode 100644
index 0000000..4441b07
--- /dev/null
+++ b/res/values-lt/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Įveskite %1$s seanso raktą"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Reikalingas „Bluetooth“ seanso raktas"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Baigėsi skirtasis ryšio su %1$s priėmimo laikas"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Baigėsi įvesties seanso rakto su %1$s skirtasis laikas"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"„Obex“ tapatybės nustatymo užklausa"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Seanso raktas"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Įveskite %1$s seanso raktą"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Automobilinė įranga"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nežinomas pavadinimas"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mano vardas"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index e5a457e..1bcd05f 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Atcelt"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Ieslēgt"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Faila pārsūtīšana"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> vēlas nosūtīt jums failu <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>)."\n\n"Vai pieņemt šo failu?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> vēlas nosūtīt jums failu <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>).\n\nVai pieņemt šo failu?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Noraidīt"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Piekrist"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Labi"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Aizvērt"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Labi"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Nezināms fails"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Nav nevienas lietotnes, ar kuru var apstrādāt šī tipa failu. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Nav nevienas lietotnes, ar kuru var apstrādāt šī tipa failu. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nav faila"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Šāds fails nepastāv. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Šāds fails nepastāv. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Lūdzu, uzgaidiet…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Tiek ieslēgts Bluetooth savienojums..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Fails tiks saņemts. Skatiet progresu paziņojumu panelī."</string>
diff --git a/res/values-lv/strings_map.xml b/res/values-lv/strings_map.xml
new file mode 100644
index 0000000..a60fd69
--- /dev/null
+++ b/res/values-lv/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Ierīces “%1$s” sesijas atslēgas ievadīšana"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Nepieciešama Bluetooth sesijas atslēga"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Radās noildze, apstiprinot savienojumu ar ierīci “%1$s”."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Radās noildze, ievadot ierīces “%1$s” sesijas atslēgu."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex autentifikācijas pieprasījums"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sesijas atslēga"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Ievadiet ierīces “%1$s” sesijas atslēgu."</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Automobiļa komplekts"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nezināms nosaukums"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mans vārds"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..c35997d
--- /dev/null
+++ b/res/values-mn-rMN/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Татан авалтын менежерт хандалт хийх."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Апп-д BluetoothShare менежерт хандах, үүнийг ашиглан файл дамжуулах боломж олгоно."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Цагаан жагсаалтаар bluetooth төхөөрөмжид хандалт хийх."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Апп-т Bluetooth төхөөрөмжийг цагаан жагсаалтад оруулж хэрэглэгчийн баталгаажуулалт шаардахгүйгээр тус төхөөрөмж рүү файл илгээх боломж олгоно."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"BT дамжуулалтын нэвтрүүлгийг хүлээн авах."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Bluetooth-с дамжуулалтын статусын мэдээллийг хүлээн авах боломж олгоно."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Үл мэдэгдэх төхөөрөмж"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Тодорхойгүй"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Нислэгийн горим"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Та Нислэгийн горимд Bluetooth ашиглах боломжгүй."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Bluetooth үйлчилгээг ашиглахын тулд та эхлээд Bluetooth-ээ асаах шаардлагатай."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Bluetooth-г одоо асаах уу?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Цуцлах"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Асаах"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Файл дамжуулалт"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" танд <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>)-г илгээхийг хүсэж байна. \n\n Энэ файлыг авах уу?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Татгалзах"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Зөвшөөрөх"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Тийм"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"\"<xliff:g id="SENDER">%1$s</xliff:g>\"-с ирж байгаа файлыг зөвшөөрөх явцад хугацаа хэтэрсэн байна"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth хуваалцах: Ирж байгаа файл"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Та энэ файлыг хүлээн авахыг хүсэж байна уу?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Өөр төхөөрөмжөөс ирж байгаа файл. Та энэ файлыг хүлээн авахыг хүсэж байгаагаа баталгаажуулна уу."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Bluetooth хуваалцах: Хүлээн авч байна <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Bluetooth хуваалцах: Хүлээн авсан <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Bluetooth хуваалцах: Файл <xliff:g id="FILE">%1$s</xliff:g> хүлээж аваагүй"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Bluetooth хуваалцах: Илгээж байна <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Bluetooth хуваалцах: Илгээсэн <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"100% дууссан"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Bluetooth хуваалцах: <xliff:g id="FILE">%1$s</xliff:g> файл илгээгдээгүй"</string>
+    <string name="download_title" msgid="3353228219772092586">"Файл дамжуулалт"</string>
+    <string name="download_line1" msgid="4926604799202134144">"Илгээгч: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"Файл: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"Файлын хэмжээ: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Файлыг хүлээн авч байна…"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Зогсоох"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Нуух"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"Файлыг хүлээж аваагүй"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"Файл: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Шалтгаан: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"Тийм"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"Файлыг хүлээж авсан"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Нээх"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"Хэнд: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"Файлын хэлбэр: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Файл илгээж байна…"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"Файлыг илгээсэн"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"Тийм"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"Файл \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" руу илгээгдсэнгүй."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"Файл: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Дахин оролдоно уу"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Хаах"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"Тийм"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Үл мэдэгдэх файл"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Ийм төрлийн файлыг нээх апп байхгүй байна. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"Файл байхгүй"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл байхгүй байна. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Түр хүлээнэ үү..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth-г асааж байна…"</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"Файлыг хүлээж авах болно. Мэдэгдлийн самбар дээрээс явцыг нь шалгана уу."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"Файлыг хүлээн авах боломжгүй."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"\"<xliff:g id="SENDER">%1$s</xliff:g>\"-с файл хүлээн авахыг зогсоосон"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" руу файлыг илгээж байна"</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"<xliff:g id="NUMBER">%1$s</xliff:g> файлуудыг \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\" руу илгээж байна"</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" руу файл илгээхийн зогсоосон"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"USB сан дотор \"<xliff:g id="SENDER">%1$s</xliff:g>\"-с ирүүлсэн файлыг хадгалах хангалттай зай байхгүй байна"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"SD карт дээр \"<xliff:g id="SENDER">%1$s</xliff:g>\"-с ирүүлсэн файлыг хадгалах хангалттай зай байхгүй байна"</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Шаардлагатай зай: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Хэт олон хүсэлтийг боловсруулж байна. Дараа дахин оролдоно уу."</string>
+    <string name="status_pending" msgid="2503691772030877944">"Файл дамжуулалт хараахан эхлээгүй байна."</string>
+    <string name="status_running" msgid="6562808920311008696">"Файл дамжуулалт үргэлжилж байна."</string>
+    <string name="status_success" msgid="239573225847565868">"Файл дамжуулалт амжилттай дууслаа."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Контент дэмжигдэхгүй байна."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"Дамжуулалтыг хүлээн авагч төхөөрөмжөөс хориглосон."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Дамжуулалтыг хэрэглэгч цуцалсан."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Хадгалах сангийн асуудал."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"USB сан алга байна."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD карт алга байна. Дамжуулсан файлуудыг хадгалахын тулд SD карт хийнэ үү."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Холболт амжилтгүй."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Хүсэлтийг зөв гүйцэтгэх боломжгүй."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Тодорхойгүй алдаа."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth хүлээж авсан"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Бүрэн хүлээж авсан."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Илгээж дууссан."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Дотогш чиглэсэн дамжуулалт"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Гадагш чиглэсэн дамжуулалт"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"Дамжуулсан түүх хоосон байна."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Жагсаалтаас бүгдийг нь арилгах болно."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth хуваалцах: Илгээсэн файлууд"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth хуваалцах: Хүлээн авсан файлууд"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> амжилттай, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> амжилтгүй."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Жагсаалтыг арилгах"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"Нээх"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Жагсаалтаас арилгах"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Арилгах"</string>
+</resources>
diff --git a/res/values-mn-rMN/strings_map.xml b/res/values-mn-rMN/strings_map.xml
new file mode 100644
index 0000000..45fc07d
--- /dev/null
+++ b/res/values-mn-rMN/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Блютүүт горимын түлхүүр шаардлагатай"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-тай холболт хийхийг зөвшөөрөх явцад хугацаа хэтэрсэн байна"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-д горимын түлхүүр оруулах явцад хугацаа хэтэрсэн байна"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex гэрчлэлтийн хүсэлт"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Горимын Түлхүүр"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Тодорхойгүй нэр"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Миний нэр"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-mn-rMN/strings_pbap.xml b/res/values-mn-rMN/strings_pbap.xml
new file mode 100644
index 0000000..121d32a
--- /dev/null
+++ b/res/values-mn-rMN/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth горимын түлхүүр шаардлагатай"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"%1$s-тай холболт хийхийг зөвшөөрөх явцад хугацаа хэтэрсэн байна"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s-д горимын түлхүүр оруулах явцад хугацаа хэтэрсэн байна"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex гэрчлэлтийн хүсэлт"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Горимын Түлхүүр"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Carkit"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Тодорхойгүй нэр"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"Миний нэр"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-mn-rMN/test_strings.xml b/res/values-mn-rMN/test_strings.xml
new file mode 100644
index 0000000..43e8d2e
--- /dev/null
+++ b/res/values-mn-rMN/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Сайн уу, TestActivity"</string>
+    <string name="app_name" msgid="1203877025577761792">"Bluetooth Хуваалцах"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Бичлэг оруулах"</string>
+    <string name="update_record" msgid="2480425402384910635">"Бичлэгийг баталгаажуулах"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Ack бичлэг"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Бүх бичлэгийг устгах"</string>
+    <string name="ok_button" msgid="6519033415223065454">"Тийм"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Бичлэгийг устгах"</string>
+    <string name="start_server" msgid="9034821924409165795">"TCP серверийг эхлүүлэх"</string>
+    <string name="notify_server" msgid="4369106744022969655">"TCP серверт мэдэгдэх"</string>
+</resources>
diff --git a/res/values-mn/strings_map.xml b/res/values-mn/strings_map.xml
new file mode 100644
index 0000000..45fc07d
--- /dev/null
+++ b/res/values-mn/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Блютүүт горимын түлхүүр шаардлагатай"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s-тай холболт хийхийг зөвшөөрөх явцад хугацаа хэтэрсэн байна"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s-д горимын түлхүүр оруулах явцад хугацаа хэтэрсэн байна"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex гэрчлэлтийн хүсэлт"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Горимын Түлхүүр"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s-н горимын түлхүүрийг оруулна уу"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Тодорхойгүй нэр"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Миний нэр"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..84c29e9
--- /dev/null
+++ b/res/values-ms-rMY/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Akses pengurus muat turun."</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Membenarkan aplikasi mengakses pengurus Perkongsian Bluetooth dan menggunakannya untuk memindahkan fail."</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Akses peranti bluetooth senarai putih."</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Membenarkan apl untuk menyenarai putihkan peranti Bluetooth sementara waktu, membolehkan peranti itu menghantar fail ke peranti ini tanpa pengesahan pengguna."</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"Terima siaran pemindahan penyerahan BT."</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"Membolehkan penerimaan maklumat status pemindahan penyerahan dari Bluetooth."</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"Peranti tidak diketahui"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"Tidak diketahui"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Mod pesawat"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Anda tidak boleh menggunakan Bluetooth dalam mod Pesawat."</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Untuk menggunakan perkhidmatan Bluetooth, anda perlu menghidupkan Bluetooth terlebih dahulu."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Hidupkan Bluetooth sekarang?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"Batal"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Hidupkan"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Pemindahan fail"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" mahu menghantar <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) kepada anda. \n\n Terima fail?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Tolak"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Terima"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"Berlaku tamat masa semasa menerima fail masuk daripada \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Perkongsian Bluetooth: Fail masuk"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Adakah anda mahu menerima fail ini?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Fail masuk daripada peranti lain. Sila sahkan bahawa anda mahu menerima fail ini."</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"Perkongsian Bluetooth: Menerima <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Perkongsian Bluetooth: Diterima <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"Perkongsian Bluetooth: Fail <xliff:g id="FILE">%1$s</xliff:g> tidak diterima"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"Perkongsian Bluetooth: Menghantar <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Perkongsian Bluetooth: Dihantar <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"Selesai 100%"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"Perkongsian Bluetooth: Fail <xliff:g id="FILE">%1$s</xliff:g> tidak dihantar"</string>
+    <string name="download_title" msgid="3353228219772092586">"Pemindahan fail"</string>
+    <string name="download_line1" msgid="4926604799202134144">"Daripada: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="download_line2" msgid="5876973543019417712">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"Saiz fail: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"Menerima fail..."</string>
+    <string name="download_cancel" msgid="9177305996747500768">"Berhenti"</string>
+    <string name="download_ok" msgid="5000360731674466039">"Sembunyi"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"Fail tidak diterima"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"Sebab: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"OK"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"Fail diterima"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"Buka"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"Kepada: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line3" msgid="4920689672457037437">"Jenis fail: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"Menghantar fail..."</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"Fail telah dihantar"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"OK"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"Fail tidak dihantarkan kepada \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\"."</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"Fail: <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"Cuba lagi"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"Tutup"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"Fail tidak diketahui"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Tiada aplikasi untuk mengendalikan fail jenis ini. \n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"Tiada fail"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Fail tidak wujud. \n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"Sila tunggu..."</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Menghidupkan Bluetooth..."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"Fail akan diterima. Semak kemajuan dalam panel Pemberitahuan."</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"Fail tidak boleh diterima."</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"Penerimaan fail daripada \"<xliff:g id="SENDER">%1$s</xliff:g>\" dihentikan"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"Menghantar fail kepada \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"Menghantar <xliff:g id="NUMBER">%1$s</xliff:g> fail kepada \"<xliff:g id="RECIPIENT">%2$s</xliff:g>\""</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"Penghantaran fail ke \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" dihentikan"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"Tiada ruang mencukupi pada storan USB untuk menyimpan fail daripada \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"Tiada ruang mencukupi pada kad SD untuk menyimpan fail daripada \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"Ruang diperlukan: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"Terlalu banyak permintaan sedang diproses. Cuba sebentar lagi."</string>
+    <string name="status_pending" msgid="2503691772030877944">"Pemindahan fail belum lagi dimulakan."</string>
+    <string name="status_running" msgid="6562808920311008696">"Pemindahan fail sedang berlangsung."</string>
+    <string name="status_success" msgid="239573225847565868">"Pemindahan fail berjaya diselesaikan."</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"Kandungan tidak disokong."</string>
+    <string name="status_forbidden" msgid="613956401054050725">"Pemindahan dilarang oleh peranti sasaran."</string>
+    <string name="status_canceled" msgid="6664490318773098285">"Pemindahan dibatalkan oleh pengguna."</string>
+    <string name="status_file_error" msgid="3671917770630165299">"Isu storan."</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"Tiada storan USB."</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"Tiada kad SD. Masukkan kad SD untuk menyimpan fail yang dipindahkan."</string>
+    <string name="status_connection_error" msgid="947681831523219891">"Sambungan tidak berjaya."</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"Permintaan tidak dapat dikendalikan dengan betul."</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"Ralat tidak diketahui."</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth diterima"</string>
+    <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Penerimaan selesai."</string>
+    <string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Penghantaran selesai."</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"Pemindahan masuk"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"Pemindahan keluar"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"Sejarah pemindahan kosong."</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Semua item akan dipadam bersih daripada senarai."</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"Perkongsian Bluetooth: Fail diterima"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Perkongsian Bluetooth: Fail diterima"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> berjaya, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> tidak berjaya."</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Padam bersih senarai"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"Buka"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Padam bersih daripada senarai"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Padam bersih"</string>
+</resources>
diff --git a/res/values-ms-rMY/strings_map.xml b/res/values-ms-rMY/strings_map.xml
new file mode 100644
index 0000000..afc98d7
--- /dev/null
+++ b/res/values-ms-rMY/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Kunci sesi Bluetooth diperlukan"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Berlaku tamat masa semasa menerima sambungan dengan %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Tamat masa berlaku semasa memasukkan kunci sesi dengan %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Permintaan pengesahan Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Kunci Sesi"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit kereta"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nama tidak diketahui"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Nama saya"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ms-rMY/strings_pbap.xml b/res/values-ms-rMY/strings_pbap.xml
new file mode 100644
index 0000000..63f873d
--- /dev/null
+++ b/res/values-ms-rMY/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Kunci sesi Bluetooth diperlukan"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"Berlaku tamat masa semasa menerima sambungan dengan %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"Tamat masa berlaku semasa memasukkan kunci sesi dengan %1$s"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Permintaan pengesahan Obex"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Kunci Sesi"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="defaultname" msgid="4821590500649090078">"Kit kereta"</string>
+    <string name="unknownName" msgid="2841414754740600042">"Nama tidak diketahui"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"Nama saya"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-ms-rMY/test_strings.xml b/res/values-ms-rMY/test_strings.xml
new file mode 100644
index 0000000..ead3bc8
--- /dev/null
+++ b/res/values-ms-rMY/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"Hello World, AktivitiUjian"</string>
+    <string name="app_name" msgid="1203877025577761792">"Perkongsian Bluetooth"</string>
+    <string name="insert_record" msgid="1450997173838378132">"Masukkan rekod"</string>
+    <string name="update_record" msgid="2480425402384910635">"Sahkan rekod"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Rekod Ack"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Padamkan semua rekod"</string>
+    <string name="ok_button" msgid="6519033415223065454">"OK"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Padamkan rekod"</string>
+    <string name="start_server" msgid="9034821924409165795">"Mulakan pelayan TCP"</string>
+    <string name="notify_server" msgid="4369106744022969655">"Beritahu pelayan TCP"</string>
+</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index ff386c0..84c29e9 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Batal"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Hidupkan"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Pemindahan fail"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" mahu menghantar <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) kepada anda. "\n\n" Terima fail?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" mahu menghantar <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) kepada anda. \n\n Terima fail?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Tolak"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Terima"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Tutup"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Fail tidak diketahui"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Tiada aplikasi untuk mengendalikan fail jenis ini. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Tiada aplikasi untuk mengendalikan fail jenis ini. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Tiada fail"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Fail tidak wujud. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Fail tidak wujud. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Sila tunggu..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Menghidupkan Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Fail akan diterima. Semak kemajuan dalam panel Pemberitahuan."</string>
diff --git a/res/values-ms/strings_map.xml b/res/values-ms/strings_map.xml
new file mode 100644
index 0000000..afc98d7
--- /dev/null
+++ b/res/values-ms/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Kunci sesi Bluetooth diperlukan"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Berlaku tamat masa semasa menerima sambungan dengan %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Tamat masa berlaku semasa memasukkan kunci sesi dengan %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Permintaan pengesahan Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Kunci Sesi"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Taipkan kunci sesi untuk %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit kereta"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nama tidak diketahui"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Nama saya"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index ce65721..7496fec 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Avbryt"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Slå på"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Filoverføring"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"«<xliff:g id="SENDER">%1$s</xliff:g>» vil sende deg <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Vil du godta filen?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"«<xliff:g id="SENDER">%1$s</xliff:g>» vil sende deg <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Vil du godta filen?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Avslå"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Godta"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Lukk"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Ukjent fil"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Det finnes ingen app på enheten som kan håndtere denne filtypen. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Det finnes ingen app på enheten som kan håndtere denne filtypen. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ingen fil"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen finnes ikke. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen finnes ikke. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Vent litt ..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Aktiverer Bluetooth …"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Filen vil bli mottatt. Du kan se fremdriften i varselpanelet."</string>
diff --git a/res/values-nb/strings_map.xml b/res/values-nb/strings_map.xml
new file mode 100644
index 0000000..5b6cc48
--- /dev/null
+++ b/res/values-nb/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Skriv inn øktsnøkkel for %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-øktsnøkkel kreves"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Det tok for lang tid å godta forbindelsen med «%1$s»"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Det tok for lang tid å legge inn øktsnøkkel med %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Autentiseringsforespørsel fra Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Øktsnøkkel"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Skriv inn øktsnøkkel for %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Bilsett"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Ukjent navn"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Navnet mitt"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ne-rNP/strings_map.xml b/res/values-ne-rNP/strings_map.xml
new file mode 100644
index 0000000..7584c1e
--- /dev/null
+++ b/res/values-ne-rNP/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"ब्लूटूथ सत्र कुञ्जी आवश्यक"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s सँग जडान स्वीकार गर्न समय सकियो"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s का साथ सत्र कुञ्जी इनपुट गर्ने समय सकियो"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex प्रमाणिकरण अनुरोध"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"सत्र कुञ्जी"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"अज्ञात नाम"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"मेरो नाम"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"००००००"</string>
+</resources>
diff --git a/res/values-ne/strings_map.xml b/res/values-ne/strings_map.xml
new file mode 100644
index 0000000..7584c1e
--- /dev/null
+++ b/res/values-ne/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"ब्लूटूथ सत्र कुञ्जी आवश्यक"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s सँग जडान स्वीकार गर्न समय सकियो"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s का साथ सत्र कुञ्जी इनपुट गर्ने समय सकियो"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex प्रमाणिकरण अनुरोध"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"सत्र कुञ्जी"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"अज्ञात नाम"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"मेरो नाम"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"००००००"</string>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index ea3437d..e786358 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Annuleren"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Inschakelen"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Bestandsoverdracht"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\'<xliff:g id="SENDER">%1$s</xliff:g>\' wil <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) naar u verzenden. "\n\n" Het bestand accepteren?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\'<xliff:g id="SENDER">%1$s</xliff:g>\' wil <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) naar u verzenden. \n\n Het bestand accepteren?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Weigeren"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Accepteren"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Sluiten"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Onbekend bestand"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Er is geen app om dit type bestand af te handelen. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Er is geen app om dit type bestand af te handelen. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Geen bestand"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Het bestand bestaat niet. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Het bestand bestaat niet. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Een ogenblik geduld..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth inschakelen…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Het bestand wordt ontvangen. U kunt de voortgang controleren in het venster \'Meldingen\'."</string>
diff --git a/res/values-nl/strings_map.xml b/res/values-nl/strings_map.xml
new file mode 100644
index 0000000..261bb63
--- /dev/null
+++ b/res/values-nl/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Typ de sessiesleutel voor %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth-sessiesleutel is vereist"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Er is een time-out opgetreden voor het accepteren van de verbinding met %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Er is een time-out opgetreden tijdens het invoeren van de sessiesleutel met %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"OBEX-verificatieverzoek"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sessiesleutel"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Typ de sessiesleutel voor %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Onbekende naam"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mijn naam"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index c60cdc5..72795c5 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Anuluj"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Włącz"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Przesyłanie pliku"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Urządzenie „<xliff:g id="SENDER">%1$s</xliff:g>” chce wysłać do Ciebie plik <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Czy zaakceptować ten plik?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Urządzenie „<xliff:g id="SENDER">%1$s</xliff:g>” chce wysłać do Ciebie plik <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Czy zaakceptować ten plik?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Odrzuć"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Akceptuj"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Zamknij"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Nieznany plik"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Brak aplikacji do obsługi tego typu pliku "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Brak aplikacji do obsługi tego typu pliku \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Brak pliku"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Plik nie istnieje. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Plik nie istnieje. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Czekaj…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Włączanie Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Plik zostanie odebrany. Sprawdzaj postęp na panelu powiadomień."</string>
diff --git a/res/values-pl/strings_map.xml b/res/values-pl/strings_map.xml
new file mode 100644
index 0000000..6de3584
--- /dev/null
+++ b/res/values-pl/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Wpisz klucz sesji dla: %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Wymagany klucz sesji Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Przekroczono limit czasu na akceptację połączenia z: %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Przekroczono limit czasu na wprowadzenie klucza sesji z: %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Żądanie uwierzytelniania Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Klucz sesji"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Wpisz klucz sesji dla: %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Zestaw samochodowy"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nieznana nazwa"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Moja nazwa"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a1593f6..5e59155 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -28,12 +28,12 @@
     <string name="airplane_error_title" msgid="2683839635115739939">"Modo de avião"</string>
     <string name="airplane_error_msg" msgid="8698965595254137230">"Não pode utilizar o Bluetooth em modo de Avião."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
-    <string name="bt_enable_line1" msgid="7203551583048149">"Para utilizar os serviços Bluetooth, tem de activar primeiro o Bluetooth."</string>
-    <string name="bt_enable_line2" msgid="4341936569415937994">"Activar o Bluetooth agora?"</string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Para utilizar os serviços Bluetooth, tem de ativar primeiro o Bluetooth."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Ativar o Bluetooth agora?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancelar"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Ativar"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferência do ficheiro"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" quer enviar-lhe <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Aceita o ficheiro?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" quer enviar-lhe <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Aceita o ficheiro?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Recusar"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aceitar"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Fechar"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Ficheiro desconhecido"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Não existe nenhuma aplicação para executar este tipo de ficheiro. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Não existe nenhuma aplicação para executar este tipo de ficheiro. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nenhum ficheiro"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"O ficheiro não existe. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"O ficheiro não existe. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Aguarde..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"A ligar Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"O ficheiro será recebido. Consulte o progresso no painel Notificações."</string>
diff --git a/res/values-pt-rPT/strings_map.xml b/res/values-pt-rPT/strings_map.xml
new file mode 100644
index 0000000..1e1a071
--- /dev/null
+++ b/res/values-pt-rPT/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Escreva a chave de sessão para %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Necessária chave de sessão Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Foi excedido o tempo para aceitar a ligação a %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Foi excedido o tempo para introduzir a chave de sessão com %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Pedido de autenticação OBEX"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Chave de sessão"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Escreva a chave de sessão para %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit para carro"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nome desconhecido"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"O meu nome"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index aa2ec74..3b72c6c 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -25,15 +25,15 @@
     <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
     <string name="unknown_device" msgid="9221903979877041009">"Dispositivo desconhecido"</string>
     <string name="unknownNumber" msgid="4994750948072751566">"Desconhecido"</string>
-    <string name="airplane_error_title" msgid="2683839635115739939">"Modo para avião"</string>
-    <string name="airplane_error_msg" msgid="8698965595254137230">"Não é possível usar o Bluetooth no modo para avião."</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"Modo avião"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"Não é possível usar o Bluetooth no modo avião."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
     <string name="bt_enable_line1" msgid="7203551583048149">"Para usar os serviços de Bluetooth, é necessário ativar o Bluetooth."</string>
     <string name="bt_enable_line2" msgid="4341936569415937994">"Ativar Bluetooth agora?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Cancelar"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Ativar"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferência de arquivo"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" deseja enviar para você <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Aceitar o arquivo?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" deseja enviar para você <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Aceitar o arquivo?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Recusar"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aceitar"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Fechar"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Arquivo desconhecido"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Não há um aplicativo para lidar com este tipo de arquivo. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Não há um aplicativo para lidar com este tipo de arquivo. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Nenhum arquivo"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"O arquivo não existe. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"O arquivo não existe. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Aguarde..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Ativando Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"O arquivo será recebido. Verifique o andamento no painel de Notificações."</string>
diff --git a/res/values-pt/strings_map.xml b/res/values-pt/strings_map.xml
new file mode 100644
index 0000000..d2e66f7
--- /dev/null
+++ b/res/values-pt/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Digite a chave de sessão para %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"É necessário fornecer a chave de sessão Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Tempo limite esgotado para aceitar a conexão com %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Tempo limite esgotado para inserir a chave de sessão com %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Solicitação de autenticação Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Chave de sessão"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Digite a chave de sessão para %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kit para carro"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nome desconhecido"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Meu nome"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 0c849d7..67ea370 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -39,7 +39,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Interrumper"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activar"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfer da datoteca"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> As tramettess gugent <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Acceptar la datoteca?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> As tramettess gugent <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Acceptar la datoteca?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Refusar"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Acceptar"</string>
     <!-- no translation found for incoming_file_confirm_timeout_ok (1414676773249857278) -->
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 99ac76d..713d026 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -33,12 +33,12 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Anulaţi"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Activaţi"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transfer de fişier"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>” doreşte să vă trimită <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Acceptaţi acest fişier?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>” doreşte să vă trimită <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Acceptaţi acest fişier?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Refuzaţi"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Acceptaţi"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
     <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"A fost atins timpul limită pentru acceptarea unui fişier primit de la „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
-    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Distribuire prin Bluetooth: se primeşte fişierul"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"Bluetooth: se primeşte fişierul"</string>
     <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Doriţi să primiţi acest fişier?"</string>
     <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Un fişier de la alt dispozitiv se află în curs de primire. Confirmaţi dacă doriţi primirea acestuia."</string>
     <string name="notification_receiving" msgid="4674648179652543984">"Distribuire prin Bluetooth: se primeşte <xliff:g id="FILE">%1$s</xliff:g>"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Închideţi"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Fişier necunoscut"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Nu există nicio aplicaţie care să gestioneze acest tip de fişier. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Nu există nicio aplicaţie care să gestioneze acest tip de fişier. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Niciun fişier"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Fişierul nu există. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Fişierul nu există. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Aşteptaţi..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Se activează Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Se va primi fişierul. Verificaţi progresul în panoul de notificări."</string>
@@ -108,10 +108,10 @@
     <string name="no_transfers" msgid="3482965619151865672">"Istoricul de transferuri este gol."</string>
     <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Toate elementele din listă vor fi eliminate."</string>
     <string name="outbound_noti_title" msgid="8051906709452260849">"Distribuire prin Bluetooth: fişiere trimise"</string>
-    <string name="inbound_noti_title" msgid="4143352641953027595">"Distribuire prin Bluetooth: fişiere primite"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth: fișiere primite"</string>
     <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> reuşite, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> eşuate."</string>
-    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Ştergeţi lista"</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"Ștergeţi lista"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"Deschideţi"</string>
-    <string name="transfer_menu_clear" msgid="5854038118831427492">"Ştergeţi din listă"</string>
-    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Ştergeţi"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"Ștergeţi din listă"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Ștergeţi"</string>
 </resources>
diff --git a/res/values-ro/strings_map.xml b/res/values-ro/strings_map.xml
new file mode 100644
index 0000000..bfed36c
--- /dev/null
+++ b/res/values-ro/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Introduceţi cheia de sesiune pentru %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Cheie de sesiune Bluetooth solicitată"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"A expirat timpul pentru acceptarea conexiunii cu %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"A expirat timpul de introducere a cheii de sesiune cu %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Cerere de autentificare pentru protocolul OBEX"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Cheia sesiunii"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Introduceţi cheia de sesiune pentru %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Set de maşină"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Nume necunoscut"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Numele meu"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-ro/test_strings.xml b/res/values-ro/test_strings.xml
index 1174667..3e10db1 100644
--- a/res/values-ro/test_strings.xml
+++ b/res/values-ro/test_strings.xml
@@ -6,9 +6,9 @@
     <string name="insert_record" msgid="1450997173838378132">"Inseraţi o înregistrare"</string>
     <string name="update_record" msgid="2480425402384910635">"Confirmaţi înregistrarea"</string>
     <string name="ack_record" msgid="6716152390978472184">"Înregistrare Ack"</string>
-    <string name="deleteAll_record" msgid="4383349788485210582">"Ştergeţi toate înregistrările"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"Ștergeţi toate înregistrările"</string>
     <string name="ok_button" msgid="6519033415223065454">"OK"</string>
-    <string name="delete_record" msgid="4645040331967533724">"Ştergeţi înregistrarea"</string>
+    <string name="delete_record" msgid="4645040331967533724">"Ștergeţi înregistrarea"</string>
     <string name="start_server" msgid="9034821924409165795">"Porniţi serverul TCP"</string>
     <string name="notify_server" msgid="4369106744022969655">"Notificaţi serverul TCP"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index fc66903..4251973 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Отмена"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Включить"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Передача файла"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" отправляет вам файл <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n"Принять файл?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" отправляет вам файл <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\nПринять файл?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Отклонить"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Принять"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ОК"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Закрыть"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"ОК"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Неизвестный файл"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Нет приложений для работы с файлами этого типа. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Нет приложений для работы с файлами этого типа. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Нет файла"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не существует. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не существует. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Подождите..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Включение Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Этот файл будет получен. Ход выполнения отображается на панели уведомлений."</string>
diff --git a/res/values-ru/strings_map.xml b/res/values-ru/strings_map.xml
new file mode 100644
index 0000000..f51054b
--- /dev/null
+++ b/res/values-ru/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Введите ключ сеанса для %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Необходим ключ сеанса Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Истекло время ожидания при установке подключения к %1$s."</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Истекло время ожидания ввода ключа сеанса для связи с %1$s."</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Запрос на аутентификацию Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ключ сеанса"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Введите ключ сеанса для %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Автомобильный комплект"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Без названия"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Мое название"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-si-rLK/strings_map.xml b/res/values-si-rLK/strings_map.xml
new file mode 100644
index 0000000..31c2feb
--- /dev/null
+++ b/res/values-si-rLK/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s සඳහා සැසි යතුර ටයිප් කරන්න"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"බ්ලූටූත් සැසි යතුර අවශ්‍යයි"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s හා සම්බන්ධය පිළිගැනීමට කාල නිමාවක්  විය"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s හා සැසි යතුර ආදානය කිරීමට කාල නිමාවක් විය"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex සත්‍යාපන ඉල්ලීම"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"සැසි යතුර"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s සඳහා සැසි යතුර ටයිප් කරන්න"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"නොදන්නා නමකි"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"මගේ නම"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-si/strings_map.xml b/res/values-si/strings_map.xml
new file mode 100644
index 0000000..31c2feb
--- /dev/null
+++ b/res/values-si/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s සඳහා සැසි යතුර ටයිප් කරන්න"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"බ්ලූටූත් සැසි යතුර අවශ්‍යයි"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s හා සම්බන්ධය පිළිගැනීමට කාල නිමාවක්  විය"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s හා සැසි යතුර ආදානය කිරීමට කාල නිමාවක් විය"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex සත්‍යාපන ඉල්ලීම"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"සැසි යතුර"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s සඳහා සැසි යතුර ටයිප් කරන්න"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"නොදන්නා නමකි"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"මගේ නම"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index b584699..198bbb7 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Získať prístup k správcovi preberania."</string>
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Získať prístup k správcovi sťahovania."</string>
     <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Umožňuje aplikácii pristupovať k Správcovi BluetoothShare a použiť ho na prenos súborov."</string>
     <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Prístup povoleného zariadenia Bluetooth."</string>
     <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Umožňuje aplikácii dočasne povoliť zariadenie Bluetooth, čím sa povolí zariadeniu odosielať súbory do tohto zariadenia bez potvrdenia používateľa."</string>
@@ -28,12 +28,12 @@
     <string name="airplane_error_title" msgid="2683839635115739939">"Režim V lietadle"</string>
     <string name="airplane_error_msg" msgid="8698965595254137230">"Technológiu Bluetooth nemôžete používať v režime V lietadle."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
-    <string name="bt_enable_line1" msgid="7203551583048149">"Komu používať služby Bluetooth, musíte najskôr rozhranie Bluetooth zapnúť."</string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Ak chcete používať služby Bluetooth, musíte najskôr rozhranie Bluetooth zapnúť."</string>
     <string name="bt_enable_line2" msgid="4341936569415937994">"Zapnúť Bluetooth?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Zrušiť"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Zapnúť"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Prenos súborov"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Používateľ <xliff:g id="SENDER">%1$s</xliff:g> sa vám pokúša odoslať súbor <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Chcete súbor prijať?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Používateľ <xliff:g id="SENDER">%1$s</xliff:g> sa vám pokúša odoslať súbor <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Chcete súbor prijať?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Odmietnuť"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Prijať"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Zavrieť"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Neznámy súbor"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Na spracovanie tohto typu súboru nemáte žiadnu aplikáciu. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Na spracovanie tohto typu súboru nemáte žiadnu aplikáciu. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Žiadny súbor"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Súbor neexistuje. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Súbor neexistuje. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Čakajte..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Prebieha zapínanie rozhrania Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Prebehne prijatie súboru. Priebeh môžete sledovať na paneli Oznámenie."</string>
diff --git a/res/values-sk/strings_map.xml b/res/values-sk/strings_map.xml
new file mode 100644
index 0000000..0b4d771
--- /dev/null
+++ b/res/values-sk/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Zadajte kľúč relácie pre zariadenie %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Požaduje sa kľúč relácie Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Časový limit na pripojenie k zariadeniu „%1$s“ vypršal"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Časový limit na zadanie kľúča relácie pre %1$s vypršal"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Žiadosť overenia Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Kľúč relácie"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Zadajte kľúč relácie pre zariadenie %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Súprava handsfree do auta"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Neznámy názov"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Moje meno"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 45760ba..31c6f36 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Prekliči"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Vklopi"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Prenos datoteke"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"»<xliff:g id="SENDER">%1$s</xliff:g>« vam želi poslati <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Želite sprejeti datoteko?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"»<xliff:g id="SENDER">%1$s</xliff:g>« vam želi poslati <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Želite sprejeti datoteko?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Zavrni"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Sprejmi"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"V redu"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Zapri"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"V redu"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Neznana datoteka"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Ni programa, s katerim bi bilo mogoče odpreti to vrsto datoteke. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Ni programa, s katerim bi bilo mogoče odpreti to vrsto datoteke. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ni datoteke"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Datoteka ne obstaja. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Datoteka ne obstaja. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Počakajte ..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Vklop Bluetootha …"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Datoteka bo prejeta. Potek preverite na plošči »Obvestila«."</string>
diff --git a/res/values-sl/strings_map.xml b/res/values-sl/strings_map.xml
new file mode 100644
index 0000000..1badf05
--- /dev/null
+++ b/res/values-sl/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Vnesite ključ seje za %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Zahtevan je ključ seje Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Iztekla se je časovna omejitev za sprejem povezave z »%1$s«"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Iztekla se je časovna omejitev za vnos ključa seje v %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Zahteva za preverjanje pristnosti Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ključ seje"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Vnesite ključ seje za %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Avtokomplet"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Neznano ime"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Moje ime"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index dcf66c4..cf770fd 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Откажи"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Укључи"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Пренос датотеке"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ жели да вам пошаље <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Желите ли да прихватите датотеку?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ жели да вам пошаље <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Желите ли да прихватите датотеку?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Одбиј"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Прихвати"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Потврди"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Затвори"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Потврди"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Непозната датотека"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Нема апликација за обраду овог типа датотеке. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Нема апликација за обраду овог типа датотеке. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Нема датотеке"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Датотека не постоји. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Датотека не постоји. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Сачекајте…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Укључивање Bluetooth-а…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Датотека ће бити примљена. Проверавајте ток на табли са обавештењима."</string>
diff --git a/res/values-sr/strings_map.xml b/res/values-sr/strings_map.xml
new file mode 100644
index 0000000..82c7982
--- /dev/null
+++ b/res/values-sr/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Унесите кључ сесије за %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Потребан је кључ сесије за Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Истекло је време за прихватање везе са уређајем %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Истекло је време за унос кључа сесије помоћу %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Захтев за потврду аутентичности преко Obex протокола"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Кључ сесије"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Унесите кључ сесије за %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Опрема за аутомобил"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Непознат назив"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Моје име"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 197621a..54e7b3e 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Avbryt"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Aktivera"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Filöverföring"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> vill skicka <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) till dig. "\n\n" Vill du ta emot filen?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"<xliff:g id="SENDER">%1$s</xliff:g> vill skicka <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) till dig. \n\n Vill du ta emot filen?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Avvisa"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Godkänn"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Stäng"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Okänd fil"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Det finns ingen app för att hantera denna typ av fil. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Det finns ingen app för att hantera denna typ av fil. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ingen fil"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen finns inte. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Filen finns inte. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Vänta …"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth aktiveras …"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Filen tas emot. Du kan se förloppet på aviseringspanelen."</string>
diff --git a/res/values-sv/strings_map.xml b/res/values-sv/strings_map.xml
new file mode 100644
index 0000000..059b3ef
--- /dev/null
+++ b/res/values-sv/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Ange sessionsnyckeln för %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"En Bluetooth-sessionsnyckel krävs"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Tidsgränsen för godkännande av anslutning till %1$s har överskridits"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Tiden för inmatning av sessionsnyckel med %1$s har gått ut"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex-autentiseringsbegäran"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Sessionsnyckel"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Ange sessionsnyckeln för %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Bilsats"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Okänt namn"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Mitt namn"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 384dcd9..d97cb52 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Ghairi"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Washa"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Uhamishaji faili"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" anataka kukutumia <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Ikubali faili?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" anataka kukutumia <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Ikubali faili?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Kataa"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Kubali"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Sawa"</string>
@@ -42,10 +42,10 @@
     <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"Je, unataka kupokea faili hii?"</string>
     <string name="incoming_file_toast_msg" msgid="1733710749992901811">"Faili zinazoingia kutoka kwa kifaa kingine. Thibitisha kuwa unataka kupokea faili hii."</string>
     <string name="notification_receiving" msgid="4674648179652543984">"Kushiriki kwa bluetooth: Inapokea <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_received" msgid="3324588019186687985">"Kushiriki kwa bluetooth: Ilipokea<xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"Kushiriki kwa bluetooth: Imepokea <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="notification_received_fail" msgid="3619350997285714746">"Kushiriki kwa Bluetooth: Faili <xliff:g id="FILE">%1$s</xliff:g> haijapokewa"</string>
     <string name="notification_sending" msgid="3035748958534983833">"Kushiriki kwa bluetooth: Inatuma <xliff:g id="FILE">%1$s</xliff:g>"</string>
-    <string name="notification_sent" msgid="9218710861333027778">"Kushiriki kwa bluetooth: <xliff:g id="FILE">%1$s</xliff:g> Iliyotumwa"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"Kushiriki kwa bluetooth: Imetuma <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="notification_sent_complete" msgid="302943281067557969">"Imekamilika 100%"</string>
     <string name="notification_sent_fail" msgid="6696082233774569445">"Kushiriki kwa bluetooth: Faili <xliff:g id="FILE">%1$s</xliff:g> haijatumwa"</string>
     <string name="download_title" msgid="3353228219772092586">"Uhamishaji faili"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Funga"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Sawa"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Faili isiyojulikana"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Hakuna programu ya kushughulikia aina hii ya faili. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Hakuna programu ya kushughulikia aina hii ya faili. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Hakuna faili."</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Faili haipo. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Faili haipo. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Tafadhali subiri…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Inawasha Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Faili itapokelewa. Kagua maendeleo katika paneli ya Arifa."</string>
@@ -100,7 +100,7 @@
     <string name="status_connection_error" msgid="947681831523219891">"Muunganisho haujafanikiwa."</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"Ombi haliwezi kushughulikiwa kwa usahihi."</string>
     <string name="status_unknown_error" msgid="8156660554237824912">"Hitilafu isiyojulikana."</string>
-    <string name="btopp_live_folder" msgid="7967791481444474554">"Bluetooth imepokelewa"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"Zilizopokewa kupitia Bluetooth"</string>
     <string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> Imepokelewa kikamilifu"</string>
     <string name="upload_success" msgid="4014469387779648949">"Kutuma kwa <xliff:g id="FILE_SIZE">%1$s</xliff:g> kumekamilika."</string>
     <string name="inbound_history_title" msgid="6940914942271327563">"Mahamisho yanayoingia"</string>
@@ -109,7 +109,7 @@
     <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"Vipengee vyote vitafutwa kutoka kwenye orodha."</string>
     <string name="outbound_noti_title" msgid="8051906709452260849">"Kushiriki kwa bluetooth: Faili zilizotumwa"</string>
     <string name="inbound_noti_title" msgid="4143352641953027595">"Kushiriki kwa bluetooth: Faili zilizopokelewa"</string>
-    <string name="noti_caption" msgid="7508708288885707365">"zimefanikiwa <xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g>, hazikufanikiwa <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g>"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> zimefanikiwa, <xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> hazikufanikiwa"</string>
     <string name="transfer_menu_clear_all" msgid="790017462957873132">"Futa orodha"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"Fungua"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Futa kutoka orodha"</string>
diff --git a/res/values-sw/strings_map.xml b/res/values-sw/strings_map.xml
new file mode 100644
index 0000000..1ac86e7
--- /dev/null
+++ b/res/values-sw/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Chapa nenosiri la kipindi cha %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Nenosiri la kipindi cha Bluetooth linahitajika"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Muda wa kukubali muunganisho na %1$s umepita"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Muda wa kuweka nenosiri kwa kipindi na %1$s umepita"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Ombi la uthibitishaji kutoka Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ufunguo wa Kipindi"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Chapa nenosiri la kipindi cha %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Kifaa cha gari"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Jina lisilojulikana"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Jina langu"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 9ff1952..617aae5 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"ยกเลิก"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"เปิด"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"การถ่ายโอนไฟล์"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ต้องการส่ง <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) ถึงคุณ "\n\n" ยอมรับไฟล์หรือไม่"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ต้องการส่ง <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) ถึงคุณ \n\n ยอมรับไฟล์หรือไม่"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"ปฏิเสธ"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"ยอมรับ"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ตกลง"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"ปิด"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"ตกลง"</string>
     <string name="unknown_file" msgid="6092727753965095366">"ไฟล์ที่ไม่รู้จัก"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"ไม่มีแอปพลิเคชันในการจัดการกับไฟล์ประเภทนี้"\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"ไม่มีแอปพลิเคชันในการจัดการกับไฟล์ประเภทนี้\n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"ไม่มีไฟล์"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"ไม่มีไฟล์นี้"\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"ไม่มีไฟล์นี้\n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"โปรดรอสักครู่..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"กำลังเปิดบลูทูธ…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"ไฟล์จะถูกรับ ดูความคืบหน้าในแผงการแจ้งเตือน"</string>
diff --git a/res/values-th/strings_map.xml b/res/values-th/strings_map.xml
new file mode 100644
index 0000000..b9008ee
--- /dev/null
+++ b/res/values-th/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"พิมพ์เซสชันคีย์ของ %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"ต้องใช้เซสชันคีย์ของบลูทูธ"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"หมดเวลายอมรับการเชื่อมต่อกับ %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"หมดเวลาป้อนเซสชันคีย์ด้วย %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"คำขอการตรวจสอบสิทธิ์ Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"เซสชันคีย์"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"พิมพ์เซสชันคีย์ของ %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"อุปกรณ์ในรถยนต์"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"ชื่อที่ไม่รู้จัก"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"ชื่อของฉัน"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 60137cd..a9923aa 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Kanselahin"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"I-on"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Paglilipat ng file"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Gusto kang padalhan ni \"<xliff:g id="SENDER">%1$s</xliff:g>\" ng <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Tanggapin ang file?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"Gusto kang padalhan ni \"<xliff:g id="SENDER">%1$s</xliff:g>\" ng <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Tanggapin ang file?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Tanggihan"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Tanggapin"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Isara"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Hindi kilalang file"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Walang app na mangangasiwa sa ganitong uri ng file. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Walang app na mangangasiwa sa ganitong uri ng file. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Walang file"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Hindi umiiral ang file. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Hindi umiiral ang file. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Pakihintay…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Ino-on ang Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Matatanggap ang file. Suriin ang pagsulong sa panel na Mga Notification."</string>
diff --git a/res/values-tl/strings_map.xml b/res/values-tl/strings_map.xml
new file mode 100644
index 0000000..e7dd123
--- /dev/null
+++ b/res/values-tl/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"I-type ang key ng session para kay %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Kinakailangan ang key ng session sa bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Nagkaroon ng time out upang tanggapin ang koneksyon sa %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Nagkaroon ng time out sa pag-input ng key ng session sa %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Kahilingan sa Obex na pagpapatunay"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Key ng Session"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"I-type ang key ng session para kay %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Carkit"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Hindi kilalang pangalan"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Pangalan ko"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 0b14c08..49083b3 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"İptal"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Aç"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Dosya aktarımı"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" size <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) dosyasını göndermek istiyor. "\n\n" Dosyayı kabul ediyor musunuz?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" size <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) dosyasını göndermek istiyor. \n\n Dosyayı kabul ediyor musunuz?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Reddet"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Kabul Et"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Tamam"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Kapat"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"Tamam"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Bilinmeyen dosya"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Bu dosya türünü işleyecek hiçbir uygulama yok. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Bu dosya türünü işleyecek hiçbir uygulama yok. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Dosya yok"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Dosya mevcut değil. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Dosya mevcut değil. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Lütfen bekleyin..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth açılıyor..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Dosya alınacak. İlerlemeyi Bildirimler panelinden izleyebilirsiniz."</string>
diff --git a/res/values-tr/strings_map.xml b/res/values-tr/strings_map.xml
new file mode 100644
index 0000000..7730ac7
--- /dev/null
+++ b/res/values-tr/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"%1$s için oturum anahtarını yazın"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Bluetooth oturum anahtarı gerekiyor"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"%1$s ile bağlantı yapılmasını kabul etme süresi doldu"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s ile oturum anahtarını girme süresi doldu"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex kimlik doğrulama isteği"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Oturum Anahtarı"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"%1$s için oturum anahtarını yazın"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Araç Kiti"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Bilinmeyen ad"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Adım"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 2497971..fdc66c1 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Скасувати"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Увімкнути"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Пересилка файлу"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" хоче надіслати вам <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Прийняти файл?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" хоче надіслати вам <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Прийняти файл?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Відхилити"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Прийняти"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Закрити"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Невідомий файл"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Немає програми для обробки цього типу файлу. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Немає програми для обробки цього типу файлу. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Немає файлу"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не існує. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Файл не існує. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Зачекайте…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Увімкнення Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Файл буде отримано. Перевіряйте прогрес на панелі сповіщень."</string>
diff --git a/res/values-uk/strings_map.xml b/res/values-uk/strings_map.xml
new file mode 100644
index 0000000..e4462b8
--- /dev/null
+++ b/res/values-uk/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Введіть ключ сеансу для %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Потрібен ключ сеансу Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Виникла затримка прийому з’єднання з %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Виникла затримка введення ключа сесії з %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Запит автентифікації Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ключ сеансу"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Введіть ключ сеансу для %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Комплект для автомобіля"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Немає імені"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Моє ім’я"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index fb9a2ad..fb2cde9 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Hủy"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Bật"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Chuyển tệp"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" muốn gửi cho bạn <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Chấp nhận tệp?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" muốn gửi cho bạn <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Chấp nhận tệp?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Từ chối"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Chấp nhận"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Đóng"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"OK"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Tệp không xác định"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Không có ứng dụng nào để xử lý loại tệp này. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Không có ứng dụng nào để xử lý loại tệp này. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Không có tệp"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Tệp không tồn tại! "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Tệp không tồn tại! \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Vui lòng đợi..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Đang bật Bluetooth…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Tệp sẽ được nhận. Hãy kiểm tra tiến trình trong bảng điều khiển Thông báo."</string>
diff --git a/res/values-vi/strings_map.xml b/res/values-vi/strings_map.xml
new file mode 100644
index 0000000..0f57ca3
--- /dev/null
+++ b/res/values-vi/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Nhập khóa phiên cho %1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Yêu cầu khóa phiên Bluetooth"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Đã hết thời gian chờ chấp nhập kết nối với %1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Đã hết thời gian chờ nhập khóa phiên với %1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Yêu cầu xác thực Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Khóa phiên"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Nhập khóa phiên cho %1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Bộ rảnh tay trên ô tô"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Tên không xác định"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Tên của tôi"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index b642fc3..5425f5c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"取消"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"打开"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"文件传输"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"“<xliff:g id="SENDER">%1$s</xliff:g>”想给您发送 <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>)。"\n\n"是否接受该文件?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"“<xliff:g id="SENDER">%1$s</xliff:g>”想给您发送 <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>)。\n\n是否接受该文件?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"拒绝"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"接受"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"确定"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"关闭"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"确定"</string>
     <string name="unknown_file" msgid="6092727753965095366">"未知文件"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"没有可处理此类文件的应用。"\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"没有可处理此类文件的应用。\n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"没有文件"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"该文件不存在。"\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"该文件不存在。\n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"请稍候..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"正在打开蓝牙..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"系统将要接收该文件。请在“通知”面板中检查进度。"</string>
diff --git a/res/values-zh-rCN/strings_map.xml b/res/values-zh-rCN/strings_map.xml
new file mode 100644
index 0000000..72ab0d0
--- /dev/null
+++ b/res/values-zh-rCN/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"输入“%1$s”的会话密钥"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"需要提供蓝牙会话密钥"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"接受与“%1$s”的连接时超时"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"输入“%1$s”的会话密钥时超时"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"OBEX 身份验证请求"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"会话密钥"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"输入“%1$s”的会话密钥"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"车用套件"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"未知名称"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"我的名字"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..46cff21
--- /dev/null
+++ b/res/values-zh-rHK/strings.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"存取下載管理員。"</string>
+    <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"允許應用程式存取 BluetoothShare 管理員並使用 BluetoothShare 管理員傳輸檔案。"</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"將藍牙裝置列入許可名單。"</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"允許應用程式暫時將藍牙裝置加入許可名單,使其不需經用戶確認便可把檔案傳送到裝置上。"</string>
+    <string name="permlab_handoverStatus" msgid="7316032998801933554">"接收藍牙交遞傳輸廣播。"</string>
+    <string name="permdesc_handoverStatus" msgid="4752738070064786310">"允許接收來自藍牙的交遞傳輸狀態資訊。"</string>
+    <string name="bt_share_picker_label" msgid="6268100924487046932">"藍牙"</string>
+    <string name="unknown_device" msgid="9221903979877041009">"不明裝置"</string>
+    <string name="unknownNumber" msgid="4994750948072751566">"未知"</string>
+    <string name="airplane_error_title" msgid="2683839635115739939">"飛行模式"</string>
+    <string name="airplane_error_msg" msgid="8698965595254137230">"裝置處於飛行模式時,無法使用藍牙功能。"</string>
+    <string name="bt_enable_title" msgid="8657832550503456572"></string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"如要使用藍牙服務,請先開啟藍牙功能。"</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"立即開啟藍牙功能?"</string>
+    <string name="bt_enable_cancel" msgid="1988832367505151727">"取消"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"開啟"</string>
+    <string name="incoming_file_confirm_title" msgid="8139874248612182627">"檔案傳輸"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"「<xliff:g id="SENDER">%1$s</xliff:g>」想將 <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) 傳送給您。\n\n您要接收檔案嗎?"</string>
+    <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"拒絕"</string>
+    <string name="incoming_file_confirm_ok" msgid="281462442932231475">"接受"</string>
+    <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"確定"</string>
+    <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"接收來自「<xliff:g id="SENDER">%1$s</xliff:g>」的檔案時發生作業逾時"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="2958227698135117210">"藍牙分享:外來檔案"</string>
+    <string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"您要接收這個檔案嗎?"</string>
+    <string name="incoming_file_toast_msg" msgid="1733710749992901811">"來自另一部裝置的檔案,請確認您要接收這個外來檔案。"</string>
+    <string name="notification_receiving" msgid="4674648179652543984">"藍牙分享:正在接收 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received" msgid="3324588019186687985">"藍牙分享:已接收 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_received_fail" msgid="3619350997285714746">"藍牙分享:未收到檔案 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sending" msgid="3035748958534983833">"藍牙分享:正在傳送 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent" msgid="9218710861333027778">"藍牙分享:已傳送 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="notification_sent_complete" msgid="302943281067557969">"傳送完成"</string>
+    <string name="notification_sent_fail" msgid="6696082233774569445">"藍牙分享:未傳送檔案 <xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_title" msgid="3353228219772092586">"檔案傳輸"</string>
+    <string name="download_line1" msgid="4926604799202134144">"寄件者:「<xliff:g id="SENDER">%1$s</xliff:g>」"</string>
+    <string name="download_line2" msgid="5876973543019417712">"檔案:<xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_line3" msgid="4384821622908676061">"檔案大小:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="download_line4" msgid="8535996869722666525"></string>
+    <string name="download_line5" msgid="3069560415845295386">"正在接收檔案…"</string>
+    <string name="download_cancel" msgid="9177305996747500768">"停止"</string>
+    <string name="download_ok" msgid="5000360731674466039">"隱藏"</string>
+    <string name="download_fail_line1" msgid="3846450148862894552">"未接收檔案"</string>
+    <string name="download_fail_line2" msgid="8950394574689971071">"檔案:<xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="download_fail_line3" msgid="3451040656154861722">"原因: <xliff:g id="REASON">%1$s</xliff:g>"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"確定"</string>
+    <string name="download_succ_line5" msgid="4509944688281573595">"已接收檔案"</string>
+    <string name="download_succ_ok" msgid="7053688246357050216">"開啟"</string>
+    <string name="upload_line1" msgid="2055952074059709052">"傳送給:「<xliff:g id="RECIPIENT">%1$s</xliff:g>」"</string>
+    <string name="upload_line3" msgid="4920689672457037437">"檔案類型:<xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+    <string name="upload_line5" msgid="7759322537674229752">"正在傳送檔案…"</string>
+    <string name="upload_succ_line5" msgid="5687317197463383601">"檔案已傳送"</string>
+    <string name="upload_succ_ok" msgid="7705428476405478828">"確定"</string>
+    <string name="upload_fail_line1" msgid="7899394672421491701">"未將檔案傳送給「<xliff:g id="RECIPIENT">%1$s</xliff:g>」。"</string>
+    <string name="upload_fail_line1_2" msgid="2108129204050841798">"檔案:<xliff:g id="FILE">%1$s</xliff:g>"</string>
+    <string name="upload_fail_ok" msgid="5807702461606714296">"重試"</string>
+    <string name="upload_fail_cancel" msgid="9118496285835687125">"關閉"</string>
+    <string name="bt_error_btn_ok" msgid="5965151173011534240">"確定"</string>
+    <string name="unknown_file" msgid="6092727753965095366">"未知的檔案"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"沒有應用程式可處理這種檔案類型。\n"</string>
+    <string name="not_exist_file" msgid="3489434189599716133">"沒有檔案"</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"檔案不存在。\n"</string>
+    <string name="enabling_progress_title" msgid="436157952334723406">"請稍候…"</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"正在開啟藍牙..."</string>
+    <string name="bt_toast_1" msgid="972182708034353383">"即將接收檔案,請在通知面板中查看進度。"</string>
+    <string name="bt_toast_2" msgid="8602553334099066582">"無法接收檔案。"</string>
+    <string name="bt_toast_3" msgid="6707884165086862518">"已停止接收來自「<xliff:g id="SENDER">%1$s</xliff:g>」的檔案"</string>
+    <string name="bt_toast_4" msgid="4678812947604395649">"正在將檔案傳送給「<xliff:g id="RECIPIENT">%1$s</xliff:g>」"</string>
+    <string name="bt_toast_5" msgid="2846870992823019494">"正在將 <xliff:g id="NUMBER">%1$s</xliff:g> 個檔案傳送給「<xliff:g id="RECIPIENT">%2$s</xliff:g>」"</string>
+    <string name="bt_toast_6" msgid="1855266596936622458">"已停止將檔案傳送給「<xliff:g id="RECIPIENT">%1$s</xliff:g>」"</string>
+    <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"USB 儲存裝置上空間不足,無法儲存「<xliff:g id="SENDER">%1$s</xliff:g>」傳來的檔案"</string>
+    <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"SD 記憶卡上空間不足,無法儲存「<xliff:g id="SENDER">%1$s</xliff:g>」傳來的檔案"</string>
+    <string name="bt_sm_2_2" msgid="2965243265852680543">"所需儲存空間:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
+    <string name="ErrorTooManyRequests" msgid="8578277541472944529">"同時處理過多要求,請稍後再試。"</string>
+    <string name="status_pending" msgid="2503691772030877944">"尚未開始傳輸檔案。"</string>
+    <string name="status_running" msgid="6562808920311008696">"正在進行檔案傳輸。"</string>
+    <string name="status_success" msgid="239573225847565868">"已完成檔案傳輸。"</string>
+    <string name="status_not_accept" msgid="1695082417193780738">"內容不受支援。"</string>
+    <string name="status_forbidden" msgid="613956401054050725">"目標裝置禁止傳輸。"</string>
+    <string name="status_canceled" msgid="6664490318773098285">"用戶已取消傳輸。"</string>
+    <string name="status_file_error" msgid="3671917770630165299">"儲存空間問題。"</string>
+    <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"沒有 USB 儲存裝置。"</string>
+    <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"沒有 SD 卡,請插入 SD 卡來儲存傳輸的檔案。"</string>
+    <string name="status_connection_error" msgid="947681831523219891">"連線失敗。"</string>
+    <string name="status_protocol_error" msgid="3245444473429269539">"無法正確處理要求。"</string>
+    <string name="status_unknown_error" msgid="8156660554237824912">"未知錯誤。"</string>
+    <string name="btopp_live_folder" msgid="7967791481444474554">"已透過藍牙接收"</string>
+    <string name="download_success" msgid="7036160438766730871">"已完成 <xliff:g id="FILE_SIZE">%1$s</xliff:g> 的接收作業。"</string>
+    <string name="upload_success" msgid="4014469387779648949">"已完成 <xliff:g id="FILE_SIZE">%1$s</xliff:g> 的傳送作業。"</string>
+    <string name="inbound_history_title" msgid="6940914942271327563">"外來傳輸"</string>
+    <string name="outbound_history_title" msgid="4279418703178140526">"向外傳輸"</string>
+    <string name="no_transfers" msgid="3482965619151865672">"傳輸記錄是空的。"</string>
+    <string name="transfer_clear_dlg_msg" msgid="1712376797268438075">"將會從清單清除所有項目。"</string>
+    <string name="outbound_noti_title" msgid="8051906709452260849">"藍牙分享:傳送的檔案"</string>
+    <string name="inbound_noti_title" msgid="4143352641953027595">"藍牙分享:接收的檔案"</string>
+    <string name="noti_caption" msgid="7508708288885707365">"<xliff:g id="SUCCESSFUL_NUMBER_0">%1$s</xliff:g> 個成功,<xliff:g id="UNSUCCESSFUL_NUMBER">%2$s</xliff:g> 個失敗。"</string>
+    <string name="transfer_menu_clear_all" msgid="790017462957873132">"清除清單"</string>
+    <string name="transfer_menu_open" msgid="3368984869083107200">"開啟"</string>
+    <string name="transfer_menu_clear" msgid="5854038118831427492">"從清單清除"</string>
+    <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"清除"</string>
+</resources>
diff --git a/res/values-zh-rHK/strings_map.xml b/res/values-zh-rHK/strings_map.xml
new file mode 100644
index 0000000..cfbe3f1
--- /dev/null
+++ b/res/values-zh-rHK/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"輸入 %1$s 的工作階段金鑰"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"必須有藍牙工作階段金鑰"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"接受與 %1$s 的連線時逾時"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"輸入與 %1$s 連線的工作階段金鑰時逾時"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex 認證要求"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"工作階段金鑰"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"輸入 %1$s 的工作階段金鑰"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"車用套件"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"未知的名稱"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"我的名稱"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-zh-rHK/strings_pbap.xml b/res/values-zh-rHK/strings_pbap.xml
new file mode 100644
index 0000000..d29dd85
--- /dev/null
+++ b/res/values-zh-rHK/strings_pbap.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"輸入 %1$s 的對稱金鑰"</string>
+    <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"必須有藍牙工作階段金鑰"</string>
+    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"接受與 %1$s 的連線時發生作業逾時"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s 輸入對稱金鑰時發生逾時"</string>
+    <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex 驗證要求"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"對稱金鑰"</string>
+    <string name="auth_notif_message" msgid="6667218116427605038">"輸入 %1$s 的對稱金鑰"</string>
+    <string name="defaultname" msgid="4821590500649090078">"車用套件"</string>
+    <string name="unknownName" msgid="2841414754740600042">"未知的名稱"</string>
+    <string name="localPhoneName" msgid="2349001318925409159">"我的姓名"</string>
+    <string name="defaultnumber" msgid="8520116145890867338">"000000"</string>
+</resources>
diff --git a/res/values-zh-rHK/test_strings.xml b/res/values-zh-rHK/test_strings.xml
new file mode 100644
index 0000000..a76b249
--- /dev/null
+++ b/res/values-zh-rHK/test_strings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="hello" msgid="1740533743008967039">"TestActivity,向全世界問好!"</string>
+    <string name="app_name" msgid="1203877025577761792">"藍牙分享"</string>
+    <string name="insert_record" msgid="1450997173838378132">"插入記錄"</string>
+    <string name="update_record" msgid="2480425402384910635">"確認記錄"</string>
+    <string name="ack_record" msgid="6716152390978472184">"Ack 記錄"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"刪除所有記錄"</string>
+    <string name="ok_button" msgid="6519033415223065454">"確定"</string>
+    <string name="delete_record" msgid="4645040331967533724">"刪除記錄"</string>
+    <string name="start_server" msgid="9034821924409165795">"啟動 TCP 伺服器"</string>
+    <string name="notify_server" msgid="4369106744022969655">"通知 TCP 伺服器"</string>
+</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 400d5a5..4e39aad 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"取消"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"開啟"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"檔案傳輸"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"「<xliff:g id="SENDER">%1$s</xliff:g>」想將 <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) 傳送給您。"\n\n"您要接收檔案嗎?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"「<xliff:g id="SENDER">%1$s</xliff:g>」想將 <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>) 傳送給您。\n\n您要接收檔案嗎?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"拒絕"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"接受"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"確定"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"關閉"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"確定"</string>
     <string name="unknown_file" msgid="6092727753965095366">"未知的檔案"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"沒有可處理這種檔案類型的應用程式。"\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"沒有可處理這種檔案類型的應用程式。\n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"沒有檔案"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"檔案不存在。"\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"檔案不存在。\n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"請稍候…"</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"正在開啟藍牙…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"即將接收檔案,請在通知面板中查看進度。"</string>
diff --git a/res/values-zh-rTW/strings_map.xml b/res/values-zh-rTW/strings_map.xml
new file mode 100644
index 0000000..96c2256
--- /dev/null
+++ b/res/values-zh-rTW/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"輸入 %1$s 的對稱金鑰"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"必須有藍牙對稱金鑰"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"接受與 %1$s 的連線時發生作業逾時"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"%1$s 輸入對稱金鑰時發生逾時"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Obex 驗證要求"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"對稱金鑰"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"輸入 %1$s 的對稱金鑰"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"車用套件"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"未知的名稱"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"我的名稱"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values-zh-rTW/test_strings.xml b/res/values-zh-rTW/test_strings.xml
index ecfdd4d..4b24156 100644
--- a/res/values-zh-rTW/test_strings.xml
+++ b/res/values-zh-rTW/test_strings.xml
@@ -6,7 +6,7 @@
     <string name="insert_record" msgid="1450997173838378132">"插入記錄"</string>
     <string name="update_record" msgid="2480425402384910635">"確認記錄"</string>
     <string name="ack_record" msgid="6716152390978472184">"Ack 記錄"</string>
-    <string name="deleteAll_record" msgid="4383349788485210582">"刪除所有記錄"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"刪除所有紀錄"</string>
     <string name="ok_button" msgid="6519033415223065454">"確定"</string>
     <string name="delete_record" msgid="4645040331967533724">"刪除記錄"</string>
     <string name="start_server" msgid="9034821924409165795">"啟動 TCP 伺服器"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 8e1e6ae..1435041 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -33,7 +33,7 @@
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Khansela"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Vula"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Ukudlulisa ifayela"</string>
-    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ufuna ukukuthumela <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). "\n\n" Yamukela ifayela?"</string>
+    <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ufuna ukukuthumela <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Yamukela ifayela?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Nqaba"</string>
     <string name="incoming_file_confirm_ok" msgid="281462442932231475">"Yamukela"</string>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Kulungile"</string>
@@ -73,9 +73,9 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"Vala"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"KULUNGILE"</string>
     <string name="unknown_file" msgid="6092727753965095366">"Ifayela engaziwa"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"Alukho uhlelo olulungiselelwe ukuthatha lolu hlobo lwefayela. "\n</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"Alukho uhlelo olulungiselelwe ukuthatha lolu hlobo lwefayela. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"Ayikho ifayela"</string>
-    <string name="not_exist_file_desc" msgid="4059531573790529229">"Ifayela ayikho. "\n</string>
+    <string name="not_exist_file_desc" msgid="4059531573790529229">"Ifayela ayikho. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Sicela ulinde..."</string>
     <string name="enabling_progress_content" msgid="4601542238119927904">"Ivula i-Bluetooth..."</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Ifayela izotholwa. Hlola intuthuki kwiphaneli Yezaziso."</string>
diff --git a/res/values-zu/strings_map.xml b/res/values-zu/strings_map.xml
new file mode 100644
index 0000000..203fab6
--- /dev/null
+++ b/res/values-zu/strings_map.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="map_session_key_dialog_title" msgid="4357431314165953502">"Thayipha ukhiye weseshini ye-%1$s"</string>
+    <string name="map_session_key_dialog_header" msgid="1858363785687455516">"Ukhiye weseshini ye-Bluetooth uyadingeka"</string>
+    <string name="map_acceptance_timeout_message" msgid="2247454902690565876">"Kube khona isikhathi sokuvala ekwamukeleni ukuxhumeka ne-%1$s"</string>
+    <string name="map_authentication_timeout_message" msgid="2151423397615327066">"Kube khona isikhathi sokuvala ekufakeni ukhiye wesikhathi nge-%1$s"</string>
+    <string name="map_auth_notif_ticker" msgid="8840174807927327119">"Isicelo sokufakazela ubuqiniso se-Obex"</string>
+    <string name="map_auth_notif_title" msgid="301767019364765129">"Ukhiye Weseshini"</string>
+    <string name="map_auth_notif_message" msgid="1510095655064214863">"Thayipha ukhiye wesikhathi we-%1$s"</string>
+    <string name="map_defaultname" msgid="3805234816465216759">"Ikhithi yemoto"</string>
+    <string name="map_unknownName" msgid="4985352365863687360">"Igama elingaziwa"</string>
+    <string name="map_localPhoneName" msgid="6264496105941797768">"Igama lami"</string>
+    <string name="map_defaultnumber" msgid="3838264444043503815">"000000"</string>
+</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index af90926..24eeb2c 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -23,4 +23,5 @@
     <bool name="profile_supported_gatt">true</bool>
     <bool name="pbap_include_photos_in_vcard">false</bool>
     <bool name="pbap_use_profile_for_owner_vcard">true</bool>
+    <bool name="profile_supported_map">true</bool>
 </resources>
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 2ff6487..3b449ac 100755
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -176,6 +176,19 @@
         return priority;
     }
 
+    /* Absolute volume implementation */
+    public boolean isAvrcpAbsoluteVolumeSupported() {
+        return mAvrcp.isAbsoluteVolumeSupported();
+    }
+
+    public void adjustAvrcpAbsoluteVolume(int direction) {
+        mAvrcp.adjustVolume(direction);
+    }
+
+    public void setAvrcpAbsoluteVolume(int volume) {
+        mAvrcp.setAbsoluteVolume(volume);
+    }
+
     synchronized boolean isA2dpPlaying(BluetoothDevice device) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM,
                                        "Need BLUETOOTH permission");
@@ -251,6 +264,24 @@
             return service.getPriority(device);
         }
 
+        public boolean isAvrcpAbsoluteVolumeSupported() {
+            A2dpService service = getService();
+            if (service == null) return false;
+            return service.isAvrcpAbsoluteVolumeSupported();
+        }
+
+        public void adjustAvrcpAbsoluteVolume(int direction) {
+            A2dpService service = getService();
+            if (service == null) return;
+            service.adjustAvrcpAbsoluteVolume(direction);
+        }
+
+        public void setAvrcpAbsoluteVolume(int volume) {
+            A2dpService service = getService();
+            if (service == null) return;
+            service.setAvrcpAbsoluteVolume(volume);
+        }
+
         public boolean isA2dpPlaying(BluetoothDevice device) {
             A2dpService service = getService();
             if (service == null) return false;
diff --git a/src/com/android/bluetooth/a2dp/Avrcp.java b/src/com/android/bluetooth/a2dp/Avrcp.java
index ac7a323..16fc327 100755
--- a/src/com/android/bluetooth/a2dp/Avrcp.java
+++ b/src/com/android/bluetooth/a2dp/Avrcp.java
@@ -16,6 +16,9 @@
 
 package com.android.bluetooth.a2dp;
 
+import java.util.Timer;
+import java.util.TimerTask;
+
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
@@ -52,7 +55,7 @@
  * support metadata, play status and event notification
  */
 final class Avrcp {
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
     private static final String TAG = "Avrcp";
 
     private Context mContext;
@@ -73,17 +76,65 @@
     private int mPlayPosChangedNT;
     private long mNextPosMs;
     private long mPrevPosMs;
+    private long mSkipStartTime;
+    private int mFeatures;
+    private int mAbsoluteVolume;
+    private int mLastSetVolume;
+    private int mLastDirection;
+    private final int mVolumeStep;
+    private final int mAudioStreamMax;
+    private boolean mVolCmdInProgress;
+    private int mAbsVolRetryTimes;
+    private int mSkipAmount;
 
-    private static final int MESSAGE_GET_PLAY_STATUS = 1;
-    private static final int MESSAGE_GET_ELEM_ATTRS = 2;
-    private static final int MESSAGE_REGISTER_NOTIFICATION = 3;
-    private static final int MESSAGE_PLAY_INTERVAL_TIMEOUT = 4;
+    /* AVRC IDs from avrc_defs.h */
+    private static final int AVRC_ID_REWIND = 0x48;
+    private static final int AVRC_ID_FAST_FOR = 0x49;
+
+    /* BTRC features */
+    public static final int BTRC_FEAT_METADATA = 0x01;
+    public static final int BTRC_FEAT_ABSOLUTE_VOLUME = 0x02;
+    public static final int BTRC_FEAT_BROWSE = 0x04;
+
+    /* AVRC response codes, from avrc_defs */
+    private static final int AVRC_RSP_NOT_IMPL = 8;
+    private static final int AVRC_RSP_ACCEPT = 9;
+    private static final int AVRC_RSP_REJ = 10;
+    private static final int AVRC_RSP_IN_TRANS = 11;
+    private static final int AVRC_RSP_IMPL_STBL = 12;
+    private static final int AVRC_RSP_CHANGED = 13;
+    private static final int AVRC_RSP_INTERIM = 15;
+
+    private static final int MESSAGE_GET_RC_FEATURES = 1;
+    private static final int MESSAGE_GET_PLAY_STATUS = 2;
+    private static final int MESSAGE_GET_ELEM_ATTRS = 3;
+    private static final int MESSAGE_REGISTER_NOTIFICATION = 4;
+    private static final int MESSAGE_PLAY_INTERVAL_TIMEOUT = 5;
+    private static final int MESSAGE_VOLUME_CHANGED = 6;
+    private static final int MESSAGE_ADJUST_VOLUME = 7;
+    private static final int MESSAGE_SET_ABSOLUTE_VOLUME = 8;
+    private static final int MESSAGE_ABS_VOL_TIMEOUT = 9;
+    private static final int MESSAGE_FAST_FORWARD = 10;
+    private static final int MESSAGE_REWIND = 11;
+    private static final int MESSAGE_CHANGE_PLAY_POS = 12;
     private static final int MSG_UPDATE_STATE = 100;
     private static final int MSG_SET_METADATA = 101;
     private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
     private static final int MSG_SET_ARTWORK = 103;
     private static final int MSG_SET_GENERATION_ID = 104;
 
+    private static final int BUTTON_TIMEOUT_TIME = 2000;
+    private static final int BASE_SKIP_AMOUNT = 2000;
+    private static final int KEY_STATE_PRESS = 1;
+    private static final int KEY_STATE_RELEASE = 0;
+    private static final int SKIP_PERIOD = 400;
+    private static final int SKIP_DOUBLE_INTERVAL = 3000;
+    private static final long MAX_MULTIPLIER_VALUE = 128L;
+    private static final int CMD_TIMEOUT_DELAY = 2000;
+    private static final int MAX_ERROR_RETRY_TIMES = 3;
+    private static final int AVRCP_MAX_VOL = 127;
+    private static final int AVRCP_BASE_VOLUME_STEP = 1;
+
     static {
         classInitNative();
     }
@@ -99,12 +150,20 @@
         mSongLengthMs = 0L;
         mPlaybackIntervalMs = 0L;
         mPlayPosChangedNT = NOTIFICATION_TYPE_CHANGED;
+        mFeatures = 0;
+        mAbsoluteVolume = -1;
+        mLastSetVolume = -1;
+        mLastDirection = 0;
+        mVolCmdInProgress = false;
+        mAbsVolRetryTimes = 0;
 
         mContext = context;
 
         initNative();
 
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+        mAudioStreamMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        mVolumeStep = Math.max(AVRCP_BASE_VOLUME_STEP, AVRCP_MAX_VOL/mAudioStreamMax);
     }
 
     private void start() {
@@ -193,6 +252,11 @@
                     clientGeneration, (clearing ? 1 : 0), mediaIntent).sendToTarget();
             }
         }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            // no-op: this RemoteControlDisplay is not subject to being disabled.
+        }
     }
 
     /** Handles Avrcp messages. */
@@ -228,6 +292,14 @@
                 mClientGeneration = msg.arg1;
                 break;
 
+            case MESSAGE_GET_RC_FEATURES:
+                String address = (String) msg.obj;
+                if (DEBUG) Log.v(TAG, "MESSAGE_GET_RC_FEATURES: address="+address+
+                                                             ", features="+msg.arg1);
+                mFeatures = msg.arg1;
+                mAudioManager.avrcpSupportsAbsoluteVolume(address, isAbsoluteVolumeSupported());
+                break;
+
             case MESSAGE_GET_PLAY_STATUS:
                 if (DEBUG) Log.v(TAG, "MESSAGE_GET_PLAY_STATUS");
                 getPlayStatusRspNative(convertPlayStateToPlayStatus(mCurrentPlayState),
@@ -262,6 +334,119 @@
                 registerNotificationRspPlayPosNative(mPlayPosChangedNT, (int)getPlayPosition());
                 break;
 
+            case MESSAGE_VOLUME_CHANGED:
+                if (DEBUG) Log.v(TAG, "MESSAGE_VOLUME_CHANGED: volume=" + msg.arg1 +
+                                                              " ctype=" + msg.arg2);
+
+                if (msg.arg2 == AVRC_RSP_ACCEPT || msg.arg2 == AVRC_RSP_REJ) {
+                    if (mVolCmdInProgress == false) {
+                        Log.e(TAG, "Unsolicited response, ignored");
+                        break;
+                    }
+                    removeMessages(MESSAGE_ABS_VOL_TIMEOUT);
+                    mVolCmdInProgress = false;
+                    mAbsVolRetryTimes = 0;
+                }
+                if (mAbsoluteVolume != msg.arg1 && (msg.arg2 == AVRC_RSP_ACCEPT ||
+                                                    msg.arg2 == AVRC_RSP_CHANGED ||
+                                                    msg.arg2 == AVRC_RSP_INTERIM)) {
+                    notifyVolumeChanged(msg.arg1);
+                    mAbsoluteVolume = msg.arg1;
+                } else if (msg.arg2 == AVRC_RSP_REJ) {
+                    Log.e(TAG, "setAbsoluteVolume call rejected");
+                }
+                break;
+
+            case MESSAGE_ADJUST_VOLUME:
+                if (DEBUG) Log.d(TAG, "MESSAGE_ADJUST_VOLUME: direction=" + msg.arg1);
+                if (mVolCmdInProgress) {
+                    if (DEBUG) Log.w(TAG, "There is already a volume command in progress.");
+                    break;
+                }
+                // Wait on verification on volume from device, before changing the volume.
+                if (mAbsoluteVolume != -1 && (msg.arg1 == -1 || msg.arg1 == 1)) {
+                    int setVol = Math.min(AVRCP_MAX_VOL,
+                                 Math.max(0, mAbsoluteVolume + msg.arg1*mVolumeStep));
+                    if (setVolumeNative(setVol)) {
+                        sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT),
+                                           CMD_TIMEOUT_DELAY);
+                        mVolCmdInProgress = true;
+                        mLastDirection = msg.arg1;
+                        mLastSetVolume = setVol;
+                    }
+                } else {
+                    Log.e(TAG, "Unknown direction in MESSAGE_ADJUST_VOLUME");
+                }
+                break;
+
+            case MESSAGE_SET_ABSOLUTE_VOLUME:
+                if (DEBUG) Log.v(TAG, "MESSAGE_SET_ABSOLUTE_VOLUME");
+                if (mVolCmdInProgress) {
+                    if (DEBUG) Log.w(TAG, "There is already a volume command in progress.");
+                    break;
+                }
+                if (setVolumeNative(msg.arg1)) {
+                    sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT), CMD_TIMEOUT_DELAY);
+                    mVolCmdInProgress = true;
+                    mLastSetVolume = msg.arg1;
+                }
+                break;
+
+            case MESSAGE_ABS_VOL_TIMEOUT:
+                if (DEBUG) Log.v(TAG, "MESSAGE_ABS_VOL_TIMEOUT: Volume change cmd timed out.");
+                mVolCmdInProgress = false;
+                if (mAbsVolRetryTimes >= MAX_ERROR_RETRY_TIMES) {
+                    mAbsVolRetryTimes = 0;
+                } else {
+                    mAbsVolRetryTimes += 1;
+                    if (setVolumeNative(mLastSetVolume)) {
+                        sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT),
+                                           CMD_TIMEOUT_DELAY);
+                        mVolCmdInProgress = true;
+                    }
+                }
+                break;
+
+            case MESSAGE_FAST_FORWARD:
+            case MESSAGE_REWIND:
+                int skipAmount;
+                if (msg.what == MESSAGE_FAST_FORWARD) {
+                    if (DEBUG) Log.v(TAG, "MESSAGE_FAST_FORWARD");
+                    skipAmount = BASE_SKIP_AMOUNT;
+                } else {
+                    if (DEBUG) Log.v(TAG, "MESSAGE_REWIND");
+                    skipAmount = -BASE_SKIP_AMOUNT;
+                }
+
+                if (hasMessages(MESSAGE_CHANGE_PLAY_POS) &&
+                        (skipAmount != mSkipAmount)) {
+                    Log.w(TAG, "missing release button event:" + mSkipAmount);
+                }
+
+                if ((!hasMessages(MESSAGE_CHANGE_PLAY_POS)) ||
+                        (skipAmount != mSkipAmount)) {
+                    mSkipStartTime = SystemClock.elapsedRealtime();
+                }
+
+                removeMessages(MESSAGE_CHANGE_PLAY_POS);
+                if (msg.arg1 == KEY_STATE_PRESS) {
+                    mSkipAmount = skipAmount;
+                    changePositionBy(mSkipAmount * getSkipMultiplier());
+                    Message posMsg = obtainMessage(MESSAGE_CHANGE_PLAY_POS);
+                    posMsg.arg1 = 1;
+                    sendMessageDelayed(posMsg, SKIP_PERIOD);
+                }
+                break;
+
+            case MESSAGE_CHANGE_PLAY_POS:
+                if (DEBUG) Log.v(TAG, "MESSAGE_CHANGE_PLAY_POS:" + msg.arg1);
+                changePositionBy(mSkipAmount * getSkipMultiplier());
+                if (msg.arg1 * SKIP_PERIOD < BUTTON_TIMEOUT_TIME) {
+                    Message posMsg = obtainMessage(MESSAGE_CHANGE_PLAY_POS);
+                    posMsg.arg1 = msg.arg1 + 1;
+                    sendMessageDelayed(posMsg, SKIP_PERIOD);
+                }
+                break;
             }
         }
     }
@@ -371,6 +556,12 @@
         if (DEBUG) Log.v(TAG, "duration=" + mSongLengthMs);
     }
 
+    private void getRcFeatures(byte[] address, int features) {
+        Message msg = mHandler.obtainMessage(MESSAGE_GET_RC_FEATURES, features, 0,
+                                             Utils.getAddressStringFromByte(address));
+        mHandler.sendMessage(msg);
+    }
+
     private void getPlayStatus() {
         Message msg = mHandler.obtainMessage(MESSAGE_GET_PLAY_STATUS);
         mHandler.sendMessage(msg);
@@ -422,6 +613,41 @@
         }
     }
 
+    private void handlePassthroughCmd(int id, int keyState) {
+        switch (id) {
+            case AVRC_ID_REWIND:
+                rewind(keyState);
+                break;
+            case AVRC_ID_FAST_FOR:
+                fastForward(keyState);
+                break;
+        }
+    }
+
+    private void fastForward(int keyState) {
+        Message msg = mHandler.obtainMessage(MESSAGE_FAST_FORWARD, keyState, 0);
+        mHandler.sendMessage(msg);
+    }
+
+    private void rewind(int keyState) {
+        Message msg = mHandler.obtainMessage(MESSAGE_REWIND, keyState, 0);
+        mHandler.sendMessage(msg);
+    }
+
+    private void changePositionBy(long amount) {
+        long currentPosMs = getPlayPosition();
+        if (currentPosMs == -1L) return;
+        long newPosMs = Math.max(0L, currentPosMs + amount);
+        mAudioManager.setRemoteControlClientPlaybackPosition(mClientGeneration,
+                newPosMs);
+    }
+
+    private int getSkipMultiplier() {
+        long currentTime = SystemClock.elapsedRealtime();
+        long multi = (long) Math.pow(2, (currentTime - mSkipStartTime)/SKIP_DOUBLE_INTERVAL);
+        return (int) Math.min(MAX_MULTIPLIER_VALUE, multi);
+    }
+
     private void sendTrackChangedRsp() {
         byte[] track = new byte[TRACK_ID_SIZE];
         /* track is stored in big endian format */
@@ -509,6 +735,59 @@
         return playStatus;
     }
 
+    /**
+     * This is called from AudioService. It will return whether this device supports abs volume.
+     * NOT USED AT THE MOMENT.
+     */
+    public boolean isAbsoluteVolumeSupported() {
+        return ((mFeatures & BTRC_FEAT_ABSOLUTE_VOLUME) != 0);
+    }
+
+    /**
+     * We get this call from AudioService. This will send a message to our handler object,
+     * requesting our handler to call setVolumeNative()
+     */
+    public void adjustVolume(int direction) {
+        Message msg = mHandler.obtainMessage(MESSAGE_ADJUST_VOLUME, direction, 0);
+        mHandler.sendMessage(msg);
+    }
+
+    public void setAbsoluteVolume(int volume) {
+        int avrcpVolume = convertToAvrcpVolume(volume);
+        avrcpVolume = Math.min(AVRCP_MAX_VOL, Math.max(0, avrcpVolume));
+        mHandler.removeMessages(MESSAGE_ADJUST_VOLUME);
+        Message msg = mHandler.obtainMessage(MESSAGE_SET_ABSOLUTE_VOLUME, avrcpVolume, 0);
+        mHandler.sendMessage(msg);
+
+    }
+
+    /* Called in the native layer as a btrc_callback to return the volume set on the carkit in the
+     * case when the volume is change locally on the carkit. This notification is not called when
+     * the volume is changed from the phone.
+     *
+     * This method will send a message to our handler to change the local stored volume and notify
+     * AudioService to update the UI
+     */
+    private void volumeChangeCallback(int volume, int ctype) {
+        Message msg = mHandler.obtainMessage(MESSAGE_VOLUME_CHANGED, volume, ctype);
+        mHandler.sendMessage(msg);
+    }
+
+    private void notifyVolumeChanged(int volume) {
+        volume = convertToAudioStreamVolume(volume);
+        mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume,
+                      AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
+    }
+
+    private int convertToAudioStreamVolume(int volume) {
+        // Rescale volume to match AudioSystem's volume
+        return (int) Math.ceil((double) volume*mAudioStreamMax/AVRCP_MAX_VOL);
+    }
+
+    private int convertToAvrcpVolume(int volume) {
+        return (int) Math.ceil((double) volume*AVRCP_MAX_VOL/mAudioStreamMax);
+    }
+
     // Do not modify without updating the HAL bt_rc.h files.
 
     // match up with btrc_play_status_t enum of bt_rc.h
@@ -553,4 +832,5 @@
     private native boolean registerNotificationRspPlayStatusNative(int type, int playStatus);
     private native boolean registerNotificationRspTrackChangeNative(int type, byte[] track);
     private native boolean registerNotificationRspPlayPosNative(int type, int playPos);
+    private native boolean setVolumeNative(int volume);
 }
diff --git a/src/com/android/bluetooth/btservice/AdapterProperties.java b/src/com/android/bluetooth/btservice/AdapterProperties.java
index b05becd..af8e416 100755
--- a/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -203,10 +203,9 @@
      * @return the mState
      */
     int getState() {
-        synchronized (mObject) {
-            if (VDBG) debugLog("State = " + mState);
-            return mState;
-        }
+        /* remove the lock to work around a platform deadlock problem */
+        /* and also for read access, it is safe to remove the lock to save CPU power */
+        return mState;
     }
 
     /**
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index f96d1f7..6c7576a 100755
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -74,8 +74,10 @@
     //For Debugging only
     private static int sRefCount=0;
 
-    public static final String ACTION_LOAD_ADAPTER_PROPERTIES="com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
-    public static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED";
+    public static final String ACTION_LOAD_ADAPTER_PROPERTIES =
+        "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
+    public static final String ACTION_SERVICE_STATE_CHANGED =
+        "com.android.bluetooth.btservice.action.STATE_CHANGED";
     public static final String EXTRA_ACTION="action";
     public static final int PROFILE_CONN_CONNECTED  = 1;
     public static final int PROFILE_CONN_REJECTED  = 2;
@@ -872,6 +874,18 @@
             return service.createSocketChannel(type, serviceName, uuid, port, flag);
         }
 
+        public boolean configHciSnoopLog(boolean enable) {
+            if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
+                (!Utils.checkCaller())) {
+                Log.w(TAG,"configHciSnoopLog(): not allowed for non-active user");
+                return false;
+            }
+
+            AdapterService service = getService();
+            if (service == null) return false;
+            return service.configHciSnoopLog(enable);
+        }
+
         public void registerCallback(IBluetoothCallback cb) {
             AdapterService service = getService();
             if (service == null) return ;
@@ -915,7 +929,7 @@
 
      public synchronized boolean enable(boolean quietMode) {
          enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                 "Need BLUETOOTH ADMIN permission");
+                                        "Need BLUETOOTH ADMIN permission");
          if (DBG)debugLog("Enable called with quiet mode status =  " + mQuietmode);
          mQuietmode  = quietMode;
          Message m =
@@ -926,7 +940,7 @@
 
      boolean disable() {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
+                                       "Need BLUETOOTH ADMIN permission");
 
         if (DBG) debugLog("disable() called...");
         Message m =
@@ -951,7 +965,7 @@
 
      String getName() {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM,
-                "Need BLUETOOTH permission");
+                                       "Need BLUETOOTH permission");
 
         try {
             return mAdapterProperties.getName();
@@ -963,7 +977,7 @@
 
      boolean setName(String name) {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
+                                       "Need BLUETOOTH ADMIN permission");
 
         return mAdapterProperties.setName(name);
     }
@@ -997,14 +1011,14 @@
 
      boolean startDiscovery() {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
+                                       "Need BLUETOOTH ADMIN permission");
 
         return startDiscoveryNative();
     }
 
      boolean cancelDiscovery() {
         enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
-                "Need BLUETOOTH ADMIN permission");
+                                       "Need BLUETOOTH ADMIN permission");
 
         return cancelDiscoveryNative();
     }
@@ -1041,6 +1055,10 @@
             return false;
         }
 
+        // Pairing is unreliable while scanning, so cancel discovery
+        // Note, remove this when native stack improves
+        cancelDiscoveryNative();
+
         Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
         msg.obj = device;
         mBondStateMachine.sendMessage(msg);
@@ -1254,7 +1272,8 @@
     }
 
      boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) {
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                       "Need BLUETOOTH ADMIN permission");
         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
         if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
             return false;
@@ -1277,7 +1296,8 @@
     }
 
      boolean setPairingConfirmation(BluetoothDevice device, boolean accept) {
-        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
+                                       "Need BLUETOOTH ADMIN permission");
         DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
         if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) {
             return false;
@@ -1322,6 +1342,11 @@
         return ParcelFileDescriptor.adoptFd(fd);
     }
 
+    boolean configHciSnoopLog(boolean enable) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        return configHciSnoopLogNative(enable);
+    }
+
      void registerCallback(IBluetoothCallback cb) {
          mCallbacks.register(cb);
       }
@@ -1396,6 +1421,8 @@
     private native int createSocketChannelNative(int type, String serviceName,
                                                  byte[] uuid, int port, int flag);
 
+    /*package*/ native boolean configHciSnoopLogNative(boolean enable);
+
     protected void finalize() {
         cleanup();
         if (TRACE_REF) {
diff --git a/src/com/android/bluetooth/btservice/Config.java b/src/com/android/bluetooth/btservice/Config.java
index a2b2ff3..99cc411 100644
--- a/src/com/android/bluetooth/btservice/Config.java
+++ b/src/com/android/bluetooth/btservice/Config.java
@@ -29,6 +29,7 @@
 import com.android.bluetooth.hid.HidService;
 import com.android.bluetooth.pan.PanService;
 import com.android.bluetooth.gatt.GattService;
+import com.android.bluetooth.map.BluetoothMapService;
 
 public class Config {
     private static final String TAG = "AdapterServiceConfig";
@@ -44,7 +45,8 @@
         HidService.class,
         HealthService.class,
         PanService.class,
-        GattService.class
+        GattService.class,
+        BluetoothMapService.class
     };
     /**
      * Resource flag to indicate whether profile is supported or not.
@@ -55,7 +57,8 @@
         R.bool.profile_supported_hid,
         R.bool.profile_supported_hdp,
         R.bool.profile_supported_pan,
-        R.bool.profile_supported_gatt
+        R.bool.profile_supported_gatt,
+        R.bool.profile_supported_map
     };
 
     private static Class[] SUPPORTED_PROFILES = new Class[0];
diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java
index a60f977..f054df6 100755
--- a/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -228,7 +228,7 @@
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, pin);
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                     BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN);
-        mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
+        mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
     }
 
     void devicePropertyChangedCallback(byte[] address, int[] types, byte[][] values) {
@@ -354,7 +354,7 @@
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, getDevice(address));
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                 BluetoothDevice.PAIRING_VARIANT_PIN);
-        mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
+        mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
         return;
     }
 
@@ -379,7 +379,7 @@
             variant = BluetoothDevice.PAIRING_VARIANT_PASSKEY;
         } else if (pairingVariant == AbstractionLayer.BT_SSP_VARIANT_PASSKEY_NOTIFICATION) {
             variant = BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY;
-	    displayPasskey = true;
+            displayPasskey = true;
         } else {
             errorLog("SSP Pairing variant not present");
             return;
@@ -396,7 +396,7 @@
             intent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, passkey);
         }
         intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, variant);
-        mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
+        mAdapterService.sendOrderedBroadcast(intent, mAdapterService.BLUETOOTH_ADMIN_PERM);
     }
 
     void aclStateChangeCallback(int status, byte[] address, int newState) {
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 2c967a5..1ab6d87 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -196,6 +196,7 @@
 
         public void binderDied() {
             if (DBG) Log.d(TAG, "Binder is dead - unregistering client (" + mAppIf + ")!");
+            stopScan(mAppIf, false);
             unregisterClient(mAppIf);
         }
     }
@@ -286,6 +287,12 @@
             service.clientDisconnect(clientIf, address);
         }
 
+        public void clientListen(int clientIf, boolean start) {
+            GattService service = getService();
+            if (service == null) return;
+            service.clientListen(clientIf, start);
+        }
+
         public void refreshDevice(int clientIf, String address) {
             GattService service = getService();
             if (service == null) return;
@@ -324,26 +331,29 @@
         public void readDescriptor(int clientIf, String address, int srvcType,
                             int srvcInstanceId, ParcelUuid srvcId,
                             int charInstanceId, ParcelUuid charId,
-                            ParcelUuid descrId, int authReq) {
+                            int descrInstanceId, ParcelUuid descrId,
+                            int authReq) {
             GattService service = getService();
             if (service == null) return;
-            service.readDescriptor(clientIf, address, srvcType, srvcInstanceId,
-                                       srvcId.getUuid(), charInstanceId,
-                                       charId.getUuid(), descrId.getUuid(),
-                                       authReq);
+            service.readDescriptor(clientIf, address, srvcType,
+                                   srvcInstanceId, srvcId.getUuid(),
+                                   charInstanceId, charId.getUuid(),
+                                   descrInstanceId, descrId.getUuid(),
+                                   authReq);
         }
 
         public void writeDescriptor(int clientIf, String address, int srvcType,
                             int srvcInstanceId, ParcelUuid srvcId,
                             int charInstanceId, ParcelUuid charId,
-                            ParcelUuid descrId, int writeType,
-                            int authReq, byte[] value) {
+                            int descrInstanceId, ParcelUuid descrId,
+                            int writeType, int authReq, byte[] value) {
             GattService service = getService();
             if (service == null) return;
-            service.writeDescriptor(clientIf, address, srvcType, srvcInstanceId,
-                                       srvcId.getUuid(), charInstanceId,
-                                       charId.getUuid(), descrId.getUuid(),
-                                       writeType, authReq, value);
+            service.writeDescriptor(clientIf, address, srvcType,
+                                    srvcInstanceId, srvcId.getUuid(),
+                                    charInstanceId, charId.getUuid(),
+                                    descrInstanceId, descrId.getUuid(),
+                                    writeType, authReq, value);
         }
 
         public void beginReliableWrite(int clientIf, String address) {
@@ -468,6 +478,14 @@
                 srvcId.getUuid(), charInstanceId, charId.getUuid(), confirm, value);
         }
 
+        public void setAdvData(int serverIf, boolean setScanRsp, boolean inclName,
+                                boolean inclTxPower, int minInterval, int maxInterval,
+                                int appearance, byte[] manufacturerData) {
+            GattService service = getService();
+            if (service == null) return;
+            service.setAdvData(serverIf, setScanRsp, inclName, inclTxPower,
+                minInterval, maxInterval, appearance, manufacturerData);
+        }
     };
 
     /**************************************************************************
@@ -619,7 +637,7 @@
     void onGetDescriptor(int connId, int status, int srvcType,
             int srvcInstId, long srvcUuidLsb, long srvcUuidMsb,
             int charInstId, long charUuidLsb, long charUuidMsb,
-            long descrUuidLsb, long descrUuidMsb) throws RemoteException {
+            int descrInstId, long descrUuidLsb, long descrUuidMsb) throws RemoteException {
 
         UUID srvcUuid = new UUID(srvcUuidMsb, srvcUuidLsb);
         UUID charUuid = new UUID(charUuidMsb, charUuidLsb);
@@ -635,14 +653,14 @@
                 app.callback.onGetDescriptor(address, srvcType,
                             srvcInstId, new ParcelUuid(srvcUuid),
                             charInstId, new ParcelUuid(charUuid),
-                            new ParcelUuid(descUuid));
+                            descrInstId, new ParcelUuid(descUuid));
             }
 
             // Get next descriptor for the current characteristic
             gattClientGetDescriptorNative(connId, srvcType,
                                     srvcInstId, srvcUuidLsb, srvcUuidMsb,
                                     charInstId, charUuidLsb, charUuidMsb,
-                                    descrUuidLsb, descrUuidMsb);
+                                    descrInstId, descrUuidLsb, descrUuidMsb);
         } else {
             // Explore the next service
             continueSearch(connId, 0);
@@ -764,7 +782,7 @@
     void onReadDescriptor(int connId, int status, int srvcType,
             int srvcInstId, long srvcUuidLsb, long srvcUuidMsb,
             int charInstId, long charUuidLsb, long charUuidMsb,
-            long descrUuidLsb, long descrUuidMsb,
+            int descrInstId, long descrUuidLsb, long descrUuidMsb,
             int charType, byte[] data) throws RemoteException {
 
         UUID srvcUuid = new UUID(srvcUuidMsb, srvcUuidLsb);
@@ -780,14 +798,14 @@
             app.callback.onDescriptorRead(address, status, srvcType,
                         srvcInstId, new ParcelUuid(srvcUuid),
                         charInstId, new ParcelUuid(charUuid),
-                        new ParcelUuid(descrUuid), data);
+                        descrInstId, new ParcelUuid(descrUuid), data);
         }
     }
 
     void onWriteDescriptor(int connId, int status, int srvcType,
             int srvcInstId, long srvcUuidLsb, long srvcUuidMsb,
             int charInstId, long charUuidLsb, long charUuidMsb,
-            long descrUuidLsb, long descrUuidMsb) throws RemoteException {
+            int descrInstId, long descrUuidLsb, long descrUuidMsb) throws RemoteException {
 
         UUID srvcUuid = new UUID(srvcUuidMsb, srvcUuidLsb);
         UUID charUuid = new UUID(charUuidMsb, charUuidLsb);
@@ -802,7 +820,7 @@
             app.callback.onDescriptorWrite(address, status, srvcType,
                         srvcInstId, new ParcelUuid(srvcUuid),
                         charInstId, new ParcelUuid(charUuid),
-                        new ParcelUuid(descrUuid));
+                        descrInstId, new ParcelUuid(descrUuid));
         }
     }
 
@@ -817,6 +835,16 @@
         }
     }
 
+    void onClientListen(int status, int clientIf)
+            throws RemoteException {
+        if (DBG) Log.d(TAG, "onClientListen() status=" + status);
+
+        ClientMap.App app = mClientMap.getById(clientIf);
+        if (app == null) return;
+
+        app.callback.onListen(status);
+    }
+
     /**************************************************************************
      * GATT Service functions - Shared CLIENT/SERVER
      *************************************************************************/
@@ -921,7 +949,6 @@
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         if (DBG) Log.d(TAG, "unregisterClient() - clientIf=" + clientIf);
-        removeScanClient(clientIf, false);
         mClientMap.remove(clientIf);
         gattClientUnregisterAppNative(clientIf);
     }
@@ -942,6 +969,11 @@
         gattClientDisconnectNative(clientIf, address, connId != null ? connId : 0);
     }
 
+    void clientListen(int clientIf, boolean start) {
+        if (DBG) Log.d(TAG, "clientListen() - start=" + start);
+        gattClientListenNative(clientIf, start);
+    }
+
     List<String> getConnectedDevices() {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
@@ -1013,7 +1045,8 @@
     void readDescriptor(int clientIf, String address, int srvcType,
                             int srvcInstanceId, UUID srvcUuid,
                             int charInstanceId, UUID charUuid,
-                            UUID descrUuid, int authReq) {
+                            int descrInstanceId, UUID descrUuid,
+                            int authReq) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         if (DBG) Log.d(TAG, "readDescriptor() - address=" + address);
@@ -1021,9 +1054,11 @@
         Integer connId = mClientMap.connIdByAddress(clientIf, address);
         if (connId != null)
             gattClientReadDescriptorNative(connId, srvcType,
-                srvcInstanceId, srvcUuid.getLeastSignificantBits(),
-                srvcUuid.getMostSignificantBits(), charInstanceId,
+                srvcInstanceId,
+                srvcUuid.getLeastSignificantBits(), srvcUuid.getMostSignificantBits(),
+                charInstanceId,
                 charUuid.getLeastSignificantBits(), charUuid.getMostSignificantBits(),
+                descrInstanceId,
                 descrUuid.getLeastSignificantBits(), descrUuid.getMostSignificantBits(),
                 authReq);
         else
@@ -1033,8 +1068,8 @@
     void writeDescriptor(int clientIf, String address, int srvcType,
                             int srvcInstanceId, UUID srvcUuid,
                             int charInstanceId, UUID charUuid,
-                            UUID descrUuid, int writeType,
-                            int authReq, byte[] value) {
+                            int descrInstanceId, UUID descrUuid,
+                            int writeType, int authReq, byte[] value) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         if (DBG) Log.d(TAG, "writeDescriptor() - address=" + address);
@@ -1042,9 +1077,11 @@
         Integer connId = mClientMap.connIdByAddress(clientIf, address);
         if (connId != null)
             gattClientWriteDescriptorNative(connId, srvcType,
-                srvcInstanceId, srvcUuid.getLeastSignificantBits(),
-                srvcUuid.getMostSignificantBits(), charInstanceId,
+                srvcInstanceId,
+                srvcUuid.getLeastSignificantBits(), srvcUuid.getMostSignificantBits(),
+                charInstanceId,
                 charUuid.getLeastSignificantBits(), charUuid.getMostSignificantBits(),
+                descrInstanceId,
                 descrUuid.getLeastSignificantBits(), descrUuid.getMostSignificantBits(),
                 writeType, authReq, value);
         else
@@ -1096,6 +1133,15 @@
         gattClientReadRemoteRssiNative(clientIf, address);
     }
 
+    void setAdvData(int serverIf, boolean setScanRsp, boolean inclName,
+                boolean inclTxPower, int minInterval, int maxInterval,
+                int appearance, byte[] manufacturerData) {
+        if (DBG) Log.d(TAG, "setAdvData() - setScanRsp=" + setScanRsp);
+        if (minInterval == 0) maxInterval = 0;
+        gattSetAdvDataNative(serverIf, setScanRsp, inclName, inclTxPower,
+            minInterval, maxInterval, appearance, manufacturerData);
+    }
+
     /**************************************************************************
      * Callback functions - SERVER
      *************************************************************************/
@@ -1477,7 +1523,7 @@
                 // Descriptor is up next
                 gattClientGetDescriptorNative(svc.connId, svc.srvcType,
                     svc.srvcInstId, svc.srvcUuidLsb, svc.srvcUuidMsb,
-                    svc.charInstId, svc.charUuidLsb, svc.charUuidMsb, 0,0);
+                    svc.charInstId, svc.charUuidLsb, svc.charUuidMsb, 0, 0, 0);
             }
         } else {
             ClientMap.App app = mClientMap.getByConnId(connId);
@@ -1682,10 +1728,10 @@
             long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
             long char_id_uuid_msb);
 
-    private native void gattClientGetDescriptorNative(int conn_id,
-            int service_type, int service_id_inst_id, long service_id_uuid_lsb,
-            long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
-            long char_id_uuid_msb, long descr_id_uuid_lsb, long descr_id_uuid_msb);
+    private native void gattClientGetDescriptorNative(int conn_id, int service_type,
+            int service_id_inst_id, long service_id_uuid_lsb, long service_id_uuid_msb,
+            int char_id_inst_id, long char_id_uuid_lsb, long char_id_uuid_msb,
+            int descr_id_inst_id, long descr_id_uuid_lsb, long descr_id_uuid_msb);
 
     private native void gattClientGetIncludedServiceNative(int conn_id,
             int service_type, int service_id_inst_id,
@@ -1698,10 +1744,10 @@
             long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
             long char_id_uuid_msb, int authReq);
 
-    private native void gattClientReadDescriptorNative(int conn_id,
-            int service_type, int service_id_inst_id, long service_id_uuid_lsb,
-            long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
-            long char_id_uuid_msb, long descr_id_uuid_lsb, long descr_id_uuid_msb,
+    private native void gattClientReadDescriptorNative(int conn_id, int service_type,
+            int service_id_inst_id, long service_id_uuid_lsb, long service_id_uuid_msb,
+            int char_id_inst_id, long char_id_uuid_lsb, long char_id_uuid_msb,
+            int descr_id_inst_id, long descr_id_uuid_lsb, long descr_id_uuid_msb,
             int authReq);
 
     private native void gattClientWriteCharacteristicNative(int conn_id,
@@ -1709,10 +1755,10 @@
             long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
             long char_id_uuid_msb, int write_type, int auth_req, byte[] value);
 
-    private native void gattClientWriteDescriptorNative(int conn_id,
-            int service_type, int service_id_inst_id, long service_id_uuid_lsb,
-            long service_id_uuid_msb, int char_id_inst_id, long char_id_uuid_lsb,
-            long char_id_uuid_msb, long descr_id_uuid_lsb, long descr_id_uuid_msb,
+    private native void gattClientWriteDescriptorNative(int conn_id, int service_type,
+            int service_id_inst_id, long service_id_uuid_lsb, long service_id_uuid_msb,
+            int char_id_inst_id, long char_id_uuid_lsb, long char_id_uuid_msb,
+            int descr_id_inst_id, long descr_id_uuid_lsb, long descr_id_uuid_msb,
             int write_type, int auth_req, byte[] value);
 
     private native void gattClientExecuteWriteNative(int conn_id, boolean execute);
@@ -1726,6 +1772,12 @@
     private native void gattClientReadRemoteRssiNative(int clientIf,
             String address);
 
+    private native void gattClientListenNative(int client_if, boolean start);
+
+    private native void gattSetAdvDataNative(int serverIf, boolean setScanRsp, boolean inclName,
+            boolean inclTxPower, int minInterval, int maxInterval,
+            int appearance, byte[] manufacturerData);
+
     private native void gattServerRegisterAppNative(long app_uuid_lsb,
                                                     long app_uuid_msb);
 
diff --git a/src/com/android/bluetooth/hfp/AtPhonebook.java b/src/com/android/bluetooth/hfp/AtPhonebook.java
index d133706..4528bd6 100755
--- a/src/com/android/bluetooth/hfp/AtPhonebook.java
+++ b/src/com/android/bluetooth/hfp/AtPhonebook.java
@@ -47,7 +47,7 @@
      *   dialed calls respectively)
      */
     private static final String[] CALLS_PROJECTION = new String[] {
-        Calls._ID, Calls.NUMBER
+        Calls._ID, Calls.NUMBER, Calls.NUMBER_PRESENTATION
     };
 
     /** The projection to use when querying the contacts database in response
@@ -69,6 +69,7 @@
     private class PhonebookResult {
         public Cursor  cursor; // result set of last query
         public int     numberColumn;
+        public int     numberPresentationColumn;
         public int     typeColumn;
         public int     nameColumn;
     };
@@ -403,6 +404,8 @@
             if (pbr.cursor == null) return false;
 
             pbr.numberColumn = pbr.cursor.getColumnIndexOrThrow(Calls.NUMBER);
+            pbr.numberPresentationColumn =
+                    pbr.cursor.getColumnIndexOrThrow(Calls.NUMBER_PRESENTATION);
             pbr.typeColumn = -1;
             pbr.nameColumn = -1;
         } else {
@@ -411,6 +414,7 @@
             if (pbr.cursor == null) return false;
 
             pbr.numberColumn = pbr.cursor.getColumnIndex(Phone.NUMBER);
+            pbr.numberPresentationColumn = -1;
             pbr.typeColumn = pbr.cursor.getColumnIndex(Phone.TYPE);
             pbr.nameColumn = pbr.cursor.getColumnIndex(Phone.DISPLAY_NAME);
         }
@@ -488,7 +492,7 @@
             String number = pbr.cursor.getString(pbr.numberColumn);
             String name = null;
             int type = -1;
-            if (pbr.nameColumn == -1) {
+            if (pbr.nameColumn == -1 && number != null && number.length() > 0) {
                 // try caller id lookup
                 // TODO: This code is horribly inefficient. I saw it
                 // take 7 seconds to process 100 missed calls.
@@ -505,8 +509,10 @@
                 }
                 if (DBG && name == null) log("Caller ID lookup failed for " + number);
 
-            } else {
+            } else if (pbr.nameColumn != -1) {
                 name = pbr.cursor.getString(pbr.nameColumn);
+            } else {
+                log("processCpbrCommand: empty name and number");
             }
             if (name == null) name = "";
             name = name.trim();
@@ -523,9 +529,14 @@
             number = number.trim();
             number = PhoneNumberUtils.stripSeparators(number);
             if (number.length() > 30) number = number.substring(0, 30);
-            if (number.equals("-1")) {
-                // unknown numbers are stored as -1 in our database
+            int numberPresentation = Calls.PRESENTATION_ALLOWED;
+            if (pbr.numberPresentationColumn != -1) {
+                numberPresentation = pbr.cursor.getInt(pbr.numberPresentationColumn);
+            }
+            if (numberPresentation != Calls.PRESENTATION_ALLOWED) {
                 number = "";
+                // TODO: there are 3 types of numbers should have resource
+                // strings for: unknown, private, and payphone
                 name = mContext.getString(R.string.unknownNumber);
             }
 
diff --git a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
index f6d282c..05034e2 100755
--- a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
+++ b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
@@ -178,6 +178,8 @@
             mService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE) ?
                 HeadsetHalConstants.NETWORK_STATE_AVAILABLE :
                 HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE;
+            setRoam(serviceState.getRoaming() ? HeadsetHalConstants.SERVICE_TYPE_ROAMING
+                                              : HeadsetHalConstants.SERVICE_TYPE_HOME);
             sendDeviceStateChanged();
         }
 
@@ -321,3 +323,13 @@
         mType = type;
     }
 }
+
+class HeadsetVendorSpecificResultCode {
+    String mCommand;
+    String mArg;
+
+    public HeadsetVendorSpecificResultCode(String command, String arg) {
+        mCommand = command;
+        mArg = arg;
+    }
+}
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index b4928f4..d66009c 100755
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -104,8 +104,12 @@
                 }
             }
             else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
-                Log.v(TAG, "HeadsetService -  Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY");
-                mStateMachine.handleAccessPermissionResult(intent);
+                int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                               BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
+                if (requestType == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) {
+                    Log.v(TAG, "Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY");
+                    mStateMachine.handleAccessPermissionResult(intent);
+                }
             }
         }
     };
@@ -257,18 +261,22 @@
             service.phoneStateChanged(numActive, numHeld, callState, number, type);
         }
 
-        public void roamChanged(boolean roam) {
-            HeadsetService service = getService();
-            if (service == null) return;
-            service.roamChanged(roam);
-        }
-
         public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                                  String number, int type) {
             HeadsetService service = getService();
             if (service == null) return;
             service.clccResponse(index, direction, status, mode, mpty, number, type);
         }
+
+        public boolean sendVendorSpecificResultCode(BluetoothDevice device,
+                                                    String command,
+                                                    String arg) {
+            HeadsetService service = getService();
+            if (service == null) {
+                return false;
+            }
+            return service.sendVendorSpecificResultCode(device, command, arg);
+        }
     };
 
     //API methods
@@ -478,11 +486,6 @@
         mStateMachine.sendMessage(msg);
     }
 
-    private void roamChanged(boolean roam) {
-        enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-        mStateMachine.sendMessage(HeadsetStateMachine.ROAM_CHANGED, roam);
-    }
-
     private void clccResponse(int index, int direction, int status, int mode, boolean mpty,
                              String number, int type) {
         enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
@@ -490,4 +493,22 @@
             new HeadsetClccResponse(index, direction, status, mode, mpty, number, type));
     }
 
+    private boolean sendVendorSpecificResultCode(BluetoothDevice device,
+                                                 String command,
+                                                 String arg) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        int connectionState = mStateMachine.getConnectionState(device);
+        if (connectionState != BluetoothProfile.STATE_CONNECTED) {
+            return false;
+        }
+        // Currently we support only "+ANDROID".
+        if (!command.equals(BluetoothHeadset.VENDOR_RESULT_CODE_COMMAND_ANDROID)) {
+            Log.w(TAG, "Disallowed unsolicited result code command: " + command);
+            return false;
+        }
+        mStateMachine.sendMessage(HeadsetStateMachine.SEND_VENDOR_SPECIFIC_RESULT_CODE,
+                new HeadsetVendorSpecificResultCode(command, arg));
+        return true;
+    }
+
 }
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 059f326..7d9dc92 100755
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -62,7 +62,9 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 final class HeadsetStateMachine extends StateMachine {
@@ -88,8 +90,8 @@
     static final int CALL_STATE_CHANGED = 9;
     static final int INTENT_BATTERY_CHANGED = 10;
     static final int DEVICE_STATE_CHANGED = 11;
-    static final int ROAM_CHANGED = 12;
-    static final int SEND_CCLC_RESPONSE = 13;
+    static final int SEND_CCLC_RESPONSE = 12;
+    static final int SEND_VENDOR_SPECIFIC_RESULT_CODE = 13;
 
     static final int VIRTUAL_CALL_START = 14;
     static final int VIRTUAL_CALL_STOP = 15;
@@ -103,6 +105,9 @@
     private static final int DIALING_OUT_TIMEOUT_VALUE = 10000;
     private static final int START_VR_TIMEOUT_VALUE = 5000;
 
+    // Keys are AT commands, and values are the company IDs.
+    private static final Map<String, Integer> VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID;
+
     private static final ParcelUuid[] HEADSET_UUIDS = {
         BluetoothUuid.HSP,
         BluetoothUuid.Handsfree,
@@ -160,6 +165,10 @@
 
     static {
         classInitNative();
+
+        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID = new HashMap<String, Integer>();
+        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+XEVENT", BluetoothAssignedNumbers.PLANTRONICS);
+        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put("+ANDROID", BluetoothAssignedNumbers.GOOGLE);
     }
 
     private HeadsetStateMachine(HeadsetService context) {
@@ -179,8 +188,9 @@
         mPhoneState = new HeadsetPhoneState(context, this);
         mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (!context.bindService(new Intent(IBluetoothHeadsetPhone.class.getName()),
-                                 mConnection, 0)) {
+        Intent intent = new Intent(IBluetoothHeadsetPhone.class.getName());
+        intent.setComponent(intent.resolveSystemService(context.getPackageManager(), 0));
+        if (intent.getComponent() == null || !context.bindService(intent, mConnection, 0)) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Phone Service");
         }
 
@@ -285,9 +295,6 @@
                 case INTENT_BATTERY_CHANGED:
                     processIntentBatteryChanged((Intent) message.obj);
                     break;
-                case ROAM_CHANGED:
-                    processRoamChanged((Boolean) message.obj);
-                    break;
                 case CALL_STATE_CHANGED:
                     processCallState((HeadsetCallState) message.obj,
                         ((message.arg1 == 1)?true:false));
@@ -416,9 +423,6 @@
                 case INTENT_BATTERY_CHANGED:
                     processIntentBatteryChanged((Intent) message.obj);
                     break;
-                case ROAM_CHANGED:
-                    processRoamChanged((Boolean) message.obj);
-                    break;
                 case CALL_STATE_CHANGED:
                     processCallState((HeadsetCallState) message.obj,
                         ((message.arg1 == 1)?true:false));
@@ -649,15 +653,16 @@
                 case INTENT_BATTERY_CHANGED:
                     processIntentBatteryChanged((Intent) message.obj);
                     break;
-                case ROAM_CHANGED:
-                    processRoamChanged((Boolean) message.obj);
-                    break;
                 case DEVICE_STATE_CHANGED:
                     processDeviceStateChanged((HeadsetDeviceState) message.obj);
                     break;
                 case SEND_CCLC_RESPONSE:
                     processSendClccResponse((HeadsetClccResponse) message.obj);
                     break;
+                case SEND_VENDOR_SPECIFIC_RESULT_CODE:
+                    processSendVendorSpecificResultCode(
+                            (HeadsetVendorSpecificResultCode) message.obj);
+                    break;
                 case DIALING_OUT_TIMEOUT:
                     if (mDialingOut) {
                         mDialingOut= false;
@@ -866,15 +871,16 @@
                 case INTENT_BATTERY_CHANGED:
                     processIntentBatteryChanged((Intent) message.obj);
                     break;
-                case ROAM_CHANGED:
-                    processRoamChanged((Boolean) message.obj);
-                    break;
                 case DEVICE_STATE_CHANGED:
                     processDeviceStateChanged((HeadsetDeviceState) message.obj);
                     break;
                 case SEND_CCLC_RESPONSE:
                     processSendClccResponse((HeadsetClccResponse) message.obj);
                     break;
+                case SEND_VENDOR_SPECIFIC_RESULT_CODE:
+                    processSendVendorSpecificResultCode(
+                            (HeadsetVendorSpecificResultCode) message.obj);
+                    break;
 
                 case VIRTUAL_CALL_START:
                     initiateScoUsingVirtualVoiceCall();
@@ -1111,8 +1117,7 @@
             mVoiceRecognitionStarted + " mWaitingforVoiceRecognition: " + mWaitingForVoiceRecognition +
             " isInCall: " + isInCall());
         if (state == HeadsetHalConstants.VR_STATE_STARTED) {
-            if (!mVoiceRecognitionStarted &&
-                !isVirtualCallInProgress() &&
+            if (!isVirtualCallInProgress() &&
                 !isInCall())
             {
                 try {
@@ -1713,21 +1718,40 @@
         return out.toArray();
     }
 
-    private void processAtXevent(String atString) {
-        log("processAtXevent - atString = "+ atString);
-        if (atString.startsWith("=") && !atString.startsWith("=?")) {
-            Object[] args = generateArgs(atString.substring(1));
-            broadcastVendorSpecificEventIntent("+XEVENT",
-                                               BluetoothAssignedNumbers.PLANTRONICS,
-                                               BluetoothHeadset.AT_CMD_TYPE_SET,
-                                               args,
-                                               mCurrentDevice);
-            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0);
+    /**
+     * @return {@code true} if the given string is a valid vendor-specific AT command.
+     */
+    private boolean processVendorSpecificAt(String atString) {
+        log("processVendorSpecificAt - atString = " + atString);
+
+        // Currently we accept only SET type commands.
+        int indexOfEqual = atString.indexOf("=");
+        if (indexOfEqual == -1) {
+            Log.e(TAG, "processVendorSpecificAt: command type error in " + atString);
+            return false;
         }
-        else {
-            Log.e(TAG, "processAtXevent: command type error");
-            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
+
+        String command = atString.substring(0, indexOfEqual);
+        Integer companyId = VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.get(command);
+        if (companyId == null) {
+            Log.e(TAG, "processVendorSpecificAt: unsupported command: " + atString);
+            return false;
         }
+
+        String arg = atString.substring(indexOfEqual + 1);
+        if (arg.startsWith("?")) {
+            Log.e(TAG, "processVendorSpecificAt: command type error in " + atString);
+            return false;
+        }
+
+        Object[] args = generateArgs(arg);
+        broadcastVendorSpecificEventIntent(command,
+                                           companyId,
+                                           BluetoothHeadset.AT_CMD_TYPE_SET,
+                                           args,
+                                           mCurrentDevice);
+        atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0);
+        return true;
     }
 
     private void processUnknownAt(String atString) {
@@ -1741,9 +1765,7 @@
             processAtCpbs(atCommand.substring(5), commandType);
         else if (atCommand.startsWith("+CPBR"))
             processAtCpbr(atCommand.substring(5), commandType, mCurrentDevice);
-        else if (atCommand.startsWith("+XEVENT"))
-            processAtXevent(atCommand.substring(7));
-        else
+        else if (!processVendorSpecificAt(atCommand))
             atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0);
     }
 
@@ -1891,11 +1913,6 @@
         mPhoneState.setBatteryCharge(batteryLevel);
     }
 
-    private void processRoamChanged(boolean roam) {
-        mPhoneState.setRoam(roam ? HeadsetHalConstants.SERVICE_TYPE_ROAMING :
-                            HeadsetHalConstants.SERVICE_TYPE_HOME);
-    }
-
     private void processDeviceStateChanged(HeadsetDeviceState deviceState) {
         notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, deviceState.mSignal,
                                  deviceState.mBatteryCharge);
@@ -1906,6 +1923,14 @@
                            clcc.mNumber, clcc.mType);
     }
 
+    private void processSendVendorSpecificResultCode(HeadsetVendorSpecificResultCode resultCode) {
+        String stringToSend = resultCode.mCommand + ": ";
+        if (resultCode.mArg != null) {
+            stringToSend += resultCode.mArg;
+        }
+        atResponseStringNative(stringToSend);
+    }
+
     private String getCurrentDeviceName() {
         String defaultName = "<unknown>";
         if (mCurrentDevice == null) {
diff --git a/src/com/android/bluetooth/map/BluetoothMapAppParams.java b/src/com/android/bluetooth/map/BluetoothMapAppParams.java
new file mode 100644
index 0000000..ffdd2f1
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapAppParams.java
@@ -0,0 +1,798 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+import android.util.Log;
+
+/**
+ * This class encapsulates the appParams needed for MAP.
+ */
+public class BluetoothMapAppParams {
+
+    private static final String TAG = "BluetoothMapAppParams";
+
+    private static final int MAX_LIST_COUNT           = 0x01;
+    private static final int MAX_LIST_COUNT_LEN       = 0x02; //, 0x0000, 0xFFFF),
+    private static final int START_OFFSET             = 0x02;
+    private static final int START_OFFSET_LEN         = 0x02; //, 0x0000, 0xFFFF),
+    private static final int FILTER_MESSAGE_TYPE      = 0x03;
+    private static final int FILTER_MESSAGE_TYPE_LEN  = 0x01; //, 0x0000, 0x000f),
+    private static final int FILTER_PERIOD_BEGIN      = 0x04;
+    private static final int FILTER_PERIOD_END        = 0x05;
+    private static final int FILTER_READ_STATUS       = 0x06;
+    private static final int FILTER_READ_STATUS_LEN   = 0x01; //, 0x0000, 0x0002),
+    private static final int FILTER_RECIPIENT         = 0x07;
+    private static final int FILTER_ORIGINATOR        = 0x08;
+    private static final int FILTER_PRIORITY          = 0x09;
+    private static final int FILTER_PRIORITY_LEN      = 0x01; //, 0x0000, 0x0002),
+    private static final int ATTACHMENT               = 0x0A;
+    private static final int ATTACHMENT_LEN           = 0x01; //, 0x0000, 0x0001),
+    private static final int TRANSPARENT              = 0x0B;
+    private static final int TRANSPARENT_LEN          = 0x01; //, 0x0000, 0x0001),
+    private static final int RETRY                    = 0x0C;
+    private static final int RETRY_LEN                = 0x01; //, 0x0000, 0x0001),
+    private static final int NEW_MESSAGE              = 0x0D;
+    private static final int NEW_MESSAGE_LEN          = 0x01; //, 0x0000, 0x0001),
+    private static final int NOTIFICATION_STATUS      = 0x0E;
+    private static final int NOTIFICATION_STATUS_LEN  = 0x01; //, 0x0000, 0xFFFF),
+    private static final int MAS_INSTANCE_ID          = 0x0F;
+    private static final int MAS_INSTANCE_ID_LEN      = 0x01; //, 0x0000, 0x00FF),
+    private static final int PARAMETER_MASK           = 0x10;
+    private static final int PARAMETER_MASK_LEN       = 0x04; //, 0x0000, 0x0000),
+    private static final int FOLDER_LISTING_SIZE      = 0x11;
+    private static final int FOLDER_LISTING_SIZE_LEN  = 0x02; //, 0x0000, 0xFFFF),
+    private static final int MESSAGE_LISTING_SIZE     = 0x12;
+    private static final int MESSAGE_LISTING_SIZE_LEN = 0x02; //, 0x0000, 0xFFFF),
+    private static final int SUBJECT_LENGTH           = 0x13;
+    private static final int SUBJECT_LENGTH_LEN       = 0x01; //, 0x0000, 0x00FF),
+    private static final int CHARSET                  = 0x14;
+    private static final int CHARSET_LEN              = 0x01; //, 0x0000, 0x0001),
+    private static final int FRACTION_REQUEST         = 0x15;
+    private static final int FRACTION_REQUEST_LEN     = 0x01; //, 0x0000, 0x0001),
+    private static final int FRACTION_DELIVER         = 0x16;
+    private static final int FRACTION_DELIVER_LEN     = 0x01; //, 0x0000, 0x0001),
+    private static final int STATUS_INDICATOR         = 0x17;
+    private static final int STATUS_INDICATOR_LEN     = 0x01; //, 0x0000, 0x0001),
+    private static final int STATUS_VALUE             = 0x18;
+    private static final int STATUS_VALUE_LEN         = 0x01; //, 0x0000, 0x0001),
+    private static final int MSE_TIME                 = 0x19;
+
+    public static final int INVALID_VALUE_PARAMETER = -1;
+    public static final int NOTIFICATION_STATUS_NO = 0;
+    public static final int NOTIFICATION_STATUS_YES = 1;
+    public static final int STATUS_INDICATOR_READ = 0;
+    public static final int STATUS_INDICATOR_DELETED = 1;
+    public static final int STATUS_VALUE_YES = 1;
+    public static final int STATUS_VALUE_NO = 0;
+    public static final int CHARSET_NATIVE = 0;
+    public static final int CHARSET_UTF8 = 1;
+
+    private int maxListCount        = INVALID_VALUE_PARAMETER;
+    private int startOffset         = INVALID_VALUE_PARAMETER;
+    private int filterMessageType   = INVALID_VALUE_PARAMETER;
+    private long filterPeriodBegin  = INVALID_VALUE_PARAMETER;
+    private long filterPeriodEnd    = INVALID_VALUE_PARAMETER;
+    private int filterReadStatus    = INVALID_VALUE_PARAMETER;
+    private String filterRecipient   = null;
+    private String filterOriginator  = null;
+    private int filterPriority      = INVALID_VALUE_PARAMETER;
+    private int attachment          = INVALID_VALUE_PARAMETER;
+    private int transparent         = INVALID_VALUE_PARAMETER;
+    private int retry               = INVALID_VALUE_PARAMETER;
+    private int newMessage          = INVALID_VALUE_PARAMETER;
+    private int notificationStatus  = INVALID_VALUE_PARAMETER;
+    private int masInstanceId       = INVALID_VALUE_PARAMETER;
+    private long parameterMask      = INVALID_VALUE_PARAMETER;
+    private int folderListingSize   = INVALID_VALUE_PARAMETER;
+    private int messageListingSize  = INVALID_VALUE_PARAMETER;
+    private int subjectLength       = INVALID_VALUE_PARAMETER;
+    private int charset             = INVALID_VALUE_PARAMETER;
+    private int fractionRequest     = INVALID_VALUE_PARAMETER;
+    private int fractionDeliver     = INVALID_VALUE_PARAMETER;
+    private int statusIndicator     = INVALID_VALUE_PARAMETER;
+    private int statusValue         = INVALID_VALUE_PARAMETER;
+    private long mseTime            = INVALID_VALUE_PARAMETER;
+
+    /**
+     * Default constructor, used to build an application parameter object to be
+     * encoded. By default the member variables will be initialized to
+     * {@link INVALID_VALUE_PARAMETER} for values, and empty strings for String
+     * typed members.
+     */
+    public BluetoothMapAppParams() {
+    }
+
+    /**
+     * Creates an application parameter object based on a application parameter
+     * OBEX header. The content of the {@link appParam} byte array will be
+     * parsed, and its content will be stored in the member variables.
+     * {@link INVALID_VALUE_PARAMETER} can be used to determine if a value is
+     * set or not, where strings will be empty, if {@link appParam} did not
+     * contain the parameter.
+     *
+     * @param appParams
+     *            the byte array containing the application parameters OBEX
+     *            header
+     * @throws IllegalArgumentException
+     *             when a parameter does not respect the valid ranges specified
+     *             in the MAP spec.
+     * @throws ParseException
+     *             if a parameter string if formated incorrectly.
+     */
+    public BluetoothMapAppParams(final byte[] appParams)
+                 throws IllegalArgumentException, ParseException {
+        ParseParams(appParams);
+    }
+
+    /**
+     * Parse an application parameter OBEX header stored in a ByteArray.
+     *
+     * @param appParams
+     *            the byte array containing the application parameters OBEX
+     *            header
+     * @throws IllegalArgumentException
+     *             when a parameter does not respect the valid ranges specified
+     *             in the MAP spec.
+     * @throws ParseException
+     *             if a parameter string if formated incorrectly.
+     */
+    private void ParseParams(final byte[] appParams) throws ParseException,
+              IllegalArgumentException {
+        int i = 0;
+        int tagId, tagLength;
+        ByteBuffer appParamBuf = ByteBuffer.wrap(appParams);
+        appParamBuf.order(ByteOrder.BIG_ENDIAN);
+        while (i < appParams.length) {
+            tagId = appParams[i++] & 0xff;     // Convert to unsigned to support values above 127
+            tagLength = appParams[i++] & 0xff; // Convert to unsigned to support values above 127
+            switch (tagId) {
+            case MAX_LIST_COUNT:
+                if (tagLength != MAX_LIST_COUNT_LEN) {
+                    Log.w(TAG, "MAX_LIST_COUNT: Wrong length received: " + tagLength
+                               + " expected: " + MAX_LIST_COUNT_LEN);
+                    break;
+                }
+                setMaxListCount(appParamBuf.getShort(i) & 0xffff); // Make it unsigned
+                break;
+            case START_OFFSET:
+                if (tagLength != START_OFFSET_LEN) {
+                    Log.w(TAG, "START_OFFSET: Wrong length received: " + tagLength + " expected: "
+                               + START_OFFSET_LEN);
+                    break;
+                }
+                setStartOffset(appParamBuf.getShort(i) & 0xffff); // Make it unsigned
+                break;
+            case FILTER_MESSAGE_TYPE:
+                if (tagLength != FILTER_MESSAGE_TYPE_LEN) {
+                    Log.w(TAG, "FILTER_MESSAGE_TYPE: Wrong length received: " + tagLength + " expected: "
+                            + FILTER_MESSAGE_TYPE_LEN);
+                    break;
+                }
+                    setFilterMessageType(appParams[i] & 0x0f);
+                break;
+            case FILTER_PERIOD_BEGIN:
+                if(tagLength != 0) {
+                    setFilterPeriodBegin(new String(appParams, i, tagLength));
+                }
+                break;
+            case FILTER_PERIOD_END:
+                if(tagLength != 0) {
+                    setFilterPeriodEnd(new String(appParams, i, tagLength));
+                }
+                break;
+            case FILTER_READ_STATUS:
+                if (tagLength != FILTER_READ_STATUS_LEN) {
+                     Log.w(TAG, "FILTER_READ_STATUS: Wrong length received: " + tagLength + " expected: "
+                             + FILTER_READ_STATUS_LEN);
+                     break;
+                 }
+                setFilterReadStatus(appParams[i] & 0x03); // Lower two bits
+                break;
+            case FILTER_RECIPIENT:
+                setFilterRecipient(new String(appParams, i, tagLength));
+                break;
+            case FILTER_ORIGINATOR:
+                setFilterOriginator(new String(appParams, i, tagLength));
+                break;
+            case FILTER_PRIORITY:
+                if (tagLength != FILTER_PRIORITY_LEN) {
+                     Log.w(TAG, "FILTER_PRIORITY: Wrong length received: " + tagLength + " expected: "
+                             + FILTER_PRIORITY_LEN);
+                     break;
+                }
+                setFilterPriority(appParams[i] & 0x03); // Lower two bits
+                break;
+            case ATTACHMENT:
+                if (tagLength != ATTACHMENT_LEN) {
+                     Log.w(TAG, "ATTACHMENT: Wrong length received: " + tagLength + " expected: "
+                             + ATTACHMENT_LEN);
+                     break;
+                }
+                setAttachment(appParams[i] & 0x01); // Lower bit
+                break;
+            case TRANSPARENT:
+                if (tagLength != TRANSPARENT_LEN) {
+                     Log.w(TAG, "TRANSPARENT: Wrong length received: " + tagLength + " expected: "
+                             + TRANSPARENT_LEN);
+                     break;
+                }
+                setTransparent(appParams[i] & 0x01); // Lower bit
+                break;
+            case RETRY:
+                if (tagLength != RETRY_LEN) {
+                     Log.w(TAG, "RETRY: Wrong length received: " + tagLength + " expected: "
+                             + RETRY_LEN);
+                     break;
+                }
+                setRetry(appParams[i] & 0x01); // Lower bit
+                break;
+            case NEW_MESSAGE:
+                if (tagLength != NEW_MESSAGE_LEN) {
+                     Log.w(TAG, "NEW_MESSAGE: Wrong length received: " + tagLength + " expected: "
+                             + NEW_MESSAGE_LEN);
+                     break;
+                }
+                setNewMessage(appParams[i] & 0x01); // Lower bit
+                break;
+            case NOTIFICATION_STATUS:
+                if (tagLength != NOTIFICATION_STATUS_LEN) {
+                     Log.w(TAG, "NOTIFICATION_STATUS: Wrong length received: " + tagLength + " expected: "
+                             + NOTIFICATION_STATUS_LEN);
+                     break;
+                }
+                setNotificationStatus(appParams[i] & 0x01); // Lower bit
+                break;
+            case MAS_INSTANCE_ID:
+                if (tagLength != MAS_INSTANCE_ID_LEN) {
+                    Log.w(TAG, "MAS_INSTANCE_ID: Wrong length received: " + tagLength + " expected: "
+                            + MAS_INSTANCE_ID_LEN);
+                    break;
+                }
+                setMasInstanceId(appParams[i] & 0xff);
+                break;
+            case PARAMETER_MASK:
+                if (tagLength != PARAMETER_MASK_LEN) {
+                    Log.w(TAG, "PARAMETER_MASK: Wrong length received: " + tagLength + " expected: "
+                            + PARAMETER_MASK_LEN);
+                    break;
+                }
+                setParameterMask(appParamBuf.getInt(i) & 0xffffffffL); // Make it unsigned
+                break;
+            case FOLDER_LISTING_SIZE:
+                if (tagLength != FOLDER_LISTING_SIZE_LEN) {
+                    Log.w(TAG, "FOLDER_LISTING_SIZE: Wrong length received: " + tagLength + " expected: "
+                            + FOLDER_LISTING_SIZE_LEN);
+                    break;
+                }
+                setFolderListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned
+                break;
+            case MESSAGE_LISTING_SIZE:
+                if (tagLength != MESSAGE_LISTING_SIZE_LEN) {
+                    Log.w(TAG, "MESSAGE_LISTING_SIZE: Wrong length received: " + tagLength + " expected: "
+                            + MESSAGE_LISTING_SIZE_LEN);
+                    break;
+                }
+                setMessageListingSize(appParamBuf.getShort(i) & 0xffff); // Make it unsigned
+                break;
+            case SUBJECT_LENGTH:
+                if (tagLength != SUBJECT_LENGTH_LEN) {
+                    Log.w(TAG, "SUBJECT_LENGTH: Wrong length received: " + tagLength + " expected: "
+                            + SUBJECT_LENGTH_LEN);
+                    break;
+                }
+                setSubjectLength(appParams[i] & 0xff);
+                break;
+            case CHARSET:
+                if (tagLength != CHARSET_LEN) {
+                    Log.w(TAG, "CHARSET: Wrong length received: " + tagLength + " expected: "
+                            + CHARSET_LEN);
+                    break;
+                }
+                setCharset(appParams[i] & 0x01); // Lower bit
+                break;
+            case FRACTION_REQUEST:
+                if (tagLength != FRACTION_REQUEST_LEN) {
+                    Log.w(TAG, "FRACTION_REQUEST: Wrong length received: " + tagLength + " expected: "
+                            + FRACTION_REQUEST_LEN);
+                    break;
+                }
+                setFractionRequest(appParams[i] & 0x01); // Lower bit
+                break;
+            case FRACTION_DELIVER:
+                if (tagLength != FRACTION_DELIVER_LEN) {
+                    Log.w(TAG, "FRACTION_DELIVER: Wrong length received: " + tagLength + " expected: "
+                            + FRACTION_DELIVER_LEN);
+                    break;
+                }
+                setFractionDeliver(appParams[i] & 0x01); // Lower bit
+                break;
+            case STATUS_INDICATOR:
+                if (tagLength != STATUS_INDICATOR_LEN) {
+                    Log.w(TAG, "STATUS_INDICATOR: Wrong length received: " + tagLength + " expected: "
+                            + STATUS_INDICATOR_LEN);
+                    break;
+                }
+                setStatusIndicator(appParams[i] & 0x01); // Lower bit
+                break;
+            case STATUS_VALUE:
+                if (tagLength != STATUS_VALUE_LEN) {
+                    Log.w(TAG, "STATUS_VALUER: Wrong length received: " + tagLength + " expected: "
+                            + STATUS_VALUE_LEN);
+                    break;
+                }
+                setStatusValue(appParams[i] & 0x01); // Lower bit
+                break;
+            case MSE_TIME:
+                setMseTime(new String(appParams, i, tagLength));
+                break;
+            default:
+                // Just skip unknown Tags, no need to report error
+                Log.w(TAG, "Unknown TagId received ( 0x" + Integer.toString(tagId, 16)
+                           + "), skipping...");
+                break;
+            }
+            i += tagLength; // Offset to next TagId
+        }
+    }
+
+    /**
+     * Get the approximate length needed to store the appParameters in a byte
+     * array.
+     *
+     * @return the length in bytes
+     * @throws UnsupportedEncodingException
+     *             if the platform does not support UTF-8 encoding.
+     */
+    private int getParamMaxLength() throws UnsupportedEncodingException {
+        int length = 0;
+        length += 25 * 2; // tagId + tagLength
+        length += 27; // fixed sizes
+        length += getFilterPeriodBegin() == INVALID_VALUE_PARAMETER ? 0 : 15;
+        length += getFilterPeriodEnd() == INVALID_VALUE_PARAMETER ? 0 : 15;
+        if (getFilterRecipient() != null)
+            length += getFilterRecipient().getBytes("UTF-8").length;
+        if (getFilterOriginator() != null)
+            length += getFilterOriginator().getBytes("UTF-8").length;
+        length += getMseTime() == INVALID_VALUE_PARAMETER ? 0 : 20;
+        return length;
+    }
+
+    /**
+     * Encode the application parameter object to a byte array.
+     *
+     * @return a byte Array representation of the application parameter object.
+     * @throws UnsupportedEncodingException
+     *             if the platform does not support UTF-8 encoding.
+     */
+    public byte[] EncodeParams() throws UnsupportedEncodingException {
+        ByteBuffer appParamBuf = ByteBuffer.allocate(getParamMaxLength());
+        appParamBuf.order(ByteOrder.BIG_ENDIAN);
+        byte[] retBuf;
+
+        if (getMaxListCount() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) MAX_LIST_COUNT);
+            appParamBuf.put((byte) MAX_LIST_COUNT_LEN);
+            appParamBuf.putShort((short) getMaxListCount());
+        }
+        if (getStartOffset() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) START_OFFSET);
+            appParamBuf.put((byte) START_OFFSET_LEN);
+            appParamBuf.putShort((short) getStartOffset());
+        }
+        if (getFilterMessageType() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FILTER_MESSAGE_TYPE);
+            appParamBuf.put((byte) FILTER_MESSAGE_TYPE_LEN);
+            appParamBuf.put((byte) getFilterMessageType());
+        }
+        if (getFilterPeriodBegin() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FILTER_PERIOD_BEGIN);
+            appParamBuf.put((byte) getFilterPeriodBeginString().getBytes("UTF-8").length);
+            appParamBuf.put(getFilterPeriodBeginString().getBytes("UTF-8"));
+        }
+        if (getFilterPeriodEnd() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FILTER_PERIOD_END);
+            appParamBuf.put((byte) getFilterPeriodEndString().getBytes("UTF-8").length);
+            appParamBuf.put(getFilterPeriodEndString().getBytes("UTF-8"));
+        }
+        if (getFilterReadStatus() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FILTER_READ_STATUS);
+            appParamBuf.put((byte) FILTER_READ_STATUS_LEN);
+            appParamBuf.put((byte) getFilterReadStatus());
+        }
+        if (getFilterRecipient() != null) {
+            appParamBuf.put((byte) FILTER_RECIPIENT);
+            appParamBuf.put((byte) getFilterRecipient().getBytes("UTF-8").length);
+            appParamBuf.put(getFilterRecipient().getBytes("UTF-8"));
+        }
+        if (getFilterOriginator() != null) {
+            appParamBuf.put((byte) FILTER_ORIGINATOR);
+            appParamBuf.put((byte) getFilterOriginator().getBytes("UTF-8").length);
+            appParamBuf.put(getFilterOriginator().getBytes("UTF-8"));
+        }
+        if (getFilterPriority() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FILTER_PRIORITY);
+            appParamBuf.put((byte) FILTER_PRIORITY_LEN);
+            appParamBuf.put((byte) getFilterPriority());
+        }
+        if (getAttachment() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) ATTACHMENT);
+            appParamBuf.put((byte) ATTACHMENT_LEN);
+            appParamBuf.put((byte) getAttachment());
+        }
+        if (getTransparent() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) TRANSPARENT);
+            appParamBuf.put((byte) TRANSPARENT_LEN);
+            appParamBuf.put((byte) getTransparent());
+        }
+        if (getRetry() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) RETRY);
+            appParamBuf.put((byte) RETRY_LEN);
+            appParamBuf.put((byte) getRetry());
+        }
+        if (getNewMessage() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) NEW_MESSAGE);
+            appParamBuf.put((byte) NEW_MESSAGE_LEN);
+            appParamBuf.put((byte) getNewMessage());
+        }
+        if (getNotificationStatus() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) NOTIFICATION_STATUS);
+            appParamBuf.put((byte) NOTIFICATION_STATUS_LEN);
+            appParamBuf.putShort((short) getNotificationStatus());
+        }
+        if (getMasInstanceId() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) MAS_INSTANCE_ID);
+            appParamBuf.put((byte) MAS_INSTANCE_ID_LEN);
+            appParamBuf.put((byte) getMasInstanceId());
+        }
+        if (getParameterMask() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) PARAMETER_MASK);
+            appParamBuf.put((byte) PARAMETER_MASK_LEN);
+            appParamBuf.putInt((int) getParameterMask());
+        }
+        if (getFolderListingSize() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FOLDER_LISTING_SIZE);
+            appParamBuf.put((byte) FOLDER_LISTING_SIZE_LEN);
+            appParamBuf.putShort((short) getFolderListingSize());
+        }
+        if (getMessageListingSize() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) MESSAGE_LISTING_SIZE);
+            appParamBuf.put((byte) MESSAGE_LISTING_SIZE_LEN);
+            appParamBuf.putShort((short) getMessageListingSize());
+        }
+        if (getSubjectLength() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) SUBJECT_LENGTH);
+            appParamBuf.put((byte) SUBJECT_LENGTH_LEN);
+            appParamBuf.put((byte) getSubjectLength());
+        }
+        if (getCharset() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) CHARSET);
+            appParamBuf.put((byte) CHARSET_LEN);
+            appParamBuf.put((byte) getCharset());
+        }
+        if (getFractionRequest() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FRACTION_REQUEST);
+            appParamBuf.put((byte) FRACTION_REQUEST_LEN);
+            appParamBuf.put((byte) getFractionRequest());
+        }
+        if (getFractionDeliver() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) FRACTION_DELIVER);
+            appParamBuf.put((byte) FRACTION_DELIVER_LEN);
+            appParamBuf.put((byte) getFractionDeliver());
+        }
+        if (getStatusIndicator() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) STATUS_INDICATOR);
+            appParamBuf.put((byte) STATUS_INDICATOR_LEN);
+            appParamBuf.put((byte) getStatusIndicator());
+        }
+        if (getStatusValue() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) STATUS_VALUE);
+            appParamBuf.put((byte) STATUS_VALUE_LEN);
+            appParamBuf.put((byte) getStatusValue());
+        }
+        if (getMseTime() != INVALID_VALUE_PARAMETER) {
+            appParamBuf.put((byte) MSE_TIME);
+            appParamBuf.put((byte) getMseTimeString().getBytes("UTF-8").length);
+            appParamBuf.put(getMseTimeString().getBytes("UTF-8"));
+        }
+        // We need to reduce the length of the array to match the content
+        retBuf = Arrays.copyOfRange(appParamBuf.array(), appParamBuf.arrayOffset(),
+                                    appParamBuf.arrayOffset() + appParamBuf.position());
+        return retBuf;
+    }
+
+    public int getMaxListCount() {
+        return maxListCount;
+    }
+
+    public void setMaxListCount(int maxListCount) throws IllegalArgumentException {
+        if (maxListCount < 0 || maxListCount > 0xFFFF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF");
+        this.maxListCount = maxListCount;
+    }
+
+    public int getStartOffset() {
+        return startOffset;
+    }
+
+    public void setStartOffset(int startOffset) throws IllegalArgumentException {
+        if (startOffset < 0 || startOffset > 0xFFFF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF");
+        this.startOffset = startOffset;
+    }
+
+    public int getFilterMessageType() {
+        return filterMessageType;
+    }
+
+    public void setFilterMessageType(int filterMessageType) throws IllegalArgumentException {
+        if (filterMessageType < 0 || filterMessageType > 0x000F)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x000F");
+        this.filterMessageType = filterMessageType;
+    }
+
+    public long getFilterPeriodBegin() {
+        return filterPeriodBegin;
+    }
+
+    public String getFilterPeriodBeginString() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = new Date(filterPeriodBegin);
+        return format.format(date); // Format to YYYYMMDDTHHMMSS local time
+    }
+
+    public void setFilterPeriodBegin(long filterPeriodBegin) {
+        this.filterPeriodBegin = filterPeriodBegin;
+    }
+
+    public void setFilterPeriodBegin(String filterPeriodBegin) throws ParseException {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = format.parse(filterPeriodBegin);
+        this.filterPeriodBegin = date.getTime();
+    }
+
+    public long getFilterPeriodEnd() {
+        return filterPeriodEnd;
+    }
+
+    public String getFilterPeriodEndString() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = new Date(filterPeriodEnd);
+        return format.format(date); // Format to YYYYMMDDTHHMMSS local time
+    }
+
+    public void setFilterPeriodEnd(long filterPeriodEnd) {
+        this.filterPeriodEnd = filterPeriodEnd;
+    }
+
+    public void setFilterPeriodEnd(String filterPeriodEnd) throws ParseException {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = format.parse(filterPeriodEnd);
+        this.filterPeriodEnd = date.getTime();
+    }
+
+    public int getFilterReadStatus() {
+        return filterReadStatus;
+    }
+
+    public void setFilterReadStatus(int filterReadStatus) throws IllegalArgumentException {
+        if (filterReadStatus < 0 || filterReadStatus > 0x0002)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002");
+        this.filterReadStatus = filterReadStatus;
+    }
+
+    public String getFilterRecipient() {
+        return filterRecipient;
+    }
+
+    public void setFilterRecipient(String filterRecipient) {
+        this.filterRecipient = filterRecipient;
+    }
+
+    public String getFilterOriginator() {
+        return filterOriginator;
+    }
+
+    public void setFilterOriginator(String filterOriginator) {
+        this.filterOriginator = filterOriginator;
+    }
+
+    public int getFilterPriority() {
+        return filterPriority;
+    }
+
+    public void setFilterPriority(int filterPriority) throws IllegalArgumentException {
+        if (filterPriority < 0 || filterPriority > 0x0002)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0002");
+        this.filterPriority = filterPriority;
+    }
+
+    public int getAttachment() {
+        return attachment;
+    }
+
+    public void setAttachment(int attachment) throws IllegalArgumentException {
+        if (attachment < 0 || attachment > 0x0001)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.attachment = attachment;
+    }
+
+    public int getTransparent() {
+        return transparent;
+    }
+
+    public void setTransparent(int transparent) throws IllegalArgumentException {
+        if (transparent < 0 || transparent > 0x0001)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.transparent = transparent;
+    }
+
+    public int getRetry() {
+        return retry;
+    }
+
+    public void setRetry(int retry) throws IllegalArgumentException {
+        if (retry < 0 || retry > 0x0001)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.retry = retry;
+    }
+
+    public int getNewMessage() {
+        return newMessage;
+    }
+
+    public void setNewMessage(int newMessage) throws IllegalArgumentException {
+        if (newMessage < 0 || newMessage > 0x0001)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.newMessage = newMessage;
+    }
+
+    public int getNotificationStatus() {
+        return notificationStatus;
+    }
+
+    public void setNotificationStatus(int notificationStatus) throws IllegalArgumentException {
+        if (notificationStatus < 0 || notificationStatus > 0x0001)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.notificationStatus = notificationStatus;
+    }
+
+    public int getMasInstanceId() {
+        return masInstanceId;
+    }
+
+    public void setMasInstanceId(int masInstanceId) {
+        if (masInstanceId < 0 || masInstanceId > 0x00FF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF");
+        this.masInstanceId = masInstanceId;
+    }
+
+    public long getParameterMask() {
+        return parameterMask;
+    }
+
+    public void setParameterMask(long parameterMask) {
+        if (parameterMask < 0 || parameterMask > 0xFFFFFFFFL)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFFFFFF");
+        this.parameterMask = parameterMask;
+    }
+
+    public int getFolderListingSize() {
+        return folderListingSize;
+    }
+
+    public void setFolderListingSize(int folderListingSize) {
+        if (folderListingSize < 0 || folderListingSize > 0xFFFF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF");
+        this.folderListingSize = folderListingSize;
+    }
+
+    public int getMessageListingSize() {
+        return messageListingSize;
+    }
+
+    public void setMessageListingSize(int messageListingSize) {
+        if (messageListingSize < 0 || messageListingSize > 0xFFFF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0xFFFF");
+        this.messageListingSize = messageListingSize;
+    }
+
+    public int getSubjectLength() {
+        return subjectLength;
+    }
+
+    public void setSubjectLength(int subjectLength) {
+        if (subjectLength < 0 || subjectLength > 0xFF)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x00FF");
+        this.subjectLength = subjectLength;
+    }
+
+    public int getCharset() {
+        return charset;
+    }
+
+    public void setCharset(int charset) {
+        if (charset < 0 || charset > 0x1)
+            throw new IllegalArgumentException("Out of range: " + charset + ", valid range is 0x0000 to 0x0001");
+        this.charset = charset;
+    }
+
+    public int getFractionRequest() {
+        return fractionRequest;
+    }
+
+    public void setFractionRequest(int fractionRequest) {
+        if (fractionRequest < 0 || fractionRequest > 0x1)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.fractionRequest = fractionRequest;
+    }
+
+    public int getFractionDeliver() {
+        return fractionDeliver;
+    }
+
+    public void setFractionDeliver(int fractionDeliver) {
+        if (fractionDeliver < 0 || fractionDeliver > 0x1)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.fractionDeliver = fractionDeliver;
+    }
+
+    public int getStatusIndicator() {
+        return statusIndicator;
+    }
+
+    public void setStatusIndicator(int statusIndicator) {
+        if (statusIndicator < 0 || statusIndicator > 0x1)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.statusIndicator = statusIndicator;
+    }
+
+    public int getStatusValue() {
+        return statusValue;
+    }
+
+    public void setStatusValue(int statusValue) {
+        if (statusValue < 0 || statusValue > 0x1)
+            throw new IllegalArgumentException("Out of range, valid range is 0x0000 to 0x0001");
+        this.statusValue = statusValue;
+    }
+
+    public long getMseTime() {
+        return mseTime;
+    }
+
+    public String getMseTimeString() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+        Date date = new Date(getMseTime());
+        return format.format(date); // Format to YYYYMMDDTHHMMSS±hhmm UTC time ± offset
+    }
+
+    public void setMseTime(long mseTime) {
+        this.mseTime = mseTime;
+    }
+
+    public void setMseTime(String mseTime) throws ParseException {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmssZ");
+        Date date = format.parse(mseTime);
+        this.mseTime = date.getTime();
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapAuthenticator.java b/src/com/android/bluetooth/map/BluetoothMapAuthenticator.java
new file mode 100644
index 0000000..2d345a1
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapAuthenticator.java
@@ -0,0 +1,88 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import javax.obex.Authenticator;
+import javax.obex.PasswordAuthentication;
+
+/**
+ * BluetoothMapAuthenticator is a used by BluetoothObexServer for obex
+ * authentication procedure.
+ */
+public class BluetoothMapAuthenticator implements Authenticator {
+    private static final String TAG = "BluetoothMapAuthenticator";
+
+    private boolean mChallenged;
+
+    private boolean mAuthCancelled;
+
+    private String mSessionKey;
+
+    private Handler mCallback;
+
+    public BluetoothMapAuthenticator(final Handler callback) {
+        mCallback = callback;
+        mChallenged = false;
+        mAuthCancelled = false;
+        mSessionKey = null;
+    }
+
+    public final synchronized void setChallenged(final boolean bool) {
+        mChallenged = bool;
+    }
+
+    public final synchronized void setCancelled(final boolean bool) {
+        mAuthCancelled = bool;
+    }
+
+    public final synchronized void setSessionKey(final String string) {
+        mSessionKey = string;
+    }
+
+    private void waitUserConfirmation() {
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMapService.MSG_OBEX_AUTH_CHALL;
+        msg.sendToTarget();
+        synchronized (this) {
+            while (!mChallenged && !mAuthCancelled) {
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Interrupted while waiting on isChallenged");
+                }
+            }
+        }
+    }
+
+    public PasswordAuthentication onAuthenticationChallenge(final String description,
+            final boolean isUserIdRequired, final boolean isFullAccess) {
+        waitUserConfirmation();
+        if (mSessionKey.trim().length() != 0) {
+            PasswordAuthentication pa = new PasswordAuthentication(null, mSessionKey.getBytes());
+            return pa;
+        }
+        return null;
+    }
+
+    // TODO: Reserved for future use only, in case MSE challenge MCE
+    public byte[] onAuthenticationResponse(final byte[] userName) {
+        byte[] b = null;
+        return b;
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapContent.java b/src/com/android/bluetooth/map/BluetoothMapContent.java
new file mode 100644
index 0000000..1108a48
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapContent.java
@@ -0,0 +1,1651 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.text.ParseException;
+
+import org.apache.http.util.ByteArrayBuffer;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.Telephony.Mms;
+import android.provider.Telephony.Sms;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+import com.google.android.mms.pdu.CharacterSets;
+
+public class BluetoothMapContent {
+    private static final String TAG = "BluetoothMapContent";
+
+    private static final boolean D = false;
+    private static final boolean V = false;
+
+    private static final int MASK_SUBJECT = 0x1;
+    private static final int MASK_DATETIME = 0x2;
+    private static final int MASK_SENDER_NAME = 0x4;
+    private static final int MASK_SENDER_ADDRESSING = 0x8;
+
+    private static final int MASK_RECIPIENT_NAME = 0x10;
+    private static final int MASK_RECIPIENT_ADDRESSING = 0x20;
+    private static final int MASK_TYPE = 0x40;
+    private static final int MASK_SIZE = 0x80;
+
+    private static final int MASK_RECEPTION_STATUS = 0x100;
+    private static final int MASK_TEXT = 0x200;
+    private static final int MASK_ATTACHMENT_SIZE = 0x400;
+    private static final int MASK_PRIORITY = 0x800;
+
+    private static final int MASK_READ = 0x1000;
+    private static final int MASK_SENT = 0x2000;
+    private static final int MASK_PROTECTED = 0x4000;
+    private static final int MASK_REPLYTO_ADDRESSING = 0x8000;
+
+    /* Type of MMS address. From Telephony.java it must be one of PduHeaders.BCC, */
+    /* PduHeaders.CC, PduHeaders.FROM, PduHeaders.TO. These are from PduHeaders.java */
+    public static final int MMS_FROM = 0x89;
+    public static final int MMS_TO = 0x97;
+    public static final int MMS_BCC = 0x81;
+    public static final int MMS_CC = 0x82;
+
+    private Context mContext;
+    private ContentResolver mResolver;
+
+    static final String[] SMS_PROJECTION = new String[] {
+        BaseColumns._ID,
+        Sms.THREAD_ID,
+        Sms.ADDRESS,
+        Sms.BODY,
+        Sms.DATE,
+        Sms.READ,
+        Sms.TYPE,
+        Sms.STATUS,
+        Sms.LOCKED,
+        Sms.ERROR_CODE,
+    };
+
+    static final String[] MMS_PROJECTION = new String[] {
+        BaseColumns._ID,
+        Mms.THREAD_ID,
+        Mms.MESSAGE_ID,
+        Mms.MESSAGE_SIZE,
+        Mms.SUBJECT,
+        Mms.CONTENT_TYPE,
+        Mms.TEXT_ONLY,
+        Mms.DATE,
+        Mms.DATE_SENT,
+        Mms.READ,
+        Mms.MESSAGE_BOX,
+        Mms.STATUS,
+    };
+
+    private class FilterInfo {
+        public static final int TYPE_SMS = 0;
+        public static final int TYPE_MMS = 1;
+
+        int msgType = TYPE_SMS;
+        int phoneType = 0;
+        String phoneNum = null;
+        String phoneAlphaTag = null;
+    }
+
+    public BluetoothMapContent(final Context context) {
+        mContext = context;
+        mResolver = mContext.getContentResolver();
+        if (mResolver == null) {
+            Log.d(TAG, "getContentResolver failed");
+        }
+    }
+
+    private void addSmsEntry() {
+        if (D) Log.d(TAG, "*** Adding dummy sms ***");
+
+        ContentValues mVal = new ContentValues();
+        mVal.put(Sms.ADDRESS, "1234");
+        mVal.put(Sms.BODY, "Hello!!!");
+        mVal.put(Sms.DATE, System.currentTimeMillis());
+        mVal.put(Sms.READ, "0");
+
+        Uri mUri = mResolver.insert(Sms.CONTENT_URI, mVal);
+    }
+
+    private BluetoothMapAppParams buildAppParams() {
+        BluetoothMapAppParams ap = new BluetoothMapAppParams();
+        try {
+            int paramMask = (MASK_SUBJECT
+                | MASK_DATETIME
+                | MASK_SENDER_NAME
+                | MASK_SENDER_ADDRESSING
+                | MASK_RECIPIENT_NAME
+                | MASK_RECIPIENT_ADDRESSING
+                | MASK_TYPE
+                | MASK_SIZE
+                | MASK_RECEPTION_STATUS
+                | MASK_TEXT
+                | MASK_ATTACHMENT_SIZE
+                | MASK_PRIORITY
+                | MASK_READ
+                | MASK_SENT
+                | MASK_PROTECTED
+                );
+            ap.setMaxListCount(5);
+            ap.setStartOffset(0);
+            ap.setFilterMessageType(0);
+            ap.setFilterPeriodBegin("20130101T000000");
+            ap.setFilterPeriodEnd("20131230T000000");
+            ap.setFilterReadStatus(0);
+            ap.setParameterMask(paramMask);
+            ap.setSubjectLength(10);
+            /* ap.setFilterOriginator("Sms*"); */
+            /* ap.setFilterRecipient("41*"); */
+        } catch (ParseException e) {
+            return null;
+        }
+        return ap;
+    }
+
+    private void printSms(Cursor c) {
+        String body = c.getString(c.getColumnIndex(Sms.BODY));
+        if (D) Log.d(TAG, "printSms " + BaseColumns._ID + ": " + c.getLong(c.getColumnIndex(BaseColumns._ID)) +
+                " " + Sms.THREAD_ID + " : " + c.getLong(c.getColumnIndex(Sms.THREAD_ID)) +
+                " " + Sms.ADDRESS + " : " + c.getString(c.getColumnIndex(Sms.ADDRESS)) +
+                " " + Sms.BODY + " : " + body.substring(0, Math.min(body.length(), 8)) +
+                " " + Sms.DATE + " : " + c.getLong(c.getColumnIndex(Sms.DATE)) +
+                " " + Sms.TYPE + " : " + c.getInt(c.getColumnIndex(Sms.TYPE)));
+    }
+
+    private void printMms(Cursor c) {
+        if (D) Log.d(TAG, "printMms " + BaseColumns._ID + ": " + c.getLong(c.getColumnIndex(BaseColumns._ID)) +
+                "\n   " + Mms.THREAD_ID + " : " + c.getLong(c.getColumnIndex(Mms.THREAD_ID)) +
+                "\n   " + Mms.MESSAGE_ID + " : " + c.getString(c.getColumnIndex(Mms.MESSAGE_ID)) +
+                "\n   " + Mms.SUBJECT + " : " + c.getString(c.getColumnIndex(Mms.SUBJECT)) +
+                "\n   " + Mms.CONTENT_TYPE + " : " + c.getString(c.getColumnIndex(Mms.CONTENT_TYPE)) +
+                "\n   " + Mms.TEXT_ONLY + " : " + c.getInt(c.getColumnIndex(Mms.TEXT_ONLY)) +
+                "\n   " + Mms.DATE + " : " + c.getLong(c.getColumnIndex(Mms.DATE)) +
+                "\n   " + Mms.DATE_SENT + " : " + c.getLong(c.getColumnIndex(Mms.DATE_SENT)) +
+                "\n   " + Mms.READ + " : " + c.getInt(c.getColumnIndex(Mms.READ)) +
+                "\n   " + Mms.MESSAGE_BOX + " : " + c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)) +
+                "\n   " + Mms.STATUS + " : " + c.getInt(c.getColumnIndex(Mms.STATUS)));
+    }
+
+    private void printMmsAddr(long id) {
+        final String[] projection = null;
+        String selection = new String("msg_id=" + id);
+        String uriStr = String.format("content://mms/%d/addr", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        Cursor c = mResolver.query(
+            uriAddress,
+            projection,
+            selection,
+            null, null);
+
+        if (c.moveToFirst()) {
+            do {
+                String add = c.getString(c.getColumnIndex("address"));
+                Integer type = c.getInt(c.getColumnIndex("type"));
+                if (type == MMS_TO) {
+                    if (D) Log.d(TAG, "   recipient: " + add + " (type: " + type + ")");
+                } else if (type == MMS_FROM) {
+                    if (D) Log.d(TAG, "   originator: " + add + " (type: " + type + ")");
+                } else {
+                    if (D) Log.d(TAG, "   address other: " + add + " (type: " + type + ")");
+                }
+
+            } while(c.moveToNext());
+        }
+    }
+
+    private void printMmsPartImage(long partid) {
+        String uriStr = String.format("content://mms/part/%d", partid);
+        Uri uriAddress = Uri.parse(uriStr);
+        int ch;
+        StringBuffer sb = new StringBuffer("");
+        InputStream is = null;
+
+        try {
+            is = mResolver.openInputStream(uriAddress);
+
+            while ((ch = is.read()) != -1) {
+                sb.append((char)ch);
+            }
+            if (D) Log.d(TAG, sb.toString());
+
+        } catch (IOException e) {
+            // do nothing for now
+            e.printStackTrace();
+        }
+    }
+
+    private void printMmsParts(long id) {
+        final String[] projection = null;
+        String selection = new String("mid=" + id);
+        String uriStr = String.format("content://mms/%d/part", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        Cursor c = mResolver.query(
+            uriAddress,
+            projection,
+            selection,
+            null, null);
+
+        if (D) Log.d(TAG, "   parts:");
+        if (c.moveToFirst()) {
+            do {
+                Long partid = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String ct = c.getString(c.getColumnIndex("ct"));
+                String name = c.getString(c.getColumnIndex("name"));
+                String charset = c.getString(c.getColumnIndex("chset"));
+                String filename = c.getString(c.getColumnIndex("fn"));
+                String text = c.getString(c.getColumnIndex("text"));
+                Integer fd = c.getInt(c.getColumnIndex("_data"));
+                String cid = c.getString(c.getColumnIndex("cid"));
+                String cl = c.getString(c.getColumnIndex("cl"));
+                String cdisp = c.getString(c.getColumnIndex("cd"));
+
+                if (D) Log.d(TAG, "     _id : " + partid +
+                    "\n     ct : " + ct +
+                    "\n     partname : " + name +
+                    "\n     charset : " + charset +
+                    "\n     filename : " + filename +
+                    "\n     text : " + text +
+                    "\n     fd : " + fd +
+                    "\n     cid : " + cid +
+                    "\n     cl : " + cl +
+                    "\n     cdisp : " + cdisp);
+
+                /* if (ct.equals("image/jpeg")) { */
+                /*     printMmsPartImage(partid); */
+                /* } */
+            } while(c.moveToNext());
+        }
+    }
+
+    public void dumpMmsTable() {
+        if (D) Log.d(TAG, "**** Dump of mms table ****");
+        Cursor c = mResolver.query(Mms.CONTENT_URI,
+                MMS_PROJECTION, null, null, "_id DESC");
+        if (c != null) {
+            if (D) Log.d(TAG, "c.getCount() = " + c.getCount());
+            c.moveToPosition(-1);
+            while (c.moveToNext()) {
+                printMms(c);
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                printMmsAddr(id);
+                printMmsParts(id);
+            }
+        } else {
+            Log.d(TAG, "query failed");
+            c.close();
+        }
+    }
+
+    public void dumpSmsTable() {
+        addSmsEntry();
+        if (D) Log.d(TAG, "**** Dump of sms table ****");
+        Cursor c = mResolver.query(Sms.CONTENT_URI,
+                SMS_PROJECTION, null, null, "_id DESC");
+        if (c != null) {
+            if (D) Log.d(TAG, "c.getCount() = " + c.getCount());
+            c.moveToPosition(-1);
+            while (c.moveToNext()) {
+                printSms(c);
+            }
+        } else {
+            Log.d(TAG, "query failed");
+            c.close();
+        }
+
+    }
+
+    public void dumpMessages() {
+        dumpSmsTable();
+        dumpMmsTable();
+
+        BluetoothMapAppParams ap = buildAppParams();
+        if (D) Log.d(TAG, "message listing size = " + msgListingSize("inbox", ap));
+        BluetoothMapMessageListing mList = msgListing("inbox", ap);
+        try {
+            mList.encode();
+        } catch (UnsupportedEncodingException ex) {
+            /* do nothing */
+        }
+        mList = msgListing("sent", ap);
+        try {
+            mList.encode();
+        } catch (UnsupportedEncodingException ex) {
+            /* do nothing */
+        }
+    }
+
+    private void setProtected(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_PROTECTED) != 0) {
+            String protect = "no";
+            if (D) Log.d(TAG, "setProtected: " + protect);
+            e.setProtect(protect);
+        }
+    }
+
+    private void setSent(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_SENT) != 0) {
+            int msgType = 0;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                msgType = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+            }
+            String sent = null;
+            if (msgType == 2) {
+                sent = "yes";
+            } else {
+                sent = "no";
+            }
+            if (D) Log.d(TAG, "setSent: " + sent);
+            e.setSent(sent);
+        }
+    }
+
+    private void setRead(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        int read = 0;
+        if (fi.msgType == FilterInfo.TYPE_SMS) {
+            read = c.getInt(c.getColumnIndex(Sms.READ));
+        } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+            read = c.getInt(c.getColumnIndex(Mms.READ));
+        }
+        String setread = null;
+        if (read == 1) {
+            setread = "yes";
+        } else {
+            setread = "no";
+        }
+        if (D) Log.d(TAG, "setRead: " + setread);
+        e.setRead(setread, ((ap.getParameterMask() & MASK_READ) != 0));
+    }
+
+    private void setPriority(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_PRIORITY) != 0) {
+            String priority = "no";
+            if (D) Log.d(TAG, "setPriority: " + priority);
+            e.setPriority(priority);
+        }
+    }
+
+    /**
+     * For SMS we set the attachment size to 0, as all data will be text data, hence
+     * attachments for SMS is not possible.
+     * For MMS all data is actually attachments, hence we do set the attachment size to
+     * the total message size. To provide a more accurate attachment size, one could
+     * extract the length (in bytes) of the text parts.
+     */
+    private void setAttachmentSize(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_ATTACHMENT_SIZE) != 0) {
+            int size = 0;
+            if (fi.msgType == FilterInfo.TYPE_MMS) {
+                size = c.getInt(c.getColumnIndex(Mms.MESSAGE_SIZE));
+            }
+            if (D) Log.d(TAG, "setAttachmentSize: " + size);
+            e.setAttachmentSize(size);
+        }
+    }
+
+    private void setText(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_TEXT) != 0) {
+            String hasText = "";
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                hasText = "yes";
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                int textOnly = c.getInt(c.getColumnIndex(Mms.TEXT_ONLY));
+                if (textOnly == 1) {
+                    hasText = "yes";
+                } else {
+                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                    String text = getTextPartsMms(id);
+                    if (text != null && text.length() > 0) {
+                        hasText = "yes";
+                    } else {
+                        hasText = "no";
+                    }
+                }
+            }
+            if (D) Log.d(TAG, "setText: " + hasText);
+            e.setText(hasText);
+        }
+    }
+
+    private void setReceptionStatus(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_RECEPTION_STATUS) != 0) {
+            String status = "complete";
+            if (D) Log.d(TAG, "setReceptionStatus: " + status);
+            e.setReceptionStatus(status);
+        }
+    }
+
+    private void setSize(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_SIZE) != 0) {
+            int size = 0;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                String subject = c.getString(c.getColumnIndex(Sms.BODY));
+                size = subject.length();
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                size = c.getInt(c.getColumnIndex(Mms.MESSAGE_SIZE));
+            }
+            if (D) Log.d(TAG, "setSize: " + size);
+            e.setSize(size);
+        }
+    }
+
+    private void setType(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_TYPE) != 0) {
+            TYPE type = null;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                if (fi.phoneType == TelephonyManager.PHONE_TYPE_GSM) {
+                    type = TYPE.SMS_GSM;
+                } else if (fi.phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
+                    type = TYPE.SMS_CDMA;
+                }
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                type = TYPE.MMS;
+            }
+            if (D) Log.d(TAG, "setType: " + type);
+            e.setType(type);
+        }
+    }
+
+    private void setRecipientAddressing(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_RECIPIENT_ADDRESSING) != 0) {
+            String address = null;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+                if (msgType == 1) {
+                    address = fi.phoneNum;
+                } else {
+                    address = c.getString(c.getColumnIndex(Sms.ADDRESS));
+                }
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                address = getAddressMms(mResolver, id, MMS_TO);
+            }
+            if (D) Log.d(TAG, "setRecipientAddressing: " + address);
+            e.setRecipientAddressing(address);
+        }
+    }
+
+    private void setRecipientName(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_RECIPIENT_NAME) != 0) {
+            String name = null;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+                if (msgType != 1) {
+                    String phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
+                    name = getContactNameFromPhone(phone);
+                } else {
+                    name = fi.phoneAlphaTag;
+                }
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String phone = getAddressMms(mResolver, id, MMS_TO);
+                name = getContactNameFromPhone(phone);
+            }
+            if (D) Log.d(TAG, "setRecipientName: " + name);
+            e.setRecipientName(name);
+        }
+    }
+
+    private void setSenderAddressing(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_SENDER_ADDRESSING) != 0) {
+            String address = null;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+                if (msgType == 1) {
+                    address = c.getString(c.getColumnIndex(Sms.ADDRESS));
+                } else {
+                    address = fi.phoneNum;
+                }
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                address = getAddressMms(mResolver, id, MMS_FROM);
+            }
+            if (D) Log.d(TAG, "setSenderAddressing: " + address);
+            e.setSenderAddressing(address);
+        }
+    }
+
+    private void setSenderName(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        if ((ap.getParameterMask() & MASK_SENDER_NAME) != 0) {
+            String name = null;
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+                if (msgType == 1) {
+                    String phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
+                    name = getContactNameFromPhone(phone);
+                } else {
+                    name = fi.phoneAlphaTag;
+                }
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String phone = getAddressMms(mResolver, id, MMS_FROM);
+                name = getContactNameFromPhone(phone);
+            }
+            if (D) Log.d(TAG, "setSenderName: " + name);
+            e.setSenderName(name);
+        }
+    }
+
+    private void setDateTime(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        long date = 0;
+
+        if (fi.msgType == FilterInfo.TYPE_SMS) {
+            date = c.getLong(c.getColumnIndex(Sms.DATE));
+        } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+            /* Use Mms.DATE for all messages. Although contract class states */
+            /* Mms.DATE_SENT are for outgoing messages. But that is not working. */
+            date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L;
+
+            /* int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); */
+            /* if (msgBox == Mms.MESSAGE_BOX_INBOX) { */
+            /*     date = c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L; */
+            /* } else { */
+            /*     date = c.getLong(c.getColumnIndex(Mms.DATE_SENT)) * 1000L; */
+            /* } */
+        }
+        e.setDateTime(date);
+    }
+
+    private String getTextPartsMms(long id) {
+        String text = "";
+        String selection = new String("mid=" + id);
+        String uriStr = String.format("content://mms/%d/part", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        Cursor c = mResolver.query(uriAddress, null, selection,
+            null, null);
+
+        if (c != null && c.moveToFirst()) {
+            do {
+                String ct = c.getString(c.getColumnIndex("ct"));
+                if (ct.equals("text/plain")) {
+                    text += c.getString(c.getColumnIndex("text"));
+                }
+            } while(c.moveToNext());
+        }
+        if (c != null) {
+            c.close();
+        }
+        return text;
+    }
+
+    private void setSubject(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        String subject = "";
+        int subLength = ap.getSubjectLength();
+        if(subLength == BluetoothMapAppParams.INVALID_VALUE_PARAMETER)
+            subLength = 256;
+
+        if ((ap.getParameterMask() & MASK_SUBJECT) != 0) {
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                subject = c.getString(c.getColumnIndex(Sms.BODY));
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                subject = c.getString(c.getColumnIndex(Mms.SUBJECT));
+                if (subject == null || subject.length() == 0) {
+                    /* Get subject from mms text body parts - if any exists */
+                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                    subject = getTextPartsMms(id);
+                }
+            }
+            if (subject != null) {
+                subject = subject.substring(0, Math.min(subject.length(),
+                    subLength));
+            }
+            if (D) Log.d(TAG, "setSubject: " + subject);
+            e.setSubject(subject);
+        }
+    }
+
+    private void setHandle(BluetoothMapMessageListingElement e, Cursor c,
+        FilterInfo fi, BluetoothMapAppParams ap) {
+        long handle = c.getLong(c.getColumnIndex(BaseColumns._ID));
+        TYPE type = null;
+        if (fi.msgType == FilterInfo.TYPE_SMS) {
+            if (fi.phoneType == TelephonyManager.PHONE_TYPE_GSM) {
+                type = TYPE.SMS_GSM;
+            } else if (fi.phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
+                type = TYPE.SMS_CDMA;
+            }
+        } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+            type = TYPE.MMS;
+        }
+        if (D) Log.d(TAG, "setHandle: " + handle + " - Type: " + type.name());
+        e.setHandle(handle, type);
+    }
+
+    private BluetoothMapMessageListingElement element(Cursor c, FilterInfo fi,
+        BluetoothMapAppParams ap) {
+        BluetoothMapMessageListingElement e = new BluetoothMapMessageListingElement();
+
+        setHandle(e, c, fi, ap);
+        setSubject(e, c, fi, ap);
+        setDateTime(e, c, fi, ap);
+        setSenderName(e, c, fi, ap);
+        setSenderAddressing(e, c, fi, ap);
+        setRecipientName(e, c, fi, ap);
+        setRecipientAddressing(e, c, fi, ap);
+        setType(e, c, fi, ap);
+        setSize(e, c, fi, ap);
+        setReceptionStatus(e, c, fi, ap);
+        setText(e, c, fi, ap);
+        setAttachmentSize(e, c, fi, ap);
+        setPriority(e, c, fi, ap);
+        setRead(e, c, fi, ap);
+        setSent(e, c, fi, ap);
+        setProtected(e, c, fi, ap);
+        return e;
+    }
+
+    private String getContactNameFromPhone(String phone) {
+        String name = null;
+
+        Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+            Uri.encode(phone));
+
+        String[] projection = {Contacts._ID, Contacts.DISPLAY_NAME};
+        String selection = Contacts.IN_VISIBLE_GROUP + "=1";
+        String orderBy = Contacts.DISPLAY_NAME + " ASC";
+
+        Cursor c = mResolver.query(uri, projection, selection, null, orderBy);
+
+        if (c != null && c.getCount() >= 1) {
+            c.moveToFirst();
+            name = c.getString(c.getColumnIndex(Contacts.DISPLAY_NAME));
+        }
+
+        c.close();
+        return name;
+    }
+
+    static public String getAddressMms(ContentResolver r, long id, int type) {
+        String selection = new String("msg_id=" + id + " AND type=" + type);
+        String uriStr = String.format("content://mms/%d/addr", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        String addr = null;
+        Cursor c = r.query(uriAddress, null, selection, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            addr = c.getString(c.getColumnIndex("address"));
+        }
+
+        if (c != null) {
+            c.close();
+        }
+        return addr;
+    }
+
+    private boolean matchRecipientMms(Cursor c, FilterInfo fi, String recip) {
+        boolean res;
+        long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+        String phone = getAddressMms(mResolver, id, MMS_TO);
+        if (phone != null && phone.length() > 0) {
+            if (phone.matches(recip)) {
+                if (D) Log.d(TAG, "match recipient phone = " + phone);
+                res = true;
+            } else {
+                String name = getContactNameFromPhone(phone);
+                if (name != null && name.length() > 0 && name.matches(recip)) {
+                    if (D) Log.d(TAG, "match recipient name = " + name);
+                    res = true;
+                } else {
+                    res = false;
+                }
+            }
+        } else {
+            res = false;
+        }
+        return res;
+    }
+
+    private boolean matchRecipientSms(Cursor c, FilterInfo fi, String recip) {
+        boolean res;
+        int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+        if (msgType == 1) {
+            String phone = fi.phoneNum;
+            String name = fi.phoneAlphaTag;
+            if (phone != null && phone.length() > 0 && phone.matches(recip)) {
+                if (D) Log.d(TAG, "match recipient phone = " + phone);
+                res = true;
+            } else if (name != null && name.length() > 0 && name.matches(recip)) {
+                if (D) Log.d(TAG, "match recipient name = " + name);
+                res = true;
+            } else {
+                res = false;
+            }
+        }
+        else {
+            String phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
+            if (phone != null && phone.length() > 0) {
+                if (phone.matches(recip)) {
+                    if (D) Log.d(TAG, "match recipient phone = " + phone);
+                    res = true;
+                } else {
+                    String name = getContactNameFromPhone(phone);
+                    if (name != null && name.length() > 0 && name.matches(recip)) {
+                        if (D) Log.d(TAG, "match recipient name = " + name);
+                        res = true;
+                    } else {
+                        res = false;
+                    }
+                }
+            } else {
+                res = false;
+            }
+        }
+        return res;
+    }
+
+    private boolean matchRecipient(Cursor c, FilterInfo fi, BluetoothMapAppParams ap) {
+        boolean res;
+        String recip = ap.getFilterRecipient();
+        if (recip != null && recip.length() > 0) {
+            recip = recip.replace("*", ".*");
+            recip = ".*" + recip + ".*";
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                res = matchRecipientSms(c, fi, recip);
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                res = matchRecipientMms(c, fi, recip);
+            } else {
+                if (D) Log.d(TAG, "Unknown msg type: " + fi.msgType);
+                res = false;
+            }
+        } else {
+            res = true;
+        }
+        return res;
+    }
+
+    private boolean matchOriginatorMms(Cursor c, FilterInfo fi, String orig) {
+        boolean res;
+        long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+        String phone = getAddressMms(mResolver, id, MMS_FROM);
+        if (phone != null && phone.length() > 0) {
+            if (phone.matches(orig)) {
+                if (D) Log.d(TAG, "match originator phone = " + phone);
+                res = true;
+            } else {
+                String name = getContactNameFromPhone(phone);
+                if (name != null && name.length() > 0 && name.matches(orig)) {
+                    if (D) Log.d(TAG, "match originator name = " + name);
+                    res = true;
+                } else {
+                    res = false;
+                }
+            }
+        } else {
+            res = false;
+        }
+        return res;
+    }
+
+    private boolean matchOriginatorSms(Cursor c, FilterInfo fi, String orig) {
+        boolean res;
+        int msgType = c.getInt(c.getColumnIndex(Sms.TYPE));
+        if (msgType == 1) {
+            String phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
+            if (phone !=null && phone.length() > 0) {
+                if (phone.matches(orig)) {
+                    if (D) Log.d(TAG, "match originator phone = " + phone);
+                    res = true;
+                } else {
+                    String name = getContactNameFromPhone(phone);
+                    if (name != null && name.length() > 0 && name.matches(orig)) {
+                        if (D) Log.d(TAG, "match originator name = " + name);
+                        res = true;
+                    } else {
+                        res = false;
+                    }
+                }
+            } else {
+                res = false;
+            }
+        }
+        else {
+            String phone = fi.phoneNum;
+            String name = fi.phoneAlphaTag;
+            if (phone != null && phone.length() > 0 && phone.matches(orig)) {
+                if (D) Log.d(TAG, "match originator phone = " + phone);
+                res = true;
+            } else if (name != null && name.length() > 0 && name.matches(orig)) {
+                if (D) Log.d(TAG, "match originator name = " + name);
+                res = true;
+            } else {
+                res = false;
+            }
+        }
+        return res;
+    }
+
+   private boolean matchOriginator(Cursor c, FilterInfo fi, BluetoothMapAppParams ap) {
+        boolean res;
+        String orig = ap.getFilterOriginator();
+        if (orig != null && orig.length() > 0) {
+            orig = orig.replace("*", ".*");
+            orig = ".*" + orig + ".*";
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+                res = matchOriginatorSms(c, fi, orig);
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                res = matchOriginatorMms(c, fi, orig);
+            } else {
+                Log.d(TAG, "Unknown msg type: " + fi.msgType);
+                res = false;
+            }
+        } else {
+            res = true;
+        }
+        return res;
+    }
+
+    private boolean matchAddresses(Cursor c, FilterInfo fi, BluetoothMapAppParams ap) {
+        if (matchOriginator(c, fi, ap) && matchRecipient(c, fi, ap)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private String setWhereFilterFolderTypeSms(String folder) {
+        String where = "";
+        if ("inbox".equalsIgnoreCase(folder)) {
+            where = "type = 1 AND thread_id <> -1";
+        }
+        else if ("outbox".equalsIgnoreCase(folder)) {
+            where = "(type = 4 OR type = 5 OR type = 6) AND thread_id <> -1";
+        }
+        else if ("sent".equalsIgnoreCase(folder)) {
+            where = "type = 2 AND thread_id <> -1";
+        }
+        else if ("draft".equalsIgnoreCase(folder)) {
+            where = "type = 3 AND thread_id <> -1";
+        }
+        else if ("deleted".equalsIgnoreCase(folder)) {
+            where = "thread_id = -1";
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterFolderTypeMms(String folder) {
+        String where = "";
+        if ("inbox".equalsIgnoreCase(folder)) {
+            where = "msg_box = 1 AND thread_id <> -1";
+        }
+        else if ("outbox".equalsIgnoreCase(folder)) {
+            where = "msg_box = 4 AND thread_id <> -1";
+        }
+        else if ("sent".equalsIgnoreCase(folder)) {
+            where = "msg_box = 2 AND thread_id <> -1";
+        }
+        else if ("draft".equalsIgnoreCase(folder)) {
+            where = "msg_box = 3 AND thread_id <> -1";
+        }
+        else if ("deleted".equalsIgnoreCase(folder)) {
+            where = "thread_id = -1";
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterFolderType(String folder, FilterInfo fi) {
+        String where = "";
+        if (fi.msgType == FilterInfo.TYPE_SMS) {
+            where = setWhereFilterFolderTypeSms(folder);
+        } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+            where = setWhereFilterFolderTypeMms(folder);
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterReadStatus(BluetoothMapAppParams ap) {
+        String where = "";
+        if (ap.getFilterReadStatus() != -1) {
+            if ((ap.getFilterReadStatus() & 0x01) != 0) {
+                where = " AND read=0 ";
+            }
+
+            if ((ap.getFilterReadStatus() & 0x02) != 0) {
+                where = " AND read=1 ";
+            }
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterPeriod(BluetoothMapAppParams ap, FilterInfo fi) {
+        String where = "";
+        if ((ap.getFilterPeriodBegin() != -1)) {
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+            where = " AND date >= " + ap.getFilterPeriodBegin();
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                where = " AND date >= " + (ap.getFilterPeriodBegin() / 1000L);
+            }
+        }
+
+        if ((ap.getFilterPeriodEnd() != -1)) {
+            if (fi.msgType == FilterInfo.TYPE_SMS) {
+            where += " AND date < " + ap.getFilterPeriodEnd();
+            } else if (fi.msgType == FilterInfo.TYPE_MMS) {
+                where += " AND date < " + (ap.getFilterPeriodEnd() / 1000L);
+            }
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterPhones(String str) {
+        String where = "";
+        str = str.replace("*", "%");
+
+        Cursor c = mResolver.query(ContactsContract.Contacts.CONTENT_URI, null,
+            ContactsContract.Contacts.DISPLAY_NAME + " like ?",
+            new String[]{str},
+            ContactsContract.Contacts.DISPLAY_NAME + " ASC");
+
+        while (c != null && c.moveToNext()) {
+            String contactId = c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
+
+            Cursor p = mResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
+                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
+                new String[]{contactId},
+                null);
+
+            while (p != null && p.moveToNext()) {
+                String number = p.getString(
+                    p.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
+
+                where += " address = " + "'" + number + "'";
+                if (!p.isLast()) {
+                    where += " OR ";
+                }
+            }
+            if (!c.isLast()) {
+                where += " OR ";
+            }
+            p.close();
+        }
+        c.close();
+
+        if (str != null && str.length() > 0) {
+            if (where.length() > 0) {
+                where += " OR ";
+            }
+            where += " address like " + "'" + str + "'";
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterOriginator(BluetoothMapAppParams ap,
+        FilterInfo fi) {
+        String where = "";
+        String orig = ap.getFilterOriginator();
+
+        if (orig != null && orig.length() > 0) {
+            String phones = setWhereFilterPhones(orig);
+
+            if (phones.length() > 0) {
+                where = " AND ((type <> 1) OR ( " + phones + " ))";
+            } else {
+                where = " AND (type <> 1)";
+            }
+
+            orig = orig.replace("*", ".*");
+            orig = ".*" + orig + ".*";
+
+            boolean localPhoneMatchOrig = false;
+            if (fi.phoneNum != null && fi.phoneNum.length() > 0
+                && fi.phoneNum.matches(orig)) {
+                localPhoneMatchOrig = true;
+            }
+
+            if (fi.phoneAlphaTag != null && fi.phoneAlphaTag.length() > 0
+                && fi.phoneAlphaTag.matches(orig)) {
+                localPhoneMatchOrig = true;
+            }
+
+            if (!localPhoneMatchOrig) {
+                where += " AND (type = 1)";
+            }
+        }
+
+        return where;
+    }
+
+    private String setWhereFilterRecipient(BluetoothMapAppParams ap,
+        FilterInfo fi) {
+        String where = "";
+        String recip = ap.getFilterRecipient();
+
+        if (recip != null && recip.length() > 0) {
+            String phones = setWhereFilterPhones(recip);
+
+            if (phones.length() > 0) {
+                where = " AND ((type = 1) OR ( " + phones + " ))";
+            } else {
+                where = " AND (type = 1)";
+            }
+
+            recip = recip.replace("*", ".*");
+            recip = ".*" + recip + ".*";
+
+            boolean localPhoneMatchOrig = false;
+            if (fi.phoneNum != null && fi.phoneNum.length() > 0
+                && fi.phoneNum.matches(recip)) {
+                localPhoneMatchOrig = true;
+            }
+
+            if (fi.phoneAlphaTag != null && fi.phoneAlphaTag.length() > 0
+                && fi.phoneAlphaTag.matches(recip)) {
+                localPhoneMatchOrig = true;
+            }
+
+            if (!localPhoneMatchOrig) {
+                where += " AND (type <> 1)";
+            }
+        }
+
+        return where;
+    }
+
+    private String setWhereFilter(String folder, FilterInfo fi, BluetoothMapAppParams ap) {
+        String where = "";
+
+        where += setWhereFilterFolderType(folder, fi);
+        where += setWhereFilterReadStatus(ap);
+        where += setWhereFilterPeriod(ap, fi);
+        /* where += setWhereFilterOriginator(ap, fi); */
+        /* where += setWhereFilterRecipient(ap, fi); */
+
+        if (D) Log.d(TAG, "where: " + where);
+
+        return where;
+    }
+
+    private boolean smsSelected(FilterInfo fi, BluetoothMapAppParams ap) {
+        int msgType = ap.getFilterMessageType();
+        int phoneType = fi.phoneType;
+
+        if (msgType == -1)
+            return true;
+        if ((msgType & 0x03) == 0)
+            return true;
+
+        if (((msgType & 0x01) == 0) && (phoneType == TelephonyManager.PHONE_TYPE_GSM))
+            return true;
+
+        if (((msgType & 0x02) == 0) && (phoneType == TelephonyManager.PHONE_TYPE_CDMA))
+            return true;
+
+        return false;
+    }
+
+    private boolean mmsSelected(FilterInfo fi, BluetoothMapAppParams ap) {
+        int msgType = ap.getFilterMessageType();
+
+        if (msgType == -1)
+            return true;
+
+        if ((msgType & 0x08) == 0)
+            return true;
+
+        return false;
+    }
+
+    private void setFilterInfo(FilterInfo fi) {
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        if (tm != null) {
+            fi.phoneType = tm.getPhoneType();
+            fi.phoneNum = tm.getLine1Number();
+            fi.phoneAlphaTag = tm.getLine1AlphaTag();
+            if (D) Log.d(TAG, "phone type = " + fi.phoneType +
+                " phone num = " + fi.phoneNum +
+                " phone alpha tag = " + fi.phoneAlphaTag);
+        }
+    }
+
+    public BluetoothMapMessageListing msgListing(String folder, BluetoothMapAppParams ap) {
+        Log.d(TAG, "msgListing: folder = " + folder);
+        BluetoothMapMessageListing bmList = new BluetoothMapMessageListing();
+        BluetoothMapMessageListingElement e = null;
+
+        /* Cache some info used throughout filtering */
+        FilterInfo fi = new FilterInfo();
+        setFilterInfo(fi);
+
+        if (smsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_SMS;
+
+            String where = setWhereFilter(folder, fi, ap);
+
+            Cursor c = mResolver.query(Sms.CONTENT_URI,
+                SMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                while (c.moveToNext()) {
+                    if (matchAddresses(c, fi, ap)) {
+                        printSms(c);
+                        e = element(c, fi, ap);
+                        bmList.add(e);
+                    }
+                }
+                c.close();
+            }
+        }
+
+        if (mmsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_MMS;
+
+            String where = setWhereFilter(folder, fi, ap);
+
+            Cursor c = mResolver.query(Mms.CONTENT_URI,
+                MMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                int cnt = 0;
+                while (c.moveToNext()) {
+                    if (matchAddresses(c, fi, ap)) {
+                        printMms(c);
+                        e = element(c, fi, ap);
+                        bmList.add(e);
+                    }
+                }
+                c.close();
+            }
+        }
+
+        /* Enable this if post sorting and segmenting needed */
+        bmList.sort();
+        bmList.segment(ap.getMaxListCount(), ap.getStartOffset());
+
+        return bmList;
+    }
+
+    public int msgListingSize(String folder, BluetoothMapAppParams ap) {
+        if (D) Log.d(TAG, "msgListingSize: folder = " + folder);
+        int cnt = 0;
+
+        /* Cache some info used throughout filtering */
+        FilterInfo fi = new FilterInfo();
+        setFilterInfo(fi);
+
+        if (smsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_SMS;
+            String where = setWhereFilter(folder, fi, ap);
+            Cursor c = mResolver.query(Sms.CONTENT_URI,
+                SMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                cnt = c.getCount();
+                c.close();
+            }
+        }
+
+        if (mmsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_MMS;
+            String where = setWhereFilter(folder, fi, ap);
+            Cursor c = mResolver.query(Mms.CONTENT_URI,
+                MMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                cnt += c.getCount();
+                c.close();
+            }
+        }
+
+        if (D) Log.d(TAG, "msgListingSize: size = " + cnt);
+        return cnt;
+    }
+    /**
+     * Return true if there are unread messages in the requested list of messages
+     * @param folder folder where the message listing should come from
+     * @param ap application parameter object
+     * @return true if unread messages are in the list, else false
+     */
+    public boolean msgListingHasUnread(String folder, BluetoothMapAppParams ap) {
+        if (D) Log.d(TAG, "msgListingHasUnread: folder = " + folder);
+        int cnt = 0;
+
+        /* Cache some info used throughout filtering */
+        FilterInfo fi = new FilterInfo();
+        setFilterInfo(fi);
+
+        if (smsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_SMS;
+            String where = setWhereFilterFolderType(folder, fi);
+            where += " AND read=0 ";
+            where += setWhereFilterPeriod(ap, fi);
+            Cursor c = mResolver.query(Sms.CONTENT_URI,
+                SMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                cnt = c.getCount();
+                c.close();
+            }
+        }
+
+        if (mmsSelected(fi, ap)) {
+            fi.msgType = FilterInfo.TYPE_MMS;
+            String where = setWhereFilterFolderType(folder, fi);
+            where += " AND read=0 ";
+            where += setWhereFilterPeriod(ap, fi);
+            Cursor c = mResolver.query(Mms.CONTENT_URI,
+                MMS_PROJECTION, where, null, "date DESC");
+
+            if (c != null) {
+                cnt += c.getCount();
+                c.close();
+            }
+        }
+
+        if (D) Log.d(TAG, "msgListingHasUnread: numUnread = " + cnt);
+        return (cnt>0)?true:false;
+    }
+
+    /**
+     * Get the folder name of an SMS message or MMS message.
+     * @param c the cursor pointing at the message
+     * @return the folder name.
+     */
+    private String getFolderName(int type, int threadId) {
+
+        if(threadId == -1)
+            return "deleted";
+
+        switch(type) {
+        case 1:
+            return "inbox";
+        case 2:
+            return "sent";
+        case 3:
+            return "draft";
+        case 4: // Just name outbox, failed and queued "outbox"
+        case 5:
+        case 6:
+            return "outbox";
+        }
+        return "";
+    }
+
+    public byte[] getMessage(String handle, BluetoothMapAppParams appParams) throws UnsupportedEncodingException{
+        TYPE type = BluetoothMapUtils.getMsgTypeFromHandle(handle);
+        long id = BluetoothMapUtils.getCpHandle(handle);
+        switch(type) {
+        case SMS_GSM:
+        case SMS_CDMA:
+            return getSmsMessage(id, appParams.getCharset());
+        case MMS:
+            return getMmsMessage(id, appParams);
+        case EMAIL:
+            throw new IllegalArgumentException("Email not implemented - invalid message handle.");
+        }
+        throw new IllegalArgumentException("Invalid message handle.");
+    }
+
+    private void setVCardFromPhoneNumber(BluetoothMapbMessage message, String phone, boolean incoming) {
+        String contactId = null, contactName = null;
+        String[] phoneNumbers = null;
+        String[] emailAddresses = null;
+        Cursor p;
+
+        Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+                Uri.encode(phone));
+
+        String[] projection = {Contacts._ID, Contacts.DISPLAY_NAME};
+        String selection = Contacts.IN_VISIBLE_GROUP + "=1";
+        String orderBy = Contacts._ID + " ASC";
+
+        // Get the contact _ID and name
+        p = mResolver.query(uri, projection, selection, null, orderBy);
+        if (p != null && p.getCount() >= 1) {
+            p.moveToFirst();
+            contactId = p.getString(p.getColumnIndex(Contacts._ID));
+            contactName = p.getString(p.getColumnIndex(Contacts.DISPLAY_NAME));
+        }
+        p.close();
+
+        // Bail out if we are unable to find a contact, based on the phone number
+        if(contactId == null) {
+            phoneNumbers = new String[1];
+            phoneNumbers[0] = phone;
+        }
+        else {
+            // Fetch all contact phone numbers
+            p = mResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
+                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
+                new String[]{contactId},
+                null);
+            if(p != null) {
+                int i = 0;
+                phoneNumbers = new String[p.getCount()];
+                while (p != null && p.moveToNext()) {
+                    String number = p.getString(
+                        p.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
+                    phoneNumbers[i++] = number;
+                }
+                p.close();
+            }
+
+            // Fetch contact e-mail addresses
+            p = mResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
+                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
+                    new String[]{contactId},
+                    null);
+            if(p != null) {
+                int i = 0;
+                emailAddresses = new String[p.getCount()];
+                while (p != null && p.moveToNext()) {
+                    String emailAddress = p.getString(
+                        p.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));
+                    emailAddresses[i++] = emailAddress;
+                }
+                p.close();
+            }
+        }
+        if(incoming == true)
+            message.addOriginator(contactName, contactName, phoneNumbers, emailAddresses); // Use version 3.0 as we only have a formatted name
+        else
+            message.addRecipient(contactName, contactName, phoneNumbers, emailAddresses); // Use version 3.0 as we only have a formatted name
+    }
+
+    public static final int MAP_MESSAGE_CHARSET_NATIVE = 0;
+    public static final int MAP_MESSAGE_CHARSET_UTF8 = 1;
+
+    public byte[] getSmsMessage(long id, int charset) throws UnsupportedEncodingException{
+        int type, threadId;
+        long time = -1;
+        String msgBody;
+        BluetoothMapbMessageSms message = new BluetoothMapbMessageSms();
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, "_ID = " + id, null, null);
+
+        if(c != null && c.moveToFirst())
+        {
+
+            if(V) Log.d(TAG,"c.count: " + c.getCount());
+
+            if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
+                message.setType(TYPE.SMS_GSM);
+            } else if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
+                message.setType(TYPE.SMS_CDMA);
+            }
+
+            String read = c.getString(c.getColumnIndex(Sms.READ));
+            if (read.equalsIgnoreCase("1"))
+                message.setStatus(true);
+            else
+                message.setStatus(false);
+
+            type = c.getInt(c.getColumnIndex(Sms.TYPE));
+            threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
+            message.setFolder(getFolderName(type, threadId));
+
+            msgBody = c.getString(c.getColumnIndex(Sms.BODY));
+
+            String phone = c.getString(c.getColumnIndex(Sms.ADDRESS));
+
+            time = c.getLong(c.getColumnIndex(Sms.DATE));
+            if(type == 1) // Inbox message needs to set the vCard as originator
+                setVCardFromPhoneNumber(message, phone, true);
+            else          // Other messages sets the vCard as the recipient
+                setVCardFromPhoneNumber(message, phone, false);
+
+            if(charset == MAP_MESSAGE_CHARSET_NATIVE) {
+                if(type == 1) //Inbox
+                    message.setSmsBodyPdus(BluetoothMapSmsPdu.getDeliverPdus(msgBody, phone, time));
+                else
+                    message.setSmsBodyPdus(BluetoothMapSmsPdu.getSubmitPdus(msgBody, phone));
+            } else /*if (charset == MAP_MESSAGE_CHARSET_UTF8)*/ {
+                message.setSmsBody(msgBody);
+            }
+
+            c.close();
+
+            return message.encode();
+        }
+        throw new IllegalArgumentException("SMS handle not found");
+    }
+
+    private void extractMmsAddresses(long id, BluetoothMapbMessageMmsEmail message) {
+        final String[] projection = null;
+        String selection = new String("msg_id=" + id);
+        String uriStr = String.format("content://mms/%d/addr", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        Cursor c = mResolver.query(
+            uriAddress,
+            projection,
+            selection,
+            null, null);
+        /* TODO: Change the setVCard...() to return the vCard, and use the name in message.addXxx() */
+        if (c.moveToFirst()) {
+            do {
+                String address = c.getString(c.getColumnIndex("address"));
+                Integer type = c.getInt(c.getColumnIndex("type"));
+                switch(type) {
+                case MMS_FROM:
+                    setVCardFromPhoneNumber(message, address, true);
+                    message.addFrom(null, address);
+                    break;
+                case MMS_TO:
+                    setVCardFromPhoneNumber(message, address, false);
+                    message.addTo(null, address);
+                    break;
+                case MMS_CC:
+                    setVCardFromPhoneNumber(message, address, false);
+                    message.addCc(null, address);
+                    break;
+                case MMS_BCC:
+                    setVCardFromPhoneNumber(message, address, false);
+                    message.addBcc(null, address);
+                default:
+                    break;
+                }
+            } while(c.moveToNext());
+        }
+    }
+
+    /**
+     * Read out a mms data part and return the data in a byte array.
+     * @param partid the content provider id of the mms.
+     * @return
+     */
+    private byte[] readMmsDataPart(long partid) {
+        String uriStr = String.format("content://mms/part/%d", partid);
+        Uri uriAddress = Uri.parse(uriStr);
+        InputStream is = null;
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        int bufferSize = 8192;
+        byte[] buffer = new byte[bufferSize];
+        byte[] retVal = null;
+
+        try {
+            is = mResolver.openInputStream(uriAddress);
+            int len = 0;
+            while ((len = is.read(buffer)) != -1) {
+              os.write(buffer, 0, len); // We need to specify the len, as it can be != bufferSize
+            }
+            retVal = os.toByteArray();
+        } catch (IOException e) {
+            // do nothing for now
+            Log.w(TAG,"Error reading part data",e);
+        } finally {
+            try {
+                os.close();
+                is.close();
+            } catch (IOException e) {
+            }
+        }
+        return retVal;
+    }
+
+    /**
+     * Read out the mms parts and update the bMessage object provided i {@linkplain message}
+     * @param id the content provider ID of the message
+     * @param message the bMessage object to add the information to
+     */
+    private void extractMmsParts(long id, BluetoothMapbMessageMmsEmail message)
+    {
+        /* TODO: If the attachment appParam is set to "no", only add the text parts.
+         * (content type contains "text" - case insensitive) */
+        final String[] projection = null;
+        String selection = new String("mid=" + id);
+        String uriStr = String.format("content://mms/%d/part", id);
+        Uri uriAddress = Uri.parse(uriStr);
+        BluetoothMapbMessageMmsEmail.MimePart part;
+        Cursor c = mResolver.query(
+            uriAddress,
+            projection,
+            selection,
+            null, null);
+
+        if (c.moveToFirst()) {
+            do {
+                Long partId = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String contentType = c.getString(c.getColumnIndex("ct"));
+                String name = c.getString(c.getColumnIndex("name"));
+                String charset = c.getString(c.getColumnIndex("chset"));
+                String filename = c.getString(c.getColumnIndex("fn"));
+                String text = c.getString(c.getColumnIndex("text"));
+                Integer fd = c.getInt(c.getColumnIndex("_data"));
+                String cid = c.getString(c.getColumnIndex("cid"));
+                String cl = c.getString(c.getColumnIndex("cl"));
+                String cdisp = c.getString(c.getColumnIndex("cd"));
+
+                if(D) Log.d(TAG, "     _id : " + partId +
+                        "\n     ct : " + contentType +
+                        "\n     partname : " + name +
+                        "\n     charset : " + charset +
+                        "\n     filename : " + filename +
+                        "\n     text : " + text +
+                        "\n     fd : " + fd +
+                        "\n     cid : " + cid +
+                        "\n     cl : " + cl +
+                        "\n     cdisp : " + cdisp);
+
+                part = message.addMimePart();
+                part.contentType = contentType;
+                part.partName = name;
+                part.contentId = cid;
+                part.contentLocation = cl;
+                part.contentDisposition = cdisp;
+
+                try {
+                    if(text != null) {
+                        part.data = text.getBytes("UTF-8");
+                        part.charsetName = "utf-8";
+                    }
+                    else {
+                        part.data = readMmsDataPart(partId);
+                        if(charset != null)
+                            part.charsetName = CharacterSets.getMimeName(Integer.parseInt(charset));
+                    }
+                } catch (NumberFormatException e) {
+                    Log.d(TAG,"extractMmsParts",e);
+                    part.data = null;
+                    part.charsetName = null;
+                } catch (UnsupportedEncodingException e) {
+                    Log.d(TAG,"extractMmsParts",e);
+                    part.data = null;
+                    part.charsetName = null;
+                } finally {
+                }
+                part.fileName = filename;
+            } while(c.moveToNext());
+        }
+        message.updateCharset();
+    }
+
+    /**
+     *
+     * @param id the content provider id for the message to fetch.
+     * @param appParams The application parameter object received from the client.
+     * @return a byte[] containing the utf-8 encoded bMessage to send to the client.
+     * @throws UnsupportedEncodingException if UTF-8 is not supported,
+     * which is guaranteed to be supported on an android device
+     */
+    public byte[] getMmsMessage(long id, BluetoothMapAppParams appParams) throws UnsupportedEncodingException {
+        int msgBox, threadId;
+        BluetoothMapbMessageMmsEmail message = new BluetoothMapbMessageMmsEmail();
+        Cursor c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION, "_ID = " + id, null, null);
+        if(c != null && c.moveToFirst())
+        {
+            message.setType(TYPE.MMS);
+
+            // The MMS info:
+            String read = c.getString(c.getColumnIndex(Mms.READ));
+            if (read.equalsIgnoreCase("1"))
+                message.setStatus(true);
+            else
+                message.setStatus(false);
+
+            msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+            threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
+            message.setFolder(getFolderName(msgBox, threadId));
+
+            message.setSubject(c.getString(c.getColumnIndex(Mms.SUBJECT)));
+            message.setMessageId(c.getString(c.getColumnIndex(Mms.MESSAGE_ID)));
+            message.setContentType(c.getString(c.getColumnIndex(Mms.CONTENT_TYPE)));
+            message.setDate(c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L);
+            message.setTextOnly(c.getInt(c.getColumnIndex(Mms.TEXT_ONLY)) == 0 ? false : true); // - TODO: Do we need this - yes, if we have only text, we should not make this a multipart message
+            message.setIncludeAttachments(appParams.getAttachment() == 0 ? false : true);
+            // c.getLong(c.getColumnIndex(Mms.DATE_SENT)); - this is never used
+            // c.getInt(c.getColumnIndex(Mms.STATUS)); - don't know what this is
+
+            // The parts
+            extractMmsParts(id, message);
+
+            // The addresses
+            extractMmsAddresses(id, message);
+
+            c.close();
+
+            return message.encode();
+        }
+        else if(c != null) {
+            c.close();
+        }
+
+        throw new IllegalArgumentException("MMS handle not found");
+    }
+
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
new file mode 100644
index 0000000..11ff0ff
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -0,0 +1,1196 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.BaseColumns;
+import android.provider.Telephony;
+import android.provider.Telephony.Mms;
+import android.provider.Telephony.MmsSms;
+import android.provider.Telephony.Sms;
+import android.provider.Telephony.Sms.Inbox;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SmsManager;
+import android.telephony.SmsMessage;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+import com.android.bluetooth.map.BluetoothMapbMessageMmsEmail.MimePart;
+import com.google.android.mms.pdu.PduHeaders;
+
+public class BluetoothMapContentObserver {
+    private static final String TAG = "BluetoothMapContentObserver";
+
+    private static final boolean D = false;
+    private static final boolean V = false;
+
+    private Context mContext;
+    private ContentResolver mResolver;
+    private BluetoothMnsObexClient mMnsClient;
+    private int mMasId;
+
+    public static final int DELETED_THREAD_ID = -1;
+
+    /* X-Mms-Message-Type field types. These are from PduHeaders.java */
+    public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84;
+
+    private TYPE mSmsType;
+
+    static final String[] SMS_PROJECTION = new String[] {
+        BaseColumns._ID,
+        Sms.THREAD_ID,
+        Sms.ADDRESS,
+        Sms.BODY,
+        Sms.DATE,
+        Sms.READ,
+        Sms.TYPE,
+        Sms.STATUS,
+        Sms.LOCKED,
+        Sms.ERROR_CODE,
+    };
+
+    static final String[] MMS_PROJECTION = new String[] {
+        BaseColumns._ID,
+        Mms.THREAD_ID,
+        Mms.MESSAGE_ID,
+        Mms.MESSAGE_SIZE,
+        Mms.SUBJECT,
+        Mms.CONTENT_TYPE,
+        Mms.TEXT_ONLY,
+        Mms.DATE,
+        Mms.DATE_SENT,
+        Mms.READ,
+        Mms.MESSAGE_BOX,
+        Mms.MESSAGE_TYPE,
+        Mms.STATUS,
+    };
+
+    public BluetoothMapContentObserver(final Context context) {
+        mContext = context;
+        mResolver = mContext.getContentResolver();
+
+        mSmsType = getSmsType();
+    }
+
+    private TYPE getSmsType() {
+        TYPE smsType = null;
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+
+        if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
+            smsType = TYPE.SMS_GSM;
+        } else if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) {
+            smsType = TYPE.SMS_CDMA;
+        }
+
+        return smsType;
+    }
+
+    private final ContentObserver mObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            onChange(selfChange, null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (V) Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId()
+                + " Uri: " + uri.toString() + " selfchange: " + selfChange);
+
+            handleMsgListChanges();
+        }
+    };
+
+    private static final String folderSms[] = {
+        "",
+        "inbox",
+        "sent",
+        "draft",
+        "outbox",
+        "outbox",
+        "outbox",
+        "inbox",
+        "inbox",
+    };
+
+    private static final String folderMms[] = {
+        "",
+        "inbox",
+        "sent",
+        "draft",
+        "outbox",
+    };
+
+    private class Event {
+        String eventType;
+        long handle;
+        String folder;
+        String oldFolder;
+        TYPE msgType;
+
+        public Event(String eventType, long handle, String folder,
+            String oldFolder, TYPE msgType) {
+            String PATH = "telecom/msg/";
+            this.eventType = eventType;
+            this.handle = handle;
+            if (folder != null) {
+                this.folder = PATH + folder;
+            } else {
+                this.folder = null;
+            }
+            if (oldFolder != null) {
+                this.oldFolder = PATH + oldFolder;
+            } else {
+                this.oldFolder = null;
+            }
+            this.msgType = msgType;
+        }
+
+        public byte[] encode() throws UnsupportedEncodingException {
+            StringWriter sw = new StringWriter();
+            XmlSerializer xmlEvtReport = Xml.newSerializer();
+            try {
+                xmlEvtReport.setOutput(sw);
+                xmlEvtReport.startDocument(null, null);
+                xmlEvtReport.text("\n");
+                xmlEvtReport.startTag("", "MAP-event-report");
+                xmlEvtReport.attribute("", "version", "1.0");
+
+                xmlEvtReport.startTag("", "event");
+                xmlEvtReport.attribute("", "type", eventType);
+                xmlEvtReport.attribute("", "handle", BluetoothMapUtils.getMapHandle(handle, msgType));
+                if (folder != null) {
+                    xmlEvtReport.attribute("", "folder", folder);
+                }
+                if (oldFolder != null) {
+                    xmlEvtReport.attribute("", "old_folder", oldFolder);
+                }
+                xmlEvtReport.attribute("", "msg_type", msgType.name());
+                xmlEvtReport.endTag("", "event");
+
+                xmlEvtReport.endTag("", "MAP-event-report");
+                xmlEvtReport.endDocument();
+            } catch (IllegalArgumentException e) {
+                e.printStackTrace();
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            if (V) System.out.println(sw.toString());
+
+            return sw.toString().getBytes("UTF-8");
+        }
+    }
+
+    private class Msg {
+        long id;
+        int type;
+
+        public Msg(long id, int type) {
+            this.id = id;
+            this.type = type;
+        }
+    }
+
+    private Map<Long, Msg> mMsgListSms =
+        Collections.synchronizedMap(new HashMap<Long, Msg>());
+
+    private Map<Long, Msg> mMsgListMms =
+        Collections.synchronizedMap(new HashMap<Long, Msg>());
+
+    public void registerObserver(BluetoothMnsObexClient mns, int masId) {
+        if (V) Log.d(TAG, "registerObserver");
+        /* Use MmsSms Uri since the Sms Uri is not notified on deletes */
+        mMasId = masId;
+        mMnsClient = mns;
+        mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver);
+        initMsgList();
+    }
+
+    public void unregisterObserver() {
+        if (V) Log.d(TAG, "unregisterObserver");
+        mResolver.unregisterContentObserver(mObserver);
+        mMnsClient = null;
+    }
+
+    private void sendEvent(Event evt) {
+        Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " "
+        + evt.folder + " " + evt.oldFolder + " " + evt.msgType.name());
+
+        if (mMnsClient == null) {
+            Log.d(TAG, "sendEvent: No MNS client registered - don't send event");
+            return;
+        }
+
+        try {
+            mMnsClient.sendEvent(evt.encode(), mMasId);
+        } catch (UnsupportedEncodingException ex) {
+            /* do nothing */
+        }
+    }
+
+    private void initMsgList() {
+        if (V) Log.d(TAG, "initMsgList");
+
+        mMsgListSms.clear();
+        mMsgListMms.clear();
+
+        HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
+
+        Cursor c = mResolver.query(Sms.CONTENT_URI,
+            SMS_PROJECTION, null, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            do {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                int type = c.getInt(c.getColumnIndex(Sms.TYPE));
+
+                Msg msg = new Msg(id, type);
+                msgListSms.put(id, msg);
+            } while (c.moveToNext());
+            c.close();
+        }
+
+        mMsgListSms = msgListSms;
+
+        HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();
+
+        c = mResolver.query(Mms.CONTENT_URI,
+            MMS_PROJECTION, null, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            do {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+
+                Msg msg = new Msg(id, type);
+                msgListMms.put(id, msg);
+            } while (c.moveToNext());
+            c.close();
+        }
+
+        mMsgListMms = msgListMms;
+    }
+
+    private void handleMsgListChangesSms() {
+        if (V) Log.d(TAG, "handleMsgListChangesSms");
+
+        HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
+
+        Cursor c = mResolver.query(Sms.CONTENT_URI,
+            SMS_PROJECTION, null, null, null);
+
+        synchronized(mMsgListSms) {
+            if (c != null && c.moveToFirst()) {
+                do {
+                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                    int type = c.getInt(c.getColumnIndex(Sms.TYPE));
+
+                    Msg msg = mMsgListSms.remove(id);
+
+                    if (msg == null) {
+                        /* New message */
+                        msg = new Msg(id, type);
+                        msgListSms.put(id, msg);
+
+                        if (folderSms[type].equals("inbox")) {
+                            Event evt = new Event("NewMessage", id, folderSms[type],
+                                null, mSmsType);
+                            sendEvent(evt);
+                        }
+                    } else {
+                        /* Existing message */
+                        if (type != msg.type) {
+                            Log.d(TAG, "new type: " + type + " old type: " + msg.type);
+                            Event evt = new Event("MessageShift", id, folderSms[type],
+                                folderSms[msg.type], mSmsType);
+                            sendEvent(evt);
+                            msg.type = type;
+                        }
+                        msgListSms.put(id, msg);
+                    }
+                } while (c.moveToNext());
+                c.close();
+            }
+
+            for (Msg msg : mMsgListSms.values()) {
+                Event evt = new Event("MessageDeleted", msg.id, "deleted",
+                    folderSms[msg.type], mSmsType);
+                sendEvent(evt);
+            }
+
+            mMsgListSms = msgListSms;
+        }
+    }
+
+    private void handleMsgListChangesMms() {
+        if (V) Log.d(TAG, "handleMsgListChangesMms");
+
+        HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>();
+
+        Cursor c = mResolver.query(Mms.CONTENT_URI,
+            MMS_PROJECTION, null, null, null);
+
+        synchronized(mMsgListMms) {
+            if (c != null && c.moveToFirst()) {
+                do {
+                    long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                    int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+                    int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE));
+
+                    Msg msg = mMsgListMms.remove(id);
+
+                    if (msg == null) {
+                        /* New message - only notify on retrieve conf */
+                        if (folderMms[type].equals("inbox") &&
+                            mtype != MESSAGE_TYPE_RETRIEVE_CONF) {
+                                continue;
+                        }
+
+                        msg = new Msg(id, type);
+                        msgListMms.put(id, msg);
+
+                        if (folderMms[type].equals("inbox")) {
+                            Event evt = new Event("NewMessage", id, folderMms[type],
+                                null, TYPE.MMS);
+                            sendEvent(evt);
+                        }
+                    } else {
+                        /* Existing message */
+                        if (type != msg.type) {
+                            Log.d(TAG, "new type: " + type + " old type: " + msg.type);
+                            Event evt = new Event("MessageShift", id, folderMms[type],
+                                folderMms[msg.type], TYPE.MMS);
+                            sendEvent(evt);
+                            msg.type = type;
+
+                            if (folderMms[type].equals("sent")) {
+                                evt = new Event("SendingSuccess", id,
+                                    folderSms[type], null, TYPE.MMS);
+                                sendEvent(evt);
+                            }
+                        }
+                        msgListMms.put(id, msg);
+                    }
+                } while (c.moveToNext());
+                c.close();
+            }
+
+            for (Msg msg : mMsgListMms.values()) {
+                Event evt = new Event("MessageDeleted", msg.id, "deleted",
+                    folderMms[msg.type], TYPE.MMS);
+                sendEvent(evt);
+            }
+
+            mMsgListMms = msgListMms;
+        }
+    }
+
+    private void handleMsgListChanges() {
+        handleMsgListChangesSms();
+        handleMsgListChangesMms();
+    }
+
+    private boolean deleteMessageMms(long handle) {
+        boolean res = false;
+        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
+        Cursor c = mResolver.query(uri, null, null, null, null);
+        if (c != null && c.moveToFirst()) {
+            /* Move to deleted folder, or delete if already in deleted folder */
+            int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
+            if (threadId != DELETED_THREAD_ID) {
+                /* Set deleted thread id */
+                ContentValues contentValues = new ContentValues();
+                contentValues.put(Mms.THREAD_ID, DELETED_THREAD_ID);
+                mResolver.update(uri, contentValues, null, null);
+            } else {
+                /* Delete from observer message list to avoid delete notifications */
+                mMsgListMms.remove(handle);
+                /* Delete message */
+                mResolver.delete(uri, null, null);
+            }
+            res = true;
+        }
+        if (c != null) {
+            c.close();
+        }
+        return res;
+    }
+
+    private void updateThreadIdMms(Uri uri, long threadId) {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Mms.THREAD_ID, threadId);
+        mResolver.update(uri, contentValues, null, null);
+    }
+
+    private boolean unDeleteMessageMms(long handle) {
+        boolean res = false;
+        Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
+        Cursor c = mResolver.query(uri, null, null, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
+            if (threadId == DELETED_THREAD_ID) {
+                /* Restore thread id from address, or if no thread for address
+                 * create new thread by insert and remove of fake message */
+                String address;
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+                if (msgBox == Mms.MESSAGE_BOX_INBOX) {
+                    address = BluetoothMapContent.getAddressMms(mResolver, id,
+                        BluetoothMapContent.MMS_FROM);
+                } else {
+                    address = BluetoothMapContent.getAddressMms(mResolver, id,
+                        BluetoothMapContent.MMS_TO);
+                }
+                Set<String> recipients = new HashSet<String>();
+                recipients.addAll(Arrays.asList(address));
+                updateThreadIdMms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients));
+            } else {
+                Log.d(TAG, "Message not in deleted folder: handle " + handle
+                    + " threadId " + threadId);
+            }
+            res = true;
+        }
+        if (c != null) {
+            c.close();
+        }
+        return res;
+    }
+
+    private boolean deleteMessageSms(long handle) {
+        boolean res = false;
+        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
+        Cursor c = mResolver.query(uri, null, null, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            /* Move to deleted folder, or delete if already in deleted folder */
+            int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
+            if (threadId != DELETED_THREAD_ID) {
+                /* Set deleted thread id */
+                ContentValues contentValues = new ContentValues();
+                contentValues.put(Sms.THREAD_ID, DELETED_THREAD_ID);
+                mResolver.update(uri, contentValues, null, null);
+            } else {
+                /* Delete from observer message list to avoid delete notifications */
+                mMsgListSms.remove(handle);
+                /* Delete message */
+                mResolver.delete(uri, null, null);
+            }
+            res = true;
+        }
+        if (c != null) {
+            c.close();
+        }
+        return res;
+    }
+
+    private void updateThreadIdSms(Uri uri, long threadId) {
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(Sms.THREAD_ID, threadId);
+        mResolver.update(uri, contentValues, null, null);
+    }
+
+    private boolean unDeleteMessageSms(long handle) {
+        boolean res = false;
+        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
+        Cursor c = mResolver.query(uri, null, null, null, null);
+
+        if (c != null && c.moveToFirst()) {
+            int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
+            if (threadId == DELETED_THREAD_ID) {
+                String address = c.getString(c.getColumnIndex(Sms.ADDRESS));
+                Set<String> recipients = new HashSet<String>();
+                recipients.addAll(Arrays.asList(address));
+                updateThreadIdSms(uri, Telephony.Threads.getOrCreateThreadId(mContext, recipients));
+            } else {
+                Log.d(TAG, "Message not in deleted folder: handle " + handle
+                    + " threadId " + threadId);
+            }
+            res = true;
+        }
+        if (c != null) {
+            c.close();
+        }
+        return res;
+    }
+
+    public boolean setMessageStatusDeleted(long handle, TYPE type, int statusValue) {
+        boolean res = false;
+        if (D) Log.d(TAG, "setMessageStatusDeleted: handle " + handle
+            + " type " + type + " value " + statusValue);
+
+        if (statusValue == BluetoothMapAppParams.STATUS_VALUE_YES) {
+            if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
+                res = deleteMessageSms(handle);
+            } else if (type == TYPE.MMS) {
+                res = deleteMessageMms(handle);
+            }
+        } else if (statusValue == BluetoothMapAppParams.STATUS_VALUE_NO) {
+            if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
+                res = unDeleteMessageSms(handle);
+            } else if (type == TYPE.MMS) {
+                res = unDeleteMessageMms(handle);
+            }
+        }
+        return res;
+    }
+
+    public boolean setMessageStatusRead(long handle, TYPE type, int statusValue) {
+        boolean res = true;
+
+        if (D) Log.d(TAG, "setMessageStatusRead: handle " + handle
+            + " type " + type + " value " + statusValue);
+
+        /* Approved MAP spec errata 3445 states that read status initiated */
+        /* by the MCE shall change the MSE read status. */
+
+        if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
+            Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
+            Cursor c = mResolver.query(uri, null, null, null, null);
+
+            ContentValues contentValues = new ContentValues();
+            contentValues.put(Sms.READ, statusValue);
+            mResolver.update(uri, contentValues, null, null);
+        } else if (type == TYPE.MMS) {
+            Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
+            Cursor c = mResolver.query(uri, null, null, null, null);
+
+            ContentValues contentValues = new ContentValues();
+            contentValues.put(Mms.READ, statusValue);
+            mResolver.update(uri, contentValues, null, null);
+        }
+
+        return res;
+    }
+
+    private class PushMsgInfo {
+        long id;
+        int transparent;
+        int retry;
+        String phone;
+        Uri uri;
+        int parts;
+        int partsSent;
+        int partsDelivered;
+        boolean resend;
+
+        public PushMsgInfo(long id, int transparent,
+            int retry, String phone, Uri uri) {
+            this.id = id;
+            this.transparent = transparent;
+            this.retry = retry;
+            this.phone = phone;
+            this.uri = uri;
+            this.resend = false;
+        };
+    }
+
+    private Map<Long, PushMsgInfo> mPushMsgList =
+        Collections.synchronizedMap(new HashMap<Long, PushMsgInfo>());
+
+    public long pushMessage(BluetoothMapbMessage msg, String folder,
+        BluetoothMapAppParams ap) throws IllegalArgumentException {
+        if (D) Log.d(TAG, "pushMessage");
+        ArrayList<BluetoothMapbMessage.vCard> recipientList = msg.getRecipients();
+        int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ?
+                0 : ap.getTransparent();
+        int retry = ap.getRetry();
+        int charset = ap.getCharset();
+        long handle = -1;
+
+        if (recipientList == null) {
+            Log.d(TAG, "empty recipient list");
+            return -1;
+        }
+
+        for (BluetoothMapbMessage.vCard recipient : recipientList) {
+            if(recipient.getEnvLevel() == 0) // Only send the message to the top level recipient
+            {
+                /* Only send to first address */
+                String phone = recipient.getFirstPhoneNumber();
+                boolean read = false;
+                boolean deliveryReport = true;
+
+                switch(msg.getType()){
+                    case MMS:
+                    {
+                        /* Send message if folder is outbox */
+                        /* to do, support MMS in the future */
+                        /*
+                        if (folder.equals("outbox")) {
+                           handle = sendMmsMessage(folder, phone, (BluetoothMapbMessageMmsEmail)msg);
+                        }
+                        */
+                        break;
+                    }
+                    case SMS_GSM: //fall-through
+                    case SMS_CDMA:
+                    {
+                        /* Add the message to the database */
+                        String msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody();
+                        Uri contentUri = Uri.parse("content://sms/" + folder);
+                        Uri uri = Sms.addMessageToUri(mResolver, contentUri, phone, msgBody,
+                            "", System.currentTimeMillis(), read, deliveryReport);
+
+                        if (uri == null) {
+                            Log.d(TAG, "pushMessage - failure on add to uri " + contentUri);
+                            return -1;
+                        }
+
+                        handle = Long.parseLong(uri.getLastPathSegment());
+
+                        /* Send message if folder is outbox */
+                        if (folder.equals("outbox")) {
+                            PushMsgInfo msgInfo = new PushMsgInfo(handle, transparent,
+                                retry, phone, uri);
+                            mPushMsgList.put(handle, msgInfo);
+                            sendMessage(msgInfo, msgBody);
+                        }
+                        break;
+                    }
+                    case EMAIL:
+                    {
+                        break;
+                    }
+                }
+
+            }
+        }
+
+        /* If multiple recipients return handle of last */
+        return handle;
+    }
+
+
+
+    public long sendMmsMessage(String folder,String to_address, BluetoothMapbMessageMmsEmail msg) {
+        /*
+         *strategy:
+         *1) parse message into parts
+         *if folder is outbox/drafts:
+         *2) push message to draft
+         *if folder is outbox:
+         *3) move message to outbox (to trigger the mms app to add msg to pending_messages list)
+         *4) send intent to mms app in order to wake it up.
+         *else if folder !outbox:
+         *1) push message to folder
+         * */
+        if (folder != null && (folder.equalsIgnoreCase("outbox")||  folder.equalsIgnoreCase("drafts"))) {
+            long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, to_address, msg);
+            /* if invalid handle (-1) then just return the handle - else continue sending (if folder is outbox) */
+            if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && folder.equalsIgnoreCase("outbox")) {
+                moveDraftToOutbox(handle);
+
+                Intent sendIntent = new Intent("android.intent.action.MMS_SEND_OUTBOX_MSG");
+                Log.d(TAG, "broadcasting intent: "+sendIntent.toString());
+                mContext.sendBroadcast(sendIntent);
+            }
+            return handle;
+        } else {
+            /* not allowed to push mms to anything but outbox/drafts */
+            throw  new IllegalArgumentException("Cannot push message to other folders than outbox/drafts");
+        }
+
+    }
+
+
+    private void moveDraftToOutbox(long handle) {
+        ContentResolver contentResolver = mContext.getContentResolver();
+        /*Move message by changing the msg_box value in the content provider database */
+        if (handle != -1) {
+            String whereClause = " _id= " + handle;
+            Uri uri = Uri.parse("content://mms");
+            Cursor queryResult = contentResolver.query(uri, null, whereClause, null, null);
+            if (queryResult != null) {
+                if (queryResult.getCount() > 0) {
+                    queryResult.moveToFirst();
+                    ContentValues data = new ContentValues();
+                    /* set folder to be outbox */
+                    data.put("msg_box", Mms.MESSAGE_BOX_OUTBOX);
+                    contentResolver.update(uri, data, whereClause, null);
+                    Log.d(TAG, "moved draft MMS to outbox");
+                }
+                queryResult.close();
+            }else {
+                Log.d(TAG, "Could not move draft to outbox ");
+            }
+        }
+    }
+    private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMmsEmail msg) {
+        /**
+         * strategy:
+         * 1) parse msg into parts + header
+         * 2) create thread id (abuse the ease of adding an SMS to get id for thread)
+         * 3) push parts into content://mms/parts/ table
+         * 3)
+         */
+
+        ContentValues values = new ContentValues();
+        values.put("msg_box", folder);
+
+        values.put("read", 0);
+        values.put("seen", 0);
+        values.put("sub", msg.getSubject());
+        values.put("sub_cs", 106);
+        values.put("ct_t", "application/vnd.wap.multipart.related");
+        values.put("exp", 604800);
+        values.put("m_cls", PduHeaders.MESSAGE_CLASS_PERSONAL_STR);
+        values.put("m_type", PduHeaders.MESSAGE_TYPE_SEND_REQ);
+        values.put("v", PduHeaders.CURRENT_MMS_VERSION);
+        values.put("pri", PduHeaders.PRIORITY_NORMAL);
+        values.put("rr", PduHeaders.VALUE_NO);
+        values.put("tr_id", "T"+ Long.toHexString(System.currentTimeMillis()));
+        values.put("d_rpt", PduHeaders.VALUE_NO);
+        values.put("locked", 0);
+        if(msg.getTextOnly() == true)
+            values.put("text_only", true);
+
+        values.put("m_size", msg.getSize());
+
+     // Get thread id
+        Set<String> recipients = new HashSet<String>();
+        recipients.addAll(Arrays.asList(to_address));
+        values.put("thread_id", Telephony.Threads.getOrCreateThreadId(mContext, recipients));
+        Uri uri = Uri.parse("content://mms");
+
+        ContentResolver cr = mContext.getContentResolver();
+        uri = cr.insert(uri, values);
+
+        if (uri == null) {
+            // unable to insert MMS
+            Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri);
+            return -1;
+        }
+
+        long handle = Long.parseLong(uri.getLastPathSegment());
+        if (V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+        try {
+            if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base.");
+        for(MimePart part : msg.getMimeParts()) {
+            int count = 0;
+            count++;
+            values.clear();
+            if(part.contentType != null &&  part.contentType.toUpperCase().contains("TEXT")) {
+                values.put("ct", "text/plain");
+                values.put("chset", 106);
+                if(part.partName != null) {
+                    values.put("fn", part.partName);
+                    values.put("name", part.partName);
+                } else if(part.contentId == null && part.contentLocation == null) {
+                    /* We must set at least one part identifier */
+                    values.put("fn", "text_" + count +".txt");
+                    values.put("name", "text_" + count +".txt");
+                }
+                if(part.contentId != null) {
+                    values.put("cid", part.contentId);
+                }
+                if(part.contentLocation != null)
+                    values.put("cl", part.contentLocation);
+                if(part.contentDisposition != null)
+                    values.put("cd", part.contentDisposition);
+                values.put("text", new String(part.data, "UTF-8"));
+                uri = Uri.parse("content://mms/" + handle + "/part");
+                uri = cr.insert(uri, values);
+                if(V) Log.v(TAG, "Added TEXT part");
+
+            } else if (part.contentType != null &&  part.contentType.toUpperCase().contains("SMIL")){
+
+                values.put("seq", -1);
+                values.put("ct", "application/smil");
+                if(part.contentId != null)
+                    values.put("cid", part.contentId);
+                if(part.contentLocation != null)
+                    values.put("cl", part.contentLocation);
+                if(part.contentDisposition != null)
+                    values.put("cd", part.contentDisposition);
+                values.put("fn", "smil.xml");
+                values.put("name", "smil.xml");
+                values.put("text", new String(part.data, "UTF-8"));
+
+                uri = Uri.parse("content://mms/" + handle + "/part");
+                uri = cr.insert(uri, values);
+                if(V) Log.v(TAG, "Added SMIL part");
+
+            }else /*VIDEO/AUDIO/IMAGE*/ {
+                writeMmsDataPart(handle, part, count);
+                if(V) Log.v(TAG, "Added OTHER part");
+            }
+            if (uri != null && V){
+                Log.v(TAG, "Added part with content-type: "+ part.contentType + " to Uri: " + uri.toString());
+            }
+        }
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, e);
+        } catch (IOException e) {
+            Log.w(TAG, e);
+        }
+
+        values.clear();
+        values.put("contact_id", "null");
+        values.put("address", "insert-address-token");
+        values.put("type", BluetoothMapContent.MMS_FROM);
+        values.put("charset", 106);
+
+        uri = Uri.parse("content://mms/" + handle + "/addr");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+
+        values.clear();
+        values.put("contact_id", "null");
+        values.put("address", to_address);
+        values.put("type", BluetoothMapContent.MMS_TO);
+        values.put("charset", 106);
+
+        uri = Uri.parse("content://mms/" + handle + "/addr");
+        uri = cr.insert(uri, values);
+        if (uri != null && V){
+            Log.v(TAG, " NEW URI " + uri.toString());
+        }
+        return handle;
+    }
+
+
+    private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException{
+        ContentValues values = new ContentValues();
+        values.put("mid", handle);
+        if(part.contentType != null)
+            values.put("ct", part.contentType);
+        if(part.contentId != null)
+            values.put("cid", part.contentId);
+        if(part.contentLocation != null)
+            values.put("cl", part.contentLocation);
+        if(part.contentDisposition != null)
+            values.put("cd", part.contentDisposition);
+        if(part.partName != null) {
+            values.put("fn", part.partName);
+            values.put("name", part.partName);
+        } else if(part.contentId == null && part.contentLocation == null) {
+            /* We must set at least one part identifier */
+            values.put("fn", "part_" + count + ".dat");
+            values.put("name", "part_" + count + ".dat");
+        }
+        Uri partUri = Uri.parse("content://mms/" + handle + "/part");
+        Uri res = mResolver.insert(partUri, values);
+
+        // Add data to part
+        OutputStream os = mResolver.openOutputStream(res);
+        os.write(part.data);
+        os.close();
+    }
+
+
+    public void sendMessage(PushMsgInfo msgInfo, String msgBody) {
+
+        SmsManager smsMng = SmsManager.getDefault();
+        ArrayList<String> parts = smsMng.divideMessage(msgBody);
+        msgInfo.parts = parts.size();
+
+        ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(msgInfo.parts);
+        ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(msgInfo.parts);
+
+        for (int i = 0; i < msgInfo.parts; i++) {
+            Intent intent;
+            intent = new Intent(ACTION_MESSAGE_DELIVERY, null);
+            intent.putExtra("HANDLE", msgInfo.id);
+            deliveryIntents.add(PendingIntent.getBroadcast(mContext, 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT));
+
+            intent = new Intent(ACTION_MESSAGE_SENT, null);
+            intent.putExtra("HANDLE", msgInfo.id);
+            sentIntents.add(PendingIntent.getBroadcast(mContext, 0, intent,
+                PendingIntent.FLAG_UPDATE_CURRENT));
+        }
+
+        Log.d(TAG, "sendMessage to " + msgInfo.phone);
+
+        smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents,
+            deliveryIntents);
+    }
+
+    private static final String ACTION_MESSAGE_DELIVERY =
+        "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY";
+    private static final String ACTION_MESSAGE_SENT =
+        "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT";
+
+    private SmsBroadcastReceiver mSmsBroadcastReceiver = new SmsBroadcastReceiver();
+
+    private class SmsBroadcastReceiver extends BroadcastReceiver {
+        private final String[] ID_PROJECTION = new String[] { Sms._ID };
+        private final Uri UPDATE_STATUS_URI = Uri.parse("content://sms/status");
+
+        public void register() {
+            Handler handler = new Handler();
+
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(ACTION_MESSAGE_DELIVERY);
+            intentFilter.addAction(ACTION_MESSAGE_SENT);
+            mContext.registerReceiver(this, intentFilter, null, handler);
+        }
+
+        public void unregister() {
+            try {
+                mContext.unregisterReceiver(this);
+            } catch (IllegalArgumentException e) {
+                /* do nothing */
+            }
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            long handle = intent.getLongExtra("HANDLE", -1);
+            PushMsgInfo msgInfo = mPushMsgList.get(handle);
+
+            Log.d(TAG, "onReceive: action"  + action);
+
+            if (msgInfo == null) {
+                Log.d(TAG, "onReceive: no msgInfo found for handle " + handle);
+                return;
+            }
+
+            if (action.equals(ACTION_MESSAGE_SENT)) {
+                msgInfo.partsSent++;
+                if (msgInfo.partsSent == msgInfo.parts) {
+                    actionMessageSent(context, intent, msgInfo);
+                }
+            } else if (action.equals(ACTION_MESSAGE_DELIVERY)) {
+                msgInfo.partsDelivered++;
+                if (msgInfo.partsDelivered == msgInfo.parts) {
+                    actionMessageDelivery(context, intent, msgInfo);
+                }
+            } else {
+                Log.d(TAG, "onReceive: Unknown action " + action);
+            }
+        }
+
+        private void actionMessageSent(Context context, Intent intent,
+            PushMsgInfo msgInfo) {
+            int result = getResultCode();
+            boolean delete = false;
+
+            if (result == Activity.RESULT_OK) {
+                Log.d(TAG, "actionMessageSent: result OK");
+                if (msgInfo.transparent == 0) {
+                    if (!Sms.moveMessageToFolder(context, msgInfo.uri,
+                            Sms.MESSAGE_TYPE_SENT, 0)) {
+                        Log.d(TAG, "Failed to move " + msgInfo.uri + " to SENT");
+                    }
+                } else {
+                    delete = true;
+                }
+
+                Event evt = new Event("SendingSuccess", msgInfo.id,
+                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
+                sendEvent(evt);
+
+            } else {
+                if (msgInfo.retry == 1) {
+                    /* Notify failure, but keep message in outbox for resending */
+                    msgInfo.resend = true;
+                    Event evt = new Event("SendingFailure", msgInfo.id,
+                        folderSms[Sms.MESSAGE_TYPE_OUTBOX], null, mSmsType);
+                    sendEvent(evt);
+                } else {
+                    if (msgInfo.transparent == 0) {
+                        if (!Sms.moveMessageToFolder(context, msgInfo.uri,
+                                Sms.MESSAGE_TYPE_FAILED, 0)) {
+                            Log.d(TAG, "Failed to move " + msgInfo.uri + " to FAILED");
+                        }
+                    } else {
+                        delete = true;
+                    }
+
+                    Event evt = new Event("SendingFailure", msgInfo.id,
+                        folderSms[Sms.MESSAGE_TYPE_FAILED], null, mSmsType);
+                    sendEvent(evt);
+                }
+            }
+
+            if (delete == true) {
+                /* Delete from Observer message list to avoid delete notifications */
+                mMsgListSms.remove(msgInfo.id);
+
+                /* Delete from DB */
+                mResolver.delete(msgInfo.uri, null, null);
+            }
+        }
+
+        private void actionMessageDelivery(Context context, Intent intent,
+            PushMsgInfo msgInfo) {
+            Uri messageUri = intent.getData();
+            byte[] pdu = intent.getByteArrayExtra("pdu");
+            String format = intent.getStringExtra("format");
+
+            SmsMessage message = SmsMessage.createFromPdu(pdu, format);
+            if (message == null) {
+                Log.d(TAG, "actionMessageDelivery: Can't get message from pdu");
+                return;
+            }
+            int status = message.getStatus();
+
+            Cursor cursor = mResolver.query(msgInfo.uri, ID_PROJECTION, null, null, null);
+
+            try {
+                if (cursor.moveToFirst()) {
+                    int messageId = cursor.getInt(0);
+
+                    Uri updateUri = ContentUris.withAppendedId(UPDATE_STATUS_URI, messageId);
+                    boolean isStatusReport = message.isStatusReportMessage();
+
+                    Log.d(TAG, "actionMessageDelivery: uri=" + messageUri + ", status=" + status +
+                                ", isStatusReport=" + isStatusReport);
+
+                    ContentValues contentValues = new ContentValues(2);
+
+                    contentValues.put(Sms.STATUS, status);
+                    contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis());
+                    mResolver.update(updateUri, contentValues, null, null);
+                } else {
+                    Log.d(TAG, "Can't find message for status update: " + messageUri);
+                }
+            } finally {
+                cursor.close();
+            }
+
+            if (status == 0) {
+                Event evt = new Event("DeliverySuccess", msgInfo.id,
+                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
+                sendEvent(evt);
+            } else {
+                Event evt = new Event("DeliveryFailure", msgInfo.id,
+                    folderSms[Sms.MESSAGE_TYPE_SENT], null, mSmsType);
+                sendEvent(evt);
+            }
+
+            mPushMsgList.remove(msgInfo.id);
+        }
+    }
+
+    private void registerPhoneServiceStateListener() {
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+    }
+
+    private void unRegisterPhoneServiceStateListener() {
+        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);
+    }
+
+    private void resendPendingMessages() {
+        /* Send pending messages in outbox */
+        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
+        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
+            null);
+
+        if (c != null && c.moveToFirst()) {
+            do {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
+                PushMsgInfo msgInfo = mPushMsgList.get(id);
+                if (msgInfo == null || msgInfo.resend == false) {
+                    continue;
+                }
+                sendMessage(msgInfo, msgBody);
+            } while (c.moveToNext());
+            c.close();
+        }
+    }
+
+    private void failPendingMessages() {
+        /* Move pending messages from outbox to failed */
+        String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
+        Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
+            null);
+
+        if (c != null && c.moveToFirst()) {
+            do {
+                long id = c.getLong(c.getColumnIndex(BaseColumns._ID));
+                String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
+                PushMsgInfo msgInfo = mPushMsgList.get(id);
+                if (msgInfo == null || msgInfo.resend == false) {
+                    continue;
+                }
+                Sms.moveMessageToFolder(mContext, msgInfo.uri,
+                    Sms.MESSAGE_TYPE_FAILED, 0);
+            } while (c.moveToNext());
+        }
+        if (c != null) c.close();
+    }
+
+    private void removeDeletedMessages() {
+        /* Remove messages from virtual "deleted" folder (thread_id -1) */
+        mResolver.delete(Uri.parse("content://sms/"),
+                "thread_id = " + DELETED_THREAD_ID, null);
+    }
+
+    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
+        @Override
+        public void onServiceStateChanged(ServiceState serviceState) {
+            Log.d(TAG, "Phone service state change: " + serviceState.getState());
+            if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
+                resendPendingMessages();
+            }
+        }
+    };
+
+    public void init() {
+        mSmsBroadcastReceiver.register();
+        registerPhoneServiceStateListener();
+    }
+
+    public void deinit() {
+        mSmsBroadcastReceiver.unregister();
+        unRegisterPhoneServiceStateListener();
+        failPendingMessages();
+        removeDeletedMessages();
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapFolderElement.java b/src/com/android/bluetooth/map/BluetoothMapFolderElement.java
new file mode 100644
index 0000000..d3909dd
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapFolderElement.java
@@ -0,0 +1,133 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import android.util.Xml;
+
+/**
+ * @author cbonde
+ *
+ */
+public class BluetoothMapFolderElement {
+    private String name;
+    private BluetoothMapFolderElement parent = null;
+    private ArrayList<BluetoothMapFolderElement> subFolders;
+
+    public BluetoothMapFolderElement( String name, BluetoothMapFolderElement parrent ){
+        this.name = name;
+        this.parent = parrent;
+        subFolders = new ArrayList<BluetoothMapFolderElement>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Fetch the parent folder.
+     * @return the parent folder or null if we are at the root folder.
+     */
+    public BluetoothMapFolderElement getParent() {
+        return parent;
+    }
+
+    /**
+     * Fetch the root folder.
+     * @return the parent folder or null if we are at the root folder.
+     */
+    public BluetoothMapFolderElement getRoot() {
+        BluetoothMapFolderElement rootFolder = this;
+        while(rootFolder.getParent() != null)
+            rootFolder = rootFolder.getParent();
+        return rootFolder;
+    }
+
+    /**
+     * Add a folder.
+     * @param name the name of the folder to add.
+     * @return the added folder element.
+     */
+    public BluetoothMapFolderElement addFolder(String name){
+        BluetoothMapFolderElement newFolder = new BluetoothMapFolderElement(name, this);
+        subFolders.add(newFolder);
+        return newFolder;
+    }
+
+    /**
+     * Fetch the number of sub folders.
+     * @return returns the number of sub folders.
+     */
+    public int getSubFolderCount(){
+        return subFolders.size();
+    }
+
+    /**
+     * Returns the subFolder element matching the supplied folder name.
+     * @param folderName the name of the subFolder to find.
+     * @return the subFolder element if found {@code null} otherwise.
+     */
+    public BluetoothMapFolderElement getSubFolder(String folderName){
+        for(BluetoothMapFolderElement subFolder : subFolders){
+            if(subFolder.getName().equals(folderName))
+                return subFolder;
+        }
+        return null;
+    }
+
+    public byte[] encode(int offset, int count) throws UnsupportedEncodingException {
+        StringWriter sw = new StringWriter();
+        XmlSerializer xmlMsgElement = Xml.newSerializer();
+        int i, stopIndex;
+        if(offset > subFolders.size())
+            throw new IllegalArgumentException("FolderListingEncode: offset > subFolders.size()");
+
+        stopIndex = offset + count;
+        if(stopIndex > subFolders.size())
+            stopIndex = subFolders.size();
+
+        try {
+            xmlMsgElement.setOutput(sw);
+            xmlMsgElement.startDocument(null, null);
+            xmlMsgElement.text("\n");
+            xmlMsgElement.startTag("", "folder-listing");
+            xmlMsgElement.attribute("", "version", "1.0");
+            for(i = offset; i<stopIndex; i++)
+            {
+                xmlMsgElement.startTag("", "folder");
+                xmlMsgElement.attribute("", "name", subFolders.get(i).getName());
+                xmlMsgElement.endTag("", "folder");
+            }
+            xmlMsgElement.endTag("", "folder-listing");
+            xmlMsgElement.endDocument();
+        } catch (IllegalArgumentException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IllegalStateException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return sw.toString().getBytes("UTF-8");
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapMessageListing.java b/src/com/android/bluetooth/map/BluetoothMapMessageListing.java
new file mode 100644
index 0000000..ffa0568
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapMessageListing.java
@@ -0,0 +1,111 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import android.util.Log;
+import android.util.Xml;
+
+public class BluetoothMapMessageListing {
+    private boolean hasUnread = false;
+    private static final String TAG = "BluetoothMapMessageListing";
+    private List<BluetoothMapMessageListingElement> list;
+
+    public BluetoothMapMessageListing(){
+     list = new ArrayList<BluetoothMapMessageListingElement>();
+    }
+    public void add(BluetoothMapMessageListingElement element) {
+        list.add(element);
+        /* update info regarding whether the list contains unread messages */
+        if (element.getRead().equalsIgnoreCase("no"))
+        {
+            hasUnread = true;
+        }
+    }
+
+    /**
+     * Used to fetch the number of BluetoothMapMessageListingElement elements in the list.
+     * @return the number of elements in the list.
+     */
+    public int getCount() {
+        if(list != null)
+        {
+            return list.size();
+        }
+        return 0;
+    }
+
+    /**
+     * does the list contain any unread messages
+     * @return true if unread messages have been added to the list, else false
+     */
+    public boolean hasUnread()
+    {
+        return hasUnread;
+    }
+
+    /**
+     * Encode the list of BluetoothMapMessageListingElement(s) into a UTF-8
+     * formatted XML-string in a trimmed byte array
+     *
+     * @return a reference to the encoded byte array.
+     * @throws UnsupportedEncodingException
+     *             if UTF-8 encoding is unsupported on the platform.
+     */
+    public byte[] encode() throws UnsupportedEncodingException {
+        StringWriter sw = new StringWriter();
+        XmlSerializer xmlMsgElement = Xml.newSerializer();
+        try {
+            xmlMsgElement.setOutput(sw);
+            xmlMsgElement.startDocument(null, null);
+            xmlMsgElement.startTag("", "MAP-msg-listing");
+            xmlMsgElement.attribute("", "version", "1.0");
+            // Do the XML encoding of list
+            for (BluetoothMapMessageListingElement element : list) {
+                element.encode(xmlMsgElement); // Append the list element
+            }
+            xmlMsgElement.endTag("", "MAP-msg-listing");
+            xmlMsgElement.endDocument();
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, e.toString());
+        } catch (IllegalStateException e) {
+            Log.w(TAG, e.toString());
+        } catch (IOException e) {
+            Log.w(TAG, e.toString());
+        }
+        return sw.toString().getBytes("UTF-8");
+    }
+
+    public void sort() {
+        Collections.sort(list);
+    }
+
+    public void segment(int count, int offset) {
+        count = Math.min(count, list.size());
+        if (offset + count <= list.size()) {
+            list = list.subList(offset, offset + count);
+        } else {
+            list = null;
+        }
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
new file mode 100644
index 0000000..9f70759
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
@@ -0,0 +1,262 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.xmlpull.v1.XmlSerializer;
+
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+
+public class BluetoothMapMessageListingElement
+    implements Comparable<BluetoothMapMessageListingElement> {
+
+    private static final String TAG = "BluetoothMapMessageListingElement";
+    private static final boolean D = false;
+    private static final boolean V = false;
+
+    private long cpHandle = 0; /* The content provider handle - without type information */
+    private String mapHandle = null; /* The map hex-string handle with type information */
+    private String subject = null;
+    private long dateTime = 0;
+    private String senderName = null;
+    private String senderAddressing = null;
+    private String replytoAddressing = null;
+    private String recipientName = null;
+    private String recipientAddressing = null;
+    private TYPE type = null;
+    private int size = -1;
+    private String text = null;
+    private String receptionStatus = null;
+    private int attachmentSize = -1;
+    private String priority = null;
+    private String read = null;
+    private String sent = null;
+    private String protect = null;
+    private boolean reportRead;
+    public long getHandle() {
+        return cpHandle;
+    }
+
+    public void setHandle(long handle, TYPE type) {
+        this.cpHandle = handle;
+        this.mapHandle = BluetoothMapUtils.getMapHandle(cpHandle, type);
+    }
+
+    public long getDateTime() {
+        return dateTime;
+    }
+
+    public String getDateTimeString() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = new Date(dateTime);
+        return format.format(date); // Format to YYYYMMDDTHHMMSS local time
+    }
+
+    public void setDateTime(long dateTime) {
+        this.dateTime = dateTime;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getSenderName() {
+        return senderName;
+    }
+
+    public void setSenderName(String senderName) {
+        this.senderName = senderName;
+    }
+
+    public String getSenderAddressing() {
+        return senderAddressing;
+    }
+
+    public void setSenderAddressing(String senderAddressing) {
+        /* TODO: This should depend on the type - for email, the addressing is an email address
+         * Consider removing this again - to allow strings.
+         */
+        this.senderAddressing = PhoneNumberUtils.extractNetworkPortion(senderAddressing);
+        if(this.senderAddressing == null || this.senderAddressing.length() < 2){
+            this.senderAddressing = "11"; // Ensure we have at least two digits to
+        }
+    }
+
+    public String getReplyToAddressing() {
+        return replytoAddressing;
+    }
+
+    public void setReplytoAddressing(String replytoAddressing) {
+        this.replytoAddressing = replytoAddressing;
+    }
+
+    public String getRecipientName() {
+        return recipientName;
+    }
+
+    public void setRecipientName(String recipientName) {
+        this.recipientName = recipientName;
+    }
+
+    public String getRecipientAddressing() {
+        return recipientAddressing;
+    }
+
+    public void setRecipientAddressing(String recipientAddressing) {
+        this.recipientAddressing = recipientAddressing;
+    }
+
+    public TYPE getType() {
+        return type;
+    }
+
+    public void setType(TYPE type) {
+        this.type = type;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getReceptionStatus() {
+        return receptionStatus;
+    }
+
+    public void setReceptionStatus(String receptionStatus) {
+        this.receptionStatus = receptionStatus;
+    }
+
+    public int getAttachmentSize() {
+        return attachmentSize;
+    }
+
+    public void setAttachmentSize(int attachmentSize) {
+        this.attachmentSize = attachmentSize;
+    }
+
+    public String getPriority() {
+        return priority;
+    }
+
+    public void setPriority(String priority) {
+        this.priority = priority;
+    }
+
+    public String getRead() {
+        return read;
+    }
+
+    public void setRead(String read, boolean reportRead) {
+        this.read = read;
+        this.reportRead = reportRead;
+    }
+
+    public String getSent() {
+        return sent;
+    }
+
+    public void setSent(String sent) {
+        this.sent = sent;
+    }
+
+    public String getProtect() {
+        return protect;
+    }
+
+    public void setProtect(String protect) {
+        this.protect = protect;
+    }
+
+    public int compareTo(BluetoothMapMessageListingElement e) {
+        if (this.dateTime < e.dateTime) {
+            return 1;
+        } else if (this.dateTime > e.dateTime) {
+            return -1;
+        } else {
+            return 0;
+        }
+    }
+
+    /* Encode the MapMessageListingElement into the StringBuilder reference.
+     * */
+    public void encode(XmlSerializer xmlMsgElement) throws IllegalArgumentException, IllegalStateException, IOException
+    {
+
+            // contruct the XML tag for a single msg in the msglisting
+            xmlMsgElement.startTag("", "msg");
+            xmlMsgElement.attribute("", "handle", mapHandle);
+            if(subject != null)
+                xmlMsgElement.attribute("", "subject", subject);
+            if(dateTime != 0)
+                xmlMsgElement.attribute("", "datetime", this.getDateTimeString());
+            if(senderName != null)
+                xmlMsgElement.attribute("", "sender_name", senderName);
+            if(senderAddressing != null)
+                xmlMsgElement.attribute("", "sender_addressing", senderAddressing);
+            if(replytoAddressing != null)
+                xmlMsgElement.attribute("", "replyto_addressing",replytoAddressing);
+            if(recipientName != null)
+                xmlMsgElement.attribute("", "recipient_name",recipientName);
+            if(recipientAddressing != null)
+                xmlMsgElement.attribute("", "recipient_addressing", recipientAddressing);
+            if(type != null)
+                xmlMsgElement.attribute("", "type", type.name());
+            if(size != -1)
+                xmlMsgElement.attribute("", "size", Integer.toString(size));
+            if(text != null)
+                xmlMsgElement.attribute("", "text", text);
+            if(receptionStatus != null)
+                xmlMsgElement.attribute("", "reception_status", receptionStatus);
+            if(attachmentSize != -1)
+                xmlMsgElement.attribute("", "attachment_size", Integer.toString(attachmentSize));
+            if(priority != null)
+                xmlMsgElement.attribute("", "priority", priority);
+            if(read != null && reportRead)
+                xmlMsgElement.attribute("", "read", read);
+            if(sent != null)
+                xmlMsgElement.attribute("", "sent", sent);
+            if(protect != null)
+                xmlMsgElement.attribute("", "protect", protect);
+            xmlMsgElement.endTag("", "msg");
+
+    }
+}
+
+
diff --git a/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
new file mode 100644
index 0000000..a876740
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -0,0 +1,704 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Calendar;
+
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+import javax.obex.ServerRequestHandler;
+
+import com.android.bluetooth.map.BluetoothMapUtils;
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+public class BluetoothMapObexServer extends ServerRequestHandler {
+
+    private static final String TAG = "BluetoothMapObexServer";
+
+    private static final boolean D = BluetoothMapService.DEBUG;
+    private static final boolean V = BluetoothMapService.VERBOSE;
+
+    private static final int UUID_LENGTH = 16;
+
+    // 128 bit UUID for MAP
+    private static final byte[] MAP_TARGET = new byte[] {
+             (byte)0xBB, (byte)0x58, (byte)0x2B, (byte)0x40,
+             (byte)0x42, (byte)0x0C, (byte)0x11, (byte)0xDB,
+             (byte)0xB0, (byte)0xDE, (byte)0x08, (byte)0x00,
+             (byte)0x20, (byte)0x0C, (byte)0x9A, (byte)0x66
+             };
+
+    /* Message types */
+    private static final String TYPE_GET_FOLDER_LISTING  = "x-obex/folder-listing";
+    private static final String TYPE_GET_MESSAGE_LISTING = "x-bt/MAP-msg-listing";
+    private static final String TYPE_MESSAGE             = "x-bt/message";
+    private static final String TYPE_SET_MESSAGE_STATUS  = "x-bt/messageStatus";
+    private static final String TYPE_SET_NOTIFICATION_REGISTRATION = "x-bt/MAP-NotificationRegistration";
+    private static final String TYPE_MESSAGE_UPDATE      = "x-bt/MAP-messageUpdate";
+
+    private BluetoothMapFolderElement mCurrentFolder;
+
+    private BluetoothMnsObexClient mMnsClient;
+
+    private Handler mCallback = null;
+
+    private Context mContext;
+
+    public static boolean sIsAborted = false;
+
+    BluetoothMapContent mOutContent;
+
+    public BluetoothMapObexServer(Handler callback, Context context,
+                                  BluetoothMnsObexClient mns) {
+        super();
+        mCallback = callback;
+        mContext = context;
+        mOutContent = new BluetoothMapContent(mContext);
+        mMnsClient = mns;
+        buildFolderStructure(); /* Build the default folder structure, and set
+                                   mCurrentFolder to root folder */
+    }
+
+    /**
+     * Build the default minimal folder structure, as defined in the MAP specification.
+     */
+    private void buildFolderStructure(){
+        mCurrentFolder = new BluetoothMapFolderElement("root", null); // This will be the root element
+        BluetoothMapFolderElement tmpFolder;
+        tmpFolder = mCurrentFolder.addFolder("telecom"); // root/telecom
+        tmpFolder = tmpFolder.addFolder("msg");          // root/telecom/msg
+        tmpFolder.addFolder("inbox");                    // root/telecom/msg/inbox
+        tmpFolder.addFolder("outbox");
+        tmpFolder.addFolder("sent");
+        tmpFolder.addFolder("deleted");
+        tmpFolder.addFolder("draft");
+    }
+
+    @Override
+    public int onConnect(final HeaderSet request, HeaderSet reply) {
+        if (D) Log.d(TAG, "onConnect():");
+        if (V) logHeader(request);
+        try {
+            byte[] uuid = (byte[])request.getHeader(HeaderSet.TARGET);
+            if (uuid == null) {
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+            if (D) Log.d(TAG, "onConnect(): uuid=" + Arrays.toString(uuid));
+
+            if (uuid.length != UUID_LENGTH) {
+                Log.w(TAG, "Wrong UUID length");
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+            for (int i = 0; i < UUID_LENGTH; i++) {
+                if (uuid[i] != MAP_TARGET[i]) {
+                    Log.w(TAG, "Wrong UUID");
+                    return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+                }
+            }
+            reply.setHeader(HeaderSet.WHO, uuid);
+        } catch (IOException e) {
+            Log.e(TAG, e.toString());
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        try {
+            byte[] remote = (byte[])request.getHeader(HeaderSet.WHO);
+            if (remote != null) {
+                if (D) Log.d(TAG, "onConnect(): remote=" + Arrays.toString(remote));
+                reply.setHeader(HeaderSet.TARGET, remote);
+            }
+        } catch (IOException e) {
+            Log.e(TAG, e.toString());
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        if (V) Log.v(TAG, "onConnect(): uuid is ok, will send out " +
+                "MSG_SESSION_ESTABLISHED msg.");
+
+
+        Message msg = Message.obtain(mCallback);
+        msg.what = BluetoothMapService.MSG_SESSION_ESTABLISHED;
+        msg.sendToTarget();
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public void onDisconnect(final HeaderSet req, final HeaderSet resp) {
+        if (D) Log.d(TAG, "onDisconnect(): enter");
+        if (V) logHeader(req);
+
+        resp.responseCode = ResponseCodes.OBEX_HTTP_OK;
+        if (mCallback != null) {
+            Message msg = Message.obtain(mCallback);
+            msg.what = BluetoothMapService.MSG_SESSION_DISCONNECTED;
+            msg.sendToTarget();
+            if (V) Log.v(TAG, "onDisconnect(): msg MSG_SESSION_DISCONNECTED sent out.");
+        }
+    }
+
+    @Override
+    public int onAbort(HeaderSet request, HeaderSet reply) {
+        if (D) Log.d(TAG, "onAbort(): enter.");
+        sIsAborted = true;
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public int onPut(final Operation op) {
+        if (D) Log.d(TAG, "onPut(): enter");
+        HeaderSet request = null;
+        String type, name;
+        byte[] appParamRaw;
+        BluetoothMapAppParams appParams = null;
+
+        try {
+            request = op.getReceivedHeader();
+            type = (String)request.getHeader(HeaderSet.TYPE);
+            name = (String)request.getHeader(HeaderSet.NAME);
+            appParamRaw = (byte[])request.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            if(appParamRaw != null)
+                appParams = new BluetoothMapAppParams(appParamRaw);
+        } catch (Exception e) {
+            Log.e(TAG, "request headers error");
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        if(D) Log.d(TAG,"type = " + type + ", name = " + name);
+        if (type.equals(TYPE_MESSAGE_UPDATE)) {
+            if(V) {
+                Log.d(TAG,"TYPE_MESSAGE_UPDATE:");
+            }
+            return ResponseCodes.OBEX_HTTP_OK;
+        }else if(type.equals(TYPE_SET_NOTIFICATION_REGISTRATION)) {
+            if(V) {
+                Log.d(TAG,"TYPE_SET_NOTIFICATION_REGISTRATION: NotificationStatus: " + appParams.getNotificationStatus());
+            }
+            return setNotificationRegistration(appParams);
+        }else if(type.equals(TYPE_SET_MESSAGE_STATUS)) {
+            if(V) {
+                Log.d(TAG,"TYPE_SET_MESSAGE_STATUS: StatusIndicator: " + appParams.getStatusIndicator() + ", StatusValue: " + appParams.getStatusValue());
+            }
+            return setMessageStatus(name, appParams);
+        } else if (type.equals(TYPE_MESSAGE)) {
+            if(V) {
+                Log.d(TAG,"TYPE_MESSAGE: Transparet: " + appParams.getTransparent() +  ", Retry: " + appParams.getRetry());
+                Log.d(TAG,"              charset: " + appParams.getCharset());
+            }
+            return pushMessage(op, name, appParams);
+
+        }
+
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+    }
+
+    private int setNotificationRegistration(BluetoothMapAppParams appParams) {
+        // Forward the request to the MNS thread as a message - including the MAS instance ID.
+        Handler mns = mMnsClient.getMessageHandler();
+        if(mns != null) {
+            Message msg = Message.obtain(mns);
+            msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION;
+            msg.arg1 = 0; // TODO: Add correct MAS ID, as specified in the SDP record.
+            msg.arg2 = appParams.getNotificationStatus();
+            msg.sendToTarget();
+            if(D) Log.d(TAG,"MSG_MNS_NOTIFICATION_REGISTRATION");
+            return ResponseCodes.OBEX_HTTP_OK;
+        } else {
+            return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // This should not happen.
+        }
+    }
+
+    private int pushMessage(final Operation op, String folderName, BluetoothMapAppParams appParams) {
+        if(appParams.getCharset() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) {
+            if(D) Log.d(TAG, "Missing charset - unable to decode message content. appParams.getCharset() = " + appParams.getCharset());
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        try {
+            if(folderName == null || folderName.equals("")) {
+                folderName = mCurrentFolder.getName();
+            }
+            if(!folderName.equals("outbox") && !folderName.equals("draft")) {
+                if(D) Log.d(TAG, "Push message only allowed to outbox and draft. folderName: " + folderName);
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+            /*  - Read out the message
+             *  - Decode into a bMessage
+             *  - send it.
+             */
+            InputStream bMsgStream;
+            BluetoothMapbMessage message;
+            bMsgStream = op.openInputStream();
+            message = BluetoothMapbMessage.parse(bMsgStream, appParams.getCharset()); // Decode the messageBody
+            // Send message
+            BluetoothMapContentObserver observer = mMnsClient.getContentObserver();
+            if (observer == null) {
+                return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // Should not happen.
+            }
+
+            long handle = observer.pushMessage(message, folderName, appParams);
+            if (D) Log.d(TAG, "pushMessage handle: " + handle);
+            if (handle < 0) {
+                return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // Should not happen.
+            }
+            HeaderSet replyHeaders = new HeaderSet();
+            String handleStr = BluetoothMapUtils.getMapHandle(handle, message.getType());
+            if (D) Log.d(TAG, "handleStr: " + handleStr + " message.getType(): " + message.getType());
+            replyHeaders.setHeader(HeaderSet.NAME, handleStr);
+            op.sendHeaders(replyHeaders);
+
+            bMsgStream.close();
+        } catch (IllegalArgumentException e) {
+            if(D) Log.w(TAG, "Wrongly formatted bMessage received", e);
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        } catch (Exception e) {
+            // TODO: Change to IOException after debug
+            Log.e(TAG, "Exception occured: ", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    private int setMessageStatus(String msgHandle, BluetoothMapAppParams appParams) {
+        int indicator = appParams.getStatusIndicator();
+        int value = appParams.getStatusValue();
+        long handle;
+        BluetoothMapUtils.TYPE msgType;
+
+        if(indicator == BluetoothMapAppParams.INVALID_VALUE_PARAMETER ||
+           value == BluetoothMapAppParams.INVALID_VALUE_PARAMETER ||
+           msgHandle == null) {
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+        BluetoothMapContentObserver observer = mMnsClient.getContentObserver();
+        if (observer == null) {
+            return ResponseCodes.OBEX_HTTP_UNAVAILABLE; // Should not happen.
+        }
+
+        try {
+            handle = BluetoothMapUtils.getCpHandle(msgHandle);
+            msgType = BluetoothMapUtils.getMsgTypeFromHandle(msgHandle);
+        } catch (NumberFormatException e) {
+            Log.w(TAG, "Wrongly formatted message handle: " + msgHandle);
+            return ResponseCodes.OBEX_HTTP_PRECON_FAILED;
+        }
+
+        if( indicator == BluetoothMapAppParams.STATUS_INDICATOR_DELETED) {
+            if (!observer.setMessageStatusDeleted(handle, msgType, value)) {
+                return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+            }
+        } else /* BluetoothMapAppParams.STATUS_INDICATOR_READE */ {
+            if (!observer.setMessageStatusRead(handle, msgType, value)) {
+                return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+            }
+        }
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public int onSetPath(final HeaderSet request, final HeaderSet reply, final boolean backup,
+            final boolean create) {
+        String folderName;
+        BluetoothMapFolderElement folder;
+        try {
+            folderName = (String)request.getHeader(HeaderSet.NAME);
+        } catch (Exception e) {
+            Log.e(TAG, "request headers error");
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        if (V) logHeader(request);
+        if (D) Log.d(TAG, "onSetPath name is " + folderName + " backup: " + backup
+                     + "create: " + create);
+
+        if(backup == true){
+            if(mCurrentFolder.getParent() != null)
+                mCurrentFolder = mCurrentFolder.getParent();
+            else
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        if (folderName == null || folderName == "") {
+            if(backup == false)
+                mCurrentFolder = mCurrentFolder.getRoot();
+        }
+        else {
+            folder = mCurrentFolder.getSubFolder(folderName);
+            if(folder != null)
+                mCurrentFolder = folder;
+            else
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+        if (V) Log.d(TAG, "Current Folder: " + mCurrentFolder.getName());
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public void onClose() {
+        if (mCallback != null) {
+            Message msg = Message.obtain(mCallback);
+            msg.what = BluetoothMapService.MSG_SERVERSESSION_CLOSE;
+            msg.sendToTarget();
+            if (D) Log.d(TAG, "onClose(): msg MSG_SERVERSESSION_CLOSE sent out.");
+        }
+    }
+
+    @Override
+    public int onGet(Operation op) {
+        sIsAborted = false;
+        HeaderSet request;
+        String type;
+        String name;
+        byte[] appParamRaw = null;
+        BluetoothMapAppParams appParams = null;
+        try {
+            request = op.getReceivedHeader();
+            type = (String)request.getHeader(HeaderSet.TYPE);
+            name = (String)request.getHeader(HeaderSet.NAME);
+            appParamRaw = (byte[])request.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            if(appParamRaw != null)
+                appParams = new BluetoothMapAppParams(appParamRaw);
+
+            if (V) logHeader(request);
+            if (D) Log.d(TAG, "OnGet type is " + type + " name is " + name);
+
+            if (type == null) {
+                if (V) Log.d(TAG, "type is null?" + type);
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            }
+
+            if (type.equals(TYPE_GET_FOLDER_LISTING)) {
+                if (V && appParams != null) {
+                    Log.d(TAG,"TYPE_GET_FOLDER_LISTING: MaxListCount = " + appParams.getMaxListCount() +
+                              ", ListStartOffset = " + appParams.getStartOffset());
+                }
+                return sendFolderListingRsp(op, appParams); // Block until all packets have been send.
+            }
+            else if (type.equals(TYPE_GET_MESSAGE_LISTING)){
+                if (V && appParams != null) {
+                    Log.d(TAG,"TYPE_GET_MESSAGE_LISTING: MaxListCount = " + appParams.getMaxListCount() +
+                              ", ListStartOffset = " + appParams.getStartOffset());
+                    Log.d(TAG,"SubjectLength = " + appParams.getSubjectLength() + ", ParameterMask = " +
+                              appParams.getParameterMask());
+                    Log.d(TAG,"FilterMessageType = " + appParams.getFilterMessageType() +
+                              ", FilterPeriodBegin = " + appParams.getFilterPeriodBegin());
+                    Log.d(TAG,"FilterPeriodEnd = " + appParams.getFilterPeriodBegin() +
+                              ", FilterReadStatus = " + appParams.getFilterReadStatus());
+                    Log.d(TAG,"FilterRecipient = " + appParams.getFilterRecipient() +
+                              ", FilterOriginator = " + appParams.getFilterOriginator());
+                    Log.d(TAG,"FilterPriority = " + appParams.getFilterPriority());
+                }
+                return sendMessageListingRsp(op, appParams, name); // Block until all packets have been send.
+            }
+            else if (type.equals(TYPE_MESSAGE)){
+                if(V && appParams != null) {
+                    Log.d(TAG,"TYPE_MESSAGE (GET): Attachment = " + appParams.getAttachment() + ", Charset = " + appParams.getCharset() +
+                        ", FractionRequest = " + appParams.getFractionRequest());
+                }
+                return sendGetMessageRsp(op, name, appParams); // Block until all packets have been send.
+            }
+            else {
+                Log.w(TAG, "unknown type request: " + type);
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+        } catch (Exception e) {
+            // TODO: Move to the part that actually throws exceptions, and change to the correat exception type
+            Log.e(TAG, "request headers error, Exception:", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+    }
+
+    /**
+     * Generate and send the message listing response based on an application
+     * parameter header. This function call will block until complete or aborted
+     * by the peer. Fragmentation of packets larger than the obex packet size
+     * will be handled by this function.
+     *
+     * @param op
+     *            The OBEX operation.
+     * @param appParams
+     *            The application parameter header
+     * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or
+     *         {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error.
+     */
+    private int sendMessageListingRsp(Operation op, BluetoothMapAppParams appParams, String folderName){
+        OutputStream outStream = null;
+        byte[] outBytes = null;
+        int maxChunkSize, bytesToWrite, bytesWritten = 0, listSize;
+        boolean hasUnread = false;
+        HeaderSet replyHeaders = new HeaderSet();
+        BluetoothMapAppParams outAppParams = new BluetoothMapAppParams();
+        BluetoothMapMessageListing outList;
+        if(folderName == null) {
+            folderName = mCurrentFolder.getName();
+        }
+        if(appParams == null){
+            appParams = new BluetoothMapAppParams();
+            appParams.setMaxListCount(1024);
+            appParams.setStartOffset(0);
+        }
+
+        // Check to see if we only need to send the size - hence no need to encode.
+        try {
+            // Open the OBEX body stream
+            outStream = op.openOutputStream();
+
+            if(appParams.getMaxListCount() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER)
+                appParams.setMaxListCount(1024);
+
+            if(appParams.getStartOffset() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER)
+                appParams.setStartOffset(0);
+
+            if(appParams.getMaxListCount() != 0) {
+                outList = mOutContent.msgListing(folderName, appParams);
+                // Generate the byte stream
+                outAppParams.setMessageListingSize(outList.getCount());
+                outBytes = outList.encode();
+                hasUnread = outList.hasUnread();
+            }
+            else {
+                listSize = mOutContent.msgListingSize(folderName, appParams);
+                hasUnread = mOutContent.msgListingHasUnread(folderName, appParams);
+                outAppParams.setMessageListingSize(listSize);
+                op.noBodyHeader();
+            }
+
+            // Build the application parameter header
+
+            // let the peer know if there are unread messages in the list
+            if(hasUnread)
+            {
+                outAppParams.setNewMessage(1);
+            }else{
+                outAppParams.setNewMessage(0);
+            }
+
+            outAppParams.setMseTime(Calendar.getInstance().getTime().getTime());
+            replyHeaders.setHeader(HeaderSet.APPLICATION_PARAMETER, outAppParams.EncodeParams());
+            op.sendHeaders(replyHeaders);
+
+        } catch (IOException e) {
+            Log.w(TAG,"sendMessageListingRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG,"sendMessageListingRsp: IllegalArgumentException - sending OBEX_HTTP_BAD_REQUEST", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        maxChunkSize = op.getMaxPacketSize(); // This must be called after setting the headers.
+        if(outBytes != null) {
+            try {
+                while (bytesWritten < outBytes.length && sIsAborted == false) {
+                    bytesToWrite = Math.min(maxChunkSize, outBytes.length - bytesWritten);
+                    outStream.write(outBytes, bytesWritten, bytesToWrite);
+                    bytesWritten += bytesToWrite;
+                }
+            } catch (IOException e) {
+                if(V) Log.w(TAG,e);
+                // We were probably aborted or disconnected
+            } finally {
+                if(outStream != null) {
+                    try {
+                        outStream.close();
+                    } catch (IOException e) {
+                        // If an error occurs during close, there is no more cleanup to do
+                    }
+                }
+            }
+            if(bytesWritten != outBytes.length)
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        } else {
+            try {
+                outStream.close();
+            } catch (IOException e) {
+                // If an error occurs during close, there is no more cleanup to do
+            }
+        }
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    /**
+     * Generate and send the Folder listing response based on an application
+     * parameter header. This function call will block until complete or aborted
+     * by the peer. Fragmentation of packets larger than the obex packet size
+     * will be handled by this function.
+     *
+     * @param op
+     *            The OBEX operation.
+     * @param appParams
+     *            The application parameter header
+     * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or
+     *         {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error.
+     */
+    private int sendFolderListingRsp(Operation op, BluetoothMapAppParams appParams){
+        OutputStream outStream = null;
+        byte[] outBytes = null;
+        BluetoothMapAppParams outAppParams = new BluetoothMapAppParams();
+        int maxChunkSize, bytesWritten = 0;
+        HeaderSet replyHeaders = new HeaderSet();
+        int bytesToWrite, maxListCount, listStartOffset;
+        if(appParams == null){
+            appParams = new BluetoothMapAppParams();
+            appParams.setMaxListCount(1024);
+        }
+
+        if(V)
+            Log.v(TAG,"sendFolderList for " + mCurrentFolder.getName());
+
+        try {
+            maxListCount = appParams.getMaxListCount();
+            listStartOffset = appParams.getStartOffset();
+
+            if(listStartOffset == BluetoothMapAppParams.INVALID_VALUE_PARAMETER)
+                listStartOffset = 0;
+
+            if(maxListCount == BluetoothMapAppParams.INVALID_VALUE_PARAMETER)
+                maxListCount = 1024;
+
+            if(maxListCount != 0)
+            {
+                outBytes = mCurrentFolder.encode(listStartOffset, maxListCount);
+                outStream = op.openOutputStream();
+            }
+
+            // Build and set the application parameter header
+            outAppParams.setFolderListingSize(mCurrentFolder.getSubFolderCount());
+            replyHeaders.setHeader(HeaderSet.APPLICATION_PARAMETER, outAppParams.EncodeParams());
+            op.sendHeaders(replyHeaders);
+
+        } catch (IOException e1) {
+            Log.w(TAG,"sendFolderListingRsp: IOException - sending OBEX_HTTP_BAD_REQUEST Exception:", e1);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        } catch (IllegalArgumentException e1) {
+            Log.w(TAG,"sendFolderListingRsp: IllegalArgumentException - sending OBEX_HTTP_BAD_REQUEST Exception:", e1);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        maxChunkSize = op.getMaxPacketSize(); // This must be called after setting the headers.
+
+        if(outBytes != null) {
+            try {
+                while (bytesWritten < outBytes.length && sIsAborted == false) {
+                    bytesToWrite = Math.min(maxChunkSize, outBytes.length - bytesWritten);
+                    outStream.write(outBytes, bytesWritten, bytesToWrite);
+                    bytesWritten += bytesToWrite;
+                }
+            } catch (IOException e) {
+                // We were probably aborted or disconnected
+            } finally {
+                if(outStream != null) {
+                    try {
+                        outStream.close();
+                    } catch (IOException e) {
+                        // If an error occurs during close, there is no more cleanup to do
+                    }
+                }
+            }
+            if(V)
+                Log.v(TAG,"sendFolderList sent " + bytesWritten + " bytes out of "+ outBytes.length);
+            if(bytesWritten == outBytes.length)
+                return ResponseCodes.OBEX_HTTP_OK;
+            else
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    /**
+     * Generate and send the get message response based on an application
+     * parameter header and a handle.
+     *
+     * @param op
+     *            The OBEX operation.
+     * @param appParams
+     *            The application parameter header
+     * @param handle
+     *            The handle of the requested message
+     * @return {@link ResponseCodes.OBEX_HTTP_OK} on success or
+     *         {@link ResponseCodes.OBEX_HTTP_BAD_REQUEST} on error.
+     */
+    private int sendGetMessageRsp(Operation op, String handle, BluetoothMapAppParams appParams){
+        OutputStream outStream ;
+        byte[] outBytes;
+        int maxChunkSize, bytesToWrite, bytesWritten = 0;
+        long msgHandle;
+
+        try {
+            outBytes = mOutContent.getMessage(handle, appParams);
+            outStream = op.openOutputStream();
+
+        } catch (IOException e) {
+            Log.w(TAG,"sendGetMessageRsp: IOException - sending OBEX_HTTP_BAD_REQUEST", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG,"sendGetMessageRsp: IllegalArgumentException (e.g. invalid handle) - sending OBEX_HTTP_BAD_REQUEST", e);
+            return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        maxChunkSize = op.getMaxPacketSize(); // This must be called after setting the headers.
+
+        if(outBytes != null) {
+            try {
+                while (bytesWritten < outBytes.length && sIsAborted == false) {
+                    bytesToWrite = Math.min(maxChunkSize, outBytes.length - bytesWritten);
+                    outStream.write(outBytes, bytesWritten, bytesToWrite);
+                    bytesWritten += bytesToWrite;
+                }
+            } catch (IOException e) {
+                // We were probably aborted or disconnected
+            } finally {
+                if(outStream != null) {
+                    try {
+                        outStream.close();
+                    } catch (IOException e) {
+                        // If an error occurs during close, there is no more cleanup to do
+                    }
+                }
+            }
+            if(bytesWritten == outBytes.length)
+                return ResponseCodes.OBEX_HTTP_OK;
+            else
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+        }
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+
+    private static final void logHeader(HeaderSet hs) {
+        Log.v(TAG, "Dumping HeaderSet " + hs.toString());
+        try {
+            Log.v(TAG, "CONNECTION_ID : " + hs.getHeader(HeaderSet.CONNECTION_ID));
+            Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME));
+            Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE));
+            Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET));
+            Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO));
+            Log.v(TAG, "APPLICATION_PARAMETER : " + hs.getHeader(HeaderSet.APPLICATION_PARAMETER));
+        } catch (IOException e) {
+            Log.e(TAG, "dump HeaderSet error " + e);
+        }
+        Log.v(TAG, "NEW!!! Dumping HeaderSet END");
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapRfcommTransport.java b/src/com/android/bluetooth/map/BluetoothMapRfcommTransport.java
new file mode 100644
index 0000000..90437d8
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapRfcommTransport.java
@@ -0,0 +1,72 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMapRfcommTransport implements ObexTransport {
+    private BluetoothSocket mSocket = null;
+
+    public BluetoothMapRfcommTransport(BluetoothSocket rfs) {
+        super();
+        this.mSocket = rfs;
+    }
+
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    public void connect() throws IOException {
+    }
+
+    public void create() throws IOException {
+    }
+
+    public void disconnect() throws IOException {
+    }
+
+    public void listen() throws IOException {
+    }
+
+    public boolean isConnected() throws IOException {
+        return true;
+    }
+
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java
new file mode 100644
index 0000000..c5c03ef
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -0,0 +1,794 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.obex.ServerSession;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothMap;
+import android.bluetooth.BluetoothUuid;
+import android.bluetooth.BluetoothMap;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.ParcelUuid;
+import android.text.TextUtils;
+import android.util.Log;
+import android.provider.Settings;
+import android.content.IntentFilter;
+import android.content.BroadcastReceiver;
+
+import com.android.bluetooth.R;
+import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder;
+
+
+public class BluetoothMapService extends ProfileService {
+    private static final String TAG = "BluetoothMapService";
+
+    /**
+     * To enable MAP DEBUG/VERBOSE logging - run below cmd in adb shell, and
+     * restart com.android.bluetooth process. only enable DEBUG log:
+     * "setprop log.tag.BluetoothMapService DEBUG"; enable both VERBOSE and
+     * DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE"
+     */
+
+    public static final boolean DEBUG = true;
+
+    public static final boolean VERBOSE = false;
+
+    /**
+     * Intent indicating incoming obex authentication request which is from
+     * PCE(Carkit)
+     */
+    public static final String AUTH_CHALL_ACTION = "com.android.bluetooth.map.authchall";
+
+    /**
+     * Intent indicating timeout for user confirmation, which is sent to
+     * BluetoothMapActivity
+     */
+    public static final String USER_CONFIRM_TIMEOUT_ACTION =
+            "com.android.bluetooth.map.userconfirmtimeout";
+
+    /**
+     * Intent Extra name indicating session key which is sent from
+     * BluetoothMapActivity
+     */
+    public static final String EXTRA_SESSION_KEY = "com.android.bluetooth.map.sessionkey";
+
+    public static final String THIS_PACKAGE_NAME = "com.android.bluetooth";
+
+    public static final int MSG_SERVERSESSION_CLOSE = 5000;
+
+    public static final int MSG_SESSION_ESTABLISHED = 5001;
+
+    public static final int MSG_SESSION_DISCONNECTED = 5002;
+
+    public static final int MSG_OBEX_AUTH_CHALL = 5003;
+
+    private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+
+    private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
+
+    private static final int START_LISTENER = 1;
+
+    private static final int USER_TIMEOUT = 2;
+
+    private static final int DISCONNECT_MAP = 3;
+
+    private PowerManager.WakeLock mWakeLock = null;
+
+    private BluetoothAdapter mAdapter;
+
+    private SocketAcceptThread mAcceptThread = null;
+
+    private BluetoothMapAuthenticator mAuth = null;
+
+    private BluetoothMapObexServer mMapServer;
+
+    private ServerSession mServerSession = null;
+
+    private BluetoothMnsObexClient mBluetoothMnsObexClient = null;
+
+    private BluetoothServerSocket mServerSocket = null;
+
+    private BluetoothSocket mConnSocket = null;
+
+    private BluetoothDevice mRemoteDevice = null;
+
+    private static String sRemoteDeviceName = null;
+
+    private volatile boolean mInterrupted;
+
+    private int mState;
+
+    private boolean isWaitingAuthorization = false;
+
+    // package and class name to which we send intent to check message access access permission
+    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
+    private static final String ACCESS_AUTHORITY_CLASS =
+        "com.android.settings.bluetooth.BluetoothPermissionRequest";
+
+    private static final ParcelUuid[] MAP_UUIDS = {
+        BluetoothUuid.MAP,
+        BluetoothUuid.MNS,
+    };
+
+    public BluetoothMapService() {
+        mState = BluetoothMap.STATE_DISCONNECTED;
+    }
+
+    private void startRfcommSocketListener() {
+        if (DEBUG) Log.d(TAG, "Map Service startRfcommSocketListener");
+
+        if (mAcceptThread == null) {
+            mAcceptThread = new SocketAcceptThread();
+            mAcceptThread.setName("BluetoothMapAcceptThread");
+            mAcceptThread.start();
+        }
+    }
+
+    private final boolean initSocket() {
+        if (DEBUG) Log.d(TAG, "Map Service initSocket");
+
+        boolean initSocketOK = false;
+        final int CREATE_RETRY_TIME = 10;
+
+        // It's possible that create will fail in some cases. retry for 10 times
+        for (int i = 0; (i < CREATE_RETRY_TIME) && !mInterrupted; i++) {
+            initSocketOK = true;
+            try {
+                // It is mandatory for MSE to support initiation of bonding and
+                // encryption.
+                mServerSocket = mAdapter.listenUsingEncryptedRfcommWithServiceRecord
+                    ("MAP SMS/MMS", BluetoothUuid.MAS.getUuid());
+
+            } catch (IOException e) {
+                Log.e(TAG, "Error create RfcommServerSocket " + e.toString());
+                initSocketOK = false;
+            }
+            if (!initSocketOK) {
+                // Need to break out of this loop if BT is being turned off.
+                if (mAdapter == null) break;
+                int state = mAdapter.getState();
+                if ((state != BluetoothAdapter.STATE_TURNING_ON) &&
+                    (state != BluetoothAdapter.STATE_ON)) {
+                    Log.w(TAG, "initServerSocket failed as BT is (being) turned off");
+                    break;
+                }
+                try {
+                    if (VERBOSE) Log.v(TAG, "wait 300 ms");
+                    Thread.sleep(300);
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
+                }
+            } else {
+                break;
+            }
+        }
+        if (mInterrupted) {
+            initSocketOK = false;
+            // close server socket to avoid resource leakage
+            closeServerSocket();
+        }
+
+        if (initSocketOK) {
+            if (VERBOSE) Log.v(TAG, "Succeed to create listening socket ");
+
+        } else {
+            Log.e(TAG, "Error to create listening socket after " + CREATE_RETRY_TIME + " try");
+        }
+        return initSocketOK;
+    }
+
+    private final synchronized void closeServerSocket() {
+        // exit SocketAcceptThread early
+        if (mServerSocket != null) {
+            try {
+                // this will cause mServerSocket.accept() return early with IOException
+                mServerSocket.close();
+                mServerSocket = null;
+            } catch (IOException ex) {
+                Log.e(TAG, "Close Server Socket error: " + ex);
+            }
+        }
+    }
+    private final synchronized void closeConnectionSocket() {
+        if (mConnSocket != null) {
+            try {
+                mConnSocket.close();
+                mConnSocket = null;
+            } catch (IOException e) {
+                Log.e(TAG, "Close Connection Socket error: " + e.toString());
+            }
+        }
+    }
+
+    private final void closeService() {
+        if (DEBUG) Log.d(TAG, "MAP Service closeService in");
+
+        // exit initSocket early
+        mInterrupted = true;
+        closeServerSocket();
+
+        if (mAcceptThread != null) {
+            try {
+                mAcceptThread.shutdown();
+                mAcceptThread.join();
+                mAcceptThread = null;
+            } catch (InterruptedException ex) {
+                Log.w(TAG, "mAcceptThread close error" + ex);
+            }
+        }
+
+        if (mWakeLock != null) {
+            mWakeLock.release();
+            mWakeLock = null;
+        }
+
+        if (mServerSession != null) {
+            mServerSession.close();
+            mServerSession = null;
+        }
+
+        if (mBluetoothMnsObexClient != null) {
+            mBluetoothMnsObexClient.shutdown();
+            mBluetoothMnsObexClient = null;
+        }
+
+        closeConnectionSocket();
+
+        if (mSessionStatusHandler != null) {
+            mSessionStatusHandler.removeCallbacksAndMessages(null);
+        }
+        isWaitingAuthorization = false;
+
+        if (VERBOSE) Log.v(TAG, "MAP Service closeService out");
+    }
+
+    private final void startObexServerSession() throws IOException {
+        if (DEBUG) Log.d(TAG, "Map Service startObexServerSession");
+
+        // acquire the wakeLock before start Obex transaction thread
+        if (mWakeLock == null) {
+            PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+            mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    "StartingObexMapTransaction");
+            mWakeLock.setReferenceCounted(false);
+            mWakeLock.acquire();
+        }
+
+        mBluetoothMnsObexClient = new BluetoothMnsObexClient(this, mRemoteDevice);
+        mMapServer = new BluetoothMapObexServer(mSessionStatusHandler, this,
+                                                mBluetoothMnsObexClient);
+        synchronized (this) {
+            // We need to get authentication now that obex server is up
+            mAuth = new BluetoothMapAuthenticator(mSessionStatusHandler);
+            mAuth.setChallenged(false);
+            mAuth.setCancelled(false);
+        }
+        // setup RFCOMM transport
+        BluetoothMapRfcommTransport transport = new BluetoothMapRfcommTransport(mConnSocket);
+        mServerSession = new ServerSession(transport, mMapServer, mAuth);
+        setState(BluetoothMap.STATE_CONNECTED);
+        if (VERBOSE) {
+            Log.v(TAG, "startObexServerSession() success!");
+        }
+    }
+
+    private void stopObexServerSession() {
+        if (DEBUG) Log.d(TAG, "MAP Service stopObexServerSession");
+
+        // Release the wake lock if obex transaction is over
+        if (mWakeLock != null) {
+            mWakeLock.release();
+            mWakeLock = null;
+        }
+
+        if (mServerSession != null) {
+            mServerSession.close();
+            mServerSession = null;
+        }
+
+        mAcceptThread = null;
+
+        if(mBluetoothMnsObexClient != null) {
+            mBluetoothMnsObexClient.shutdown();
+            mBluetoothMnsObexClient = null;
+        }
+        closeConnectionSocket();
+
+        // Last obex transaction is finished, we start to listen for incoming
+        // connection again
+        if (mAdapter.isEnabled()) {
+            startRfcommSocketListener();
+        }
+        setState(BluetoothMap.STATE_DISCONNECTED);
+    }
+
+
+
+    /**
+     * A thread that runs in the background waiting for remote rfcomm
+     * connect.Once a remote socket connected, this thread shall be
+     * shutdown.When the remote disconnect,this thread shall run again waiting
+     * for next request.
+     */
+    private class SocketAcceptThread extends Thread {
+
+        private boolean stopped = false;
+
+        @Override
+        public void run() {
+            BluetoothServerSocket serverSocket;
+            if (mServerSocket == null) {
+                if (!initSocket()) {
+                    return;
+                }
+            }
+
+            while (!stopped) {
+                try {
+                    if (DEBUG) Log.d(TAG, "Accepting socket connection...");
+                    serverSocket = mServerSocket;
+                    if(serverSocket == null) {
+                        Log.w(TAG, "mServerSocket is null");
+                        break;
+                    }
+                    mConnSocket = serverSocket.accept();
+                    if (DEBUG) Log.d(TAG, "Accepted socket connection...");
+                    synchronized (BluetoothMapService.this) {
+                        if (mConnSocket == null) {
+                            Log.w(TAG, "mConnSocket is null");
+                            break;
+                        }
+                        mRemoteDevice = mConnSocket.getRemoteDevice();
+                    }
+                    if (mRemoteDevice == null) {
+                        Log.i(TAG, "getRemoteDevice() = null");
+                        break;
+                    }
+
+                    sRemoteDeviceName = mRemoteDevice.getName();
+                    // In case getRemoteName failed and return null
+                    if (TextUtils.isEmpty(sRemoteDeviceName)) {
+                        sRemoteDeviceName = getString(R.string.defaultname);
+                    }
+                    boolean trust = mRemoteDevice.getTrustState();
+                    if (DEBUG) Log.d(TAG, "GetTrustState() = " + trust);
+
+
+                    if (trust) {
+                        try {
+                            if (DEBUG) Log.d(TAG, "incoming connection accepted from: "
+                                + sRemoteDeviceName + " automatically as trusted device");
+                            startObexServerSession();
+                        } catch (IOException ex) {
+                            Log.e(TAG, "catch exception starting obex server session"
+                                    + ex.toString());
+                        }
+                    } else {
+                        Intent intent = new
+                            Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST);
+                        intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
+                        intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                        BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS);
+                        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
+
+                        isWaitingAuthorization = true;
+                        sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+
+                        if (DEBUG) Log.d(TAG, "waiting for authorization for connection from: "
+                                + sRemoteDeviceName);
+
+                    }
+                    stopped = true; // job done ,close this thread;
+                } catch (IOException ex) {
+                    stopped=true;
+                    if (VERBOSE) Log.v(TAG, "Accept exception: " + ex.toString());
+                }
+            }
+        }
+
+        void shutdown() {
+            stopped = true;
+            interrupt();
+        }
+    }
+
+    private final Handler mSessionStatusHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (VERBOSE) Log.v(TAG, "Handler(): got msg=" + msg.what);
+
+            switch (msg.what) {
+                case START_LISTENER:
+                    if (mAdapter.isEnabled()) {
+                        startRfcommSocketListener();
+                    }
+                    break;
+                case USER_TIMEOUT:
+                    Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL);
+                    intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
+                    intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                    BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS);
+                    sendBroadcast(intent);
+                    isWaitingAuthorization = false;
+                    stopObexServerSession();
+                    break;
+                case MSG_SERVERSESSION_CLOSE:
+                    stopObexServerSession();
+                    break;
+                case MSG_SESSION_ESTABLISHED:
+                    break;
+                case MSG_SESSION_DISCONNECTED:
+                    // handled elsewhere
+                    break;
+                case DISCONNECT_MAP:
+                    disconnectMap((BluetoothDevice)msg.obj);
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+
+
+   public int getState() {
+        return mState;
+    }
+
+    public BluetoothDevice getRemoteDevice() {
+        return mRemoteDevice;
+    }
+    private void setState(int state) {
+        setState(state, BluetoothMap.RESULT_SUCCESS);
+    }
+
+    private synchronized void setState(int state, int result) {
+        if (state != mState) {
+            if (DEBUG) Log.d(TAG, "Map state " + mState + " -> " + state + ", result = "
+                    + result);
+            int prevState = mState;
+            mState = state;
+            Intent intent = new Intent(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
+            intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
+            intent.putExtra(BluetoothProfile.EXTRA_STATE, mState);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
+            sendBroadcast(intent, BLUETOOTH_PERM);
+            AdapterService s = AdapterService.getAdapterService();
+            if (s != null) {
+                s.onProfileConnectionStateChanged(mRemoteDevice, BluetoothProfile.MAP,
+                        mState, prevState);
+            }
+        }
+    }
+
+    public static String getRemoteDeviceName() {
+        return sRemoteDeviceName;
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        mSessionStatusHandler.sendMessage(mSessionStatusHandler.obtainMessage(DISCONNECT_MAP, 0, 0, device));
+        return true;
+    }
+
+    public boolean disconnectMap(BluetoothDevice device) {
+        boolean result = false;
+        if (DEBUG) Log.d(TAG, "disconnectMap");
+        if (getRemoteDevice().equals(device)) {
+            switch (mState) {
+                case BluetoothMap.STATE_CONNECTED:
+                    if (mServerSession != null) {
+                        mServerSession.close();
+                        mServerSession = null;
+                    }
+                    if(mBluetoothMnsObexClient != null) {
+                        mBluetoothMnsObexClient.shutdown();
+                        mBluetoothMnsObexClient = null;
+                    }
+                    closeConnectionSocket();
+
+                    setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
+                    result = true;
+                    break;
+                default:
+                    break;
+                }
+        }
+        return result;
+    }
+
+    public List<BluetoothDevice> getConnectedDevices() {
+        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
+        synchronized(this) {
+            if (mState == BluetoothMap.STATE_CONNECTED && mRemoteDevice != null) {
+                devices.add(mRemoteDevice);
+            }
+        }
+        return devices;
+    }
+
+    public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+        List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
+        Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
+        int connectionState;
+        synchronized (this) {
+            for (BluetoothDevice device : bondedDevices) {
+                ParcelUuid[] featureUuids = device.getUuids();
+                if (!BluetoothUuid.containsAnyUuid(featureUuids, MAP_UUIDS)) {
+                    continue;
+                }
+                connectionState = getConnectionState(device);
+                for(int i = 0; i < states.length; i++) {
+                    if (connectionState == states[i]) {
+                        deviceList.add(device);
+                    }
+                }
+            }
+        }
+        return deviceList;
+    }
+
+    public int getConnectionState(BluetoothDevice device) {
+        synchronized(this) {
+            if (getState() == BluetoothMap.STATE_CONNECTED && getRemoteDevice().equals(device)) {
+                return BluetoothProfile.STATE_CONNECTED;
+            } else {
+                return BluetoothProfile.STATE_DISCONNECTED;
+            }
+        }
+    }
+
+    public boolean setPriority(BluetoothDevice device, int priority) {
+        Settings.Global.putInt(getContentResolver(),
+            Settings.Global.getBluetoothMapPriorityKey(device.getAddress()),
+            priority);
+        if (DEBUG) Log.d(TAG, "Saved priority " + device + " = " + priority);
+        return true;
+    }
+
+    public int getPriority(BluetoothDevice device) {
+        int priority = Settings.Global.getInt(getContentResolver(),
+            Settings.Global.getBluetoothMapPriorityKey(device.getAddress()),
+            BluetoothProfile.PRIORITY_UNDEFINED);
+        return priority;
+    }
+
+    @Override
+    protected IProfileServiceBinder initBinder() {
+        return new BluetoothMapBinder(this);
+    }
+
+    @Override
+    protected boolean start() {
+        if (DEBUG) Log.d(TAG, "start()");
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        try {
+            registerReceiver(mMapReceiver, filter);
+        } catch (Exception e) {
+            Log.w(TAG,"Unable to register map receiver",e);
+        }
+        mInterrupted = false;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        // start RFCOMM listener
+        mSessionStatusHandler.sendMessage(mSessionStatusHandler
+                .obtainMessage(START_LISTENER));
+        return true;
+    }
+
+    @Override
+    protected boolean stop() {
+        if (DEBUG) Log.d(TAG, "stop()");
+        try {
+            unregisterReceiver(mMapReceiver);
+        } catch (Exception e) {
+            Log.w(TAG,"Unable to unregister map receiver",e);
+        }
+
+        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
+        closeService();
+        return true;
+    }
+
+    public boolean cleanup()  {
+        if (DEBUG) Log.d(TAG, "cleanup()");
+        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
+        closeService();
+        return true;
+    }
+
+    private MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver();
+
+    private class MapBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) Log.d(TAG, "onReceive");
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                               BluetoothAdapter.ERROR);
+                if (state == BluetoothAdapter.STATE_TURNING_OFF) {
+                    if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF");
+                    // Release all resources
+                    closeService();
+                } else if (state == BluetoothAdapter.STATE_ON) {
+                    if (DEBUG) Log.d(TAG, "STATE_ON");
+                    mInterrupted = false;
+                    // start RFCOMM listener
+                    mSessionStatusHandler.sendMessage(mSessionStatusHandler
+                                  .obtainMessage(START_LISTENER));
+                }
+            } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
+                int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                               BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
+                if (DEBUG) Log.d(TAG, "Received ACTION_CONNECTION_ACCESS_REPLY:" +
+                           requestType + ":" + isWaitingAuthorization);
+                if ((!isWaitingAuthorization) ||
+                    (requestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) {
+                    // this reply is not for us
+                    return;
+                }
+
+                isWaitingAuthorization = false;
+
+                if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
+                                       BluetoothDevice.CONNECTION_ACCESS_NO) ==
+                    BluetoothDevice.CONNECTION_ACCESS_YES) {
+                    //bluetooth connection accepted by user
+                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
+                        boolean result = mRemoteDevice.setTrust(true);
+                        if (DEBUG) Log.d(TAG, "setTrust() result=" + result);
+                    }
+                    try {
+                        if (mConnSocket != null) {
+                            // start obex server and rfcomm connection
+                            startObexServerSession();
+                        } else {
+                            stopObexServerSession();
+                        }
+                    } catch (IOException ex) {
+                        Log.e(TAG, "Caught the error: " + ex.toString());
+                    }
+                } else {
+                    stopObexServerSession();
+                }
+            }
+        }
+    };
+
+    //Binder object: Must be static class or memory leak may occur
+    /**
+     * This class implements the IBluetoothMap interface - or actually it validates the
+     * preconditions for calling the actual functionality in the MapService, and calls it.
+     */
+    private static class BluetoothMapBinder extends IBluetoothMap.Stub
+        implements IProfileServiceBinder {
+        private BluetoothMapService mService;
+
+        private BluetoothMapService getService() {
+            if (!Utils.checkCaller()) {
+                Log.w(TAG,"MAP call not allowed for non-active user");
+                return null;
+            }
+
+            if (mService != null && mService.isAvailable()) {
+                mService.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+                return mService;
+            }
+            return null;
+        }
+
+        BluetoothMapBinder(BluetoothMapService service) {
+            if (VERBOSE) Log.v(TAG, "BluetoothMapBinder()");
+            mService = service;
+        }
+
+        public boolean cleanup()  {
+            mService = null;
+            return true;
+        }
+
+        public int getState() {
+            if (VERBOSE) Log.v(TAG, "getState()");
+            BluetoothMapService service = getService();
+            if (service == null) return BluetoothMap.STATE_DISCONNECTED;
+            return getService().getState();
+        }
+
+        public BluetoothDevice getClient() {
+            if (VERBOSE) Log.v(TAG, "getClient()");
+            BluetoothMapService service = getService();
+            if (service == null) return null;
+            Log.v(TAG, "getClient() - returning " + service.getRemoteDevice());
+            return service.getRemoteDevice();
+        }
+
+        public boolean isConnected(BluetoothDevice device) {
+            if (VERBOSE) Log.v(TAG, "isConnected()");
+            BluetoothMapService service = getService();
+            if (service == null) return false;
+            return service.getState() == BluetoothMap.STATE_CONNECTED && service.getRemoteDevice().equals(device);
+        }
+
+        public boolean connect(BluetoothDevice device) {
+            if (VERBOSE) Log.v(TAG, "connect()");
+            BluetoothMapService service = getService();
+            if (service == null) return false;
+            return false;
+        }
+
+        public boolean disconnect(BluetoothDevice device) {
+            if (VERBOSE) Log.v(TAG, "disconnect()");
+            BluetoothMapService service = getService();
+            if (service == null) return false;
+            return service.disconnect(device);
+        }
+
+        public List<BluetoothDevice> getConnectedDevices() {
+            if (VERBOSE) Log.v(TAG, "getConnectedDevices()");
+            BluetoothMapService service = getService();
+            if (service == null) return new ArrayList<BluetoothDevice>(0);
+            return service.getConnectedDevices();
+        }
+
+        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+            if (VERBOSE) Log.v(TAG, "getDevicesMatchingConnectionStates()");
+            BluetoothMapService service = getService();
+            if (service == null) return new ArrayList<BluetoothDevice>(0);
+            return service.getDevicesMatchingConnectionStates(states);
+        }
+
+        public int getConnectionState(BluetoothDevice device) {
+            if (VERBOSE) Log.v(TAG, "getConnectionState()");
+            BluetoothMapService service = getService();
+            if (service == null) return BluetoothProfile.STATE_DISCONNECTED;
+            return service.getConnectionState(device);
+        }
+
+        public boolean setPriority(BluetoothDevice device, int priority) {
+            BluetoothMapService service = getService();
+            if (service == null) return false;
+            return service.setPriority(device, priority);
+        }
+
+        public int getPriority(BluetoothDevice device) {
+            BluetoothMapService service = getService();
+            if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED;
+            return service.getPriority(device);
+        }
+    };
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
new file mode 100644
index 0000000..2070c26
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
@@ -0,0 +1,748 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
+import static com.android.internal.telephony.SmsConstants.ENCODING_7BIT;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Random;
+
+import android.telephony.PhoneNumberUtils;
+import android.telephony.SmsMessage;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.internal.telephony.*;
+/*import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
+import com.android.internal.telephony.SmsConstants;*/
+import com.android.internal.telephony.SmsHeader;
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
+import com.android.internal.telephony.cdma.sms.*;
+import com.android.internal.telephony.gsm.SmsMessage.SubmitPdu;
+
+public class BluetoothMapSmsPdu {
+
+    private static final String TAG = "BluetoothMapSmsPdu";
+    private static final boolean V = false;
+    private static int INVALID_VALUE = -1;
+    public static int SMS_TYPE_GSM = 1;
+    public static int SMS_TYPE_CDMA = 2;
+
+
+    /* TODO: We need to handle the SC-address mentioned in errata 4335.
+     * Since the definition could be read in three different ways, I have asked
+     * the car working group for clarification, and are awaiting confirmation that
+     * this clarification will go into the MAP spec:
+     *  "The native format should be <sc_addr><tpdu> where <sc_addr> is <length><ton><1..10 octet of address>
+     *   coded according to 24.011. The IEI is not to be used, as the fixed order of the data makes a type 4 LV
+     *   information element sufficient. <length> is a single octet which value is the length of the value-field
+     *   in octets including both the <ton> and the <address>."
+     * */
+
+
+    public static class SmsPdu {
+        private byte[] data;
+        private byte[] scAddress = {0}; // At the moment we do not use the scAddress, hence set the length to 0.
+        private int userDataMsgOffset = 0;
+        private int encoding;
+        private int languageTable;
+        private int languageShiftTable;
+        private int type;
+
+        /* Members used for pdu decoding */
+        private int userDataSeptetPadding = INVALID_VALUE;
+        private int msgSeptetCount = 0;
+
+        SmsPdu(byte[] data, int type){
+            this.data = data;
+            this.encoding = INVALID_VALUE;
+            this.type = type;
+            this.languageTable = INVALID_VALUE;
+            this.languageShiftTable = INVALID_VALUE;
+            this.userDataMsgOffset = gsmSubmitGetTpUdOffset(); // Assume no user data header
+        }
+
+        /**
+         * Create a pdu instance based on the data generated on this device.
+         * @param data
+         * @param encoding
+         * @param type
+         * @param languageTable
+         */
+        SmsPdu(byte[]data, int encoding, int type, int languageTable){
+            this.data = data;
+            this.encoding = encoding;
+            this.type = type;
+            this.languageTable = languageTable;
+        }
+        public byte[] getData(){
+            return data;
+        }
+        public byte[] getScAddress(){
+            return scAddress;
+        }
+        public void setEncoding(int encoding) {
+            this.encoding = encoding;
+        }
+        public int getEncoding(){
+            return encoding;
+        }
+        public int getType(){
+            return type;
+        }
+        public int getUserDataMsgOffset() {
+            return userDataMsgOffset;
+        }
+        /** The user data message payload size in bytes - excluding the user data header. */
+        public int getUserDataMsgSize() {
+            return data.length - userDataMsgOffset;
+        }
+
+        public int getLanguageShiftTable() {
+            return languageShiftTable;
+        }
+
+        public int getLanguageTable() {
+            return languageTable;
+        }
+
+        public int getUserDataSeptetPadding() {
+            return userDataSeptetPadding;
+        }
+
+        public int getMsgSeptetCount() {
+            return msgSeptetCount;
+        }
+
+
+        /* PDU parsing/modification functionality */
+        private final static byte TELESERVICE_IDENTIFIER                    = 0x00;
+        private final static byte SERVICE_CATEGORY                          = 0x01;
+        private final static byte ORIGINATING_ADDRESS                       = 0x02;
+        private final static byte ORIGINATING_SUB_ADDRESS                   = 0x03;
+        private final static byte DESTINATION_ADDRESS                       = 0x04;
+        private final static byte DESTINATION_SUB_ADDRESS                   = 0x05;
+        private final static byte BEARER_REPLY_OPTION                       = 0x06;
+        private final static byte CAUSE_CODES                               = 0x07;
+        private final static byte BEARER_DATA                               = 0x08;
+
+        /**
+         * Find and return the offset to the specified parameter ID
+         * @param parameterId The parameter ID to find
+         * @return the offset in number of bytes to the parameterID entry in the pdu data.
+         * The byte at the offset contains the parameter ID, the byte following contains the
+         * parameter length, and offset + 2 is the first byte of the parameter data.
+         */
+        private int cdmaGetParameterOffset(byte parameterId) {
+            ByteArrayInputStream pdu = new ByteArrayInputStream(data);
+            int offset = 0;
+            boolean found = false;
+
+            try {
+                pdu.skip(1); // Skip the message type
+
+                while (pdu.available() > 0) {
+                    int currentId = pdu.read();
+                    int currentLen = pdu.read();
+
+                    if(currentId == parameterId) {
+                        found = true;
+                        break;
+                    }
+                    else {
+                        pdu.skip(currentLen);
+                        offset += 2 + currentLen;
+                    }
+                }
+                pdu.close();
+            } catch (Exception e) {
+                Log.e(TAG, "cdmaGetParameterOffset: ", e);
+            }
+
+            if(found)
+                return offset;
+            else
+                return 0;
+        }
+
+        private final static byte BEARER_DATA_MSG_ID = 0x00;
+
+        private int cdmaGetSubParameterOffset(byte subParameterId) {
+            ByteArrayInputStream pdu = new ByteArrayInputStream(data);
+            int offset = 0;
+            boolean found = false;
+            offset = cdmaGetParameterOffset(BEARER_DATA) + 2; // Add to offset the BEARER_DATA parameter id and length bytes
+            pdu.skip(offset);
+            try {
+
+                while (pdu.available() > 0) {
+                    int currentId = pdu.read();
+                    int currentLen = pdu.read();
+
+                    if(currentId == subParameterId) {
+                        found = true;
+                        break;
+                    }
+                    else {
+                        pdu.skip(currentLen);
+                        offset += 2 + currentLen;
+                    }
+                }
+                pdu.close();
+            } catch (Exception e) {
+                Log.e(TAG, "cdmaGetParameterOffset: ", e);
+            }
+
+            if(found)
+                return offset;
+            else
+                return 0;
+        }
+
+
+        public void cdmaChangeToDeliverPdu(long date){
+            /* Things to change:
+             *  - Message Type in bearer data (Not the overall point-to-point type)
+             *  - Change address ID from destination to originating (sub addresses are not used)
+             *  - A time stamp is not mandatory.
+             */
+            int offset;
+            offset = cdmaGetParameterOffset(DESTINATION_ADDRESS);
+            data[offset] = ORIGINATING_ADDRESS;
+            offset = cdmaGetParameterOffset(DESTINATION_SUB_ADDRESS);
+            data[offset] = ORIGINATING_SUB_ADDRESS;
+
+            offset = cdmaGetSubParameterOffset(BEARER_DATA_MSG_ID);
+
+//            if(data != null && data.length > 2) {
+                int tmp = data[offset+2] & 0xff; // Skip the subParam ID and length, and read the first byte.
+                // Mask out the type
+                tmp &= 0x0f;
+                // Set the new type
+                tmp |= ((BearerData.MESSAGE_TYPE_DELIVER << 4) & 0xf0);
+                // Store the result
+                data[offset+2] = (byte) tmp;
+
+//            }
+                /* TODO: Do we need to change anything in the user data? Not sure if the user data is
+                 *        just encoded using GSM encoding, or it is an actual GSM submit PDU embedded
+                 *        in the user data?
+                 */
+
+        }
+
+        private static final byte TP_MIT_DELIVER       = 0x00; // bit 0 and 1
+        private static final byte TP_MMS_NO_MORE       = 0x04; // bit 2
+        private static final byte TP_RP_NO_REPLY_PATH  = 0x00; // bit 7
+        private static final byte TP_UDHI_MASK         = 0x40; // bit 6
+        private static final byte TP_SRI_NO_REPORT     = 0x00; // bit 5
+
+        private int gsmSubmitGetTpPidOffset() {
+            /* calculate the offset to TP_PID.
+             * The TP-DA has variable length, and the length excludes the 2 byte length and type headers.
+             * The TP-DA is two bytes within the PDU */
+            int offset = 2 + ((data[2]+1) & 0xff)/2 + 2; // data[2] is the number of semi-octets in the phone number (ceil result)
+            if((offset > data.length) || (offset > (2 + 12))) // max length of TP_DA is 12 bytes + two byte offset.
+                throw new IllegalArgumentException("wrongly formatted gsm submit PDU. offset = " + offset);
+            return offset;
+        }
+
+        public int gsmSubmitGetTpDcs() {
+            return data[gsmSubmitGetTpDcsOffset()] & 0xff;
+        }
+
+        public boolean gsmSubmitHasUserDataHeader() {
+            return ((data[0] & 0xff) & TP_UDHI_MASK) == TP_UDHI_MASK;
+        }
+
+        private int gsmSubmitGetTpDcsOffset() {
+            return gsmSubmitGetTpPidOffset() + 1;
+        }
+
+        private int gsmSubmitGetTpUdlOffset() {
+            switch(((data[0]  & 0xff) & (0x08 | 0x04))>>2) {
+            case 0: // Not TP-VP present
+                return gsmSubmitGetTpPidOffset() + 2;
+            case 1: // TP-VP relative format
+                return gsmSubmitGetTpPidOffset() + 2 + 1;
+            case 2: // TP-VP enhanced format
+            case 3: // TP-VP absolute format
+                break;
+            }
+            return gsmSubmitGetTpPidOffset() + 2 + 7;
+        }
+        private int gsmSubmitGetTpUdOffset() {
+            return gsmSubmitGetTpUdlOffset() + 1;
+        }
+
+        public void gsmDecodeUserDataHeader() {
+            ByteArrayInputStream pdu = new ByteArrayInputStream(data);
+
+            pdu.skip(gsmSubmitGetTpUdlOffset());
+            int userDataLength = pdu.read();
+            if(gsmSubmitHasUserDataHeader() == true) {
+                int userDataHeaderLength = pdu.read();
+
+                // This part is only needed to extract the language info, hence only needed for 7 bit encoding
+                if(encoding == SmsConstants.ENCODING_7BIT)
+                {
+                    byte[] udh = new byte[userDataHeaderLength];
+                    try {
+                        pdu.read(udh);
+                    } catch (IOException e) {
+                        Log.w(TAG, "unable to read userDataHeader", e);
+                    }
+                    SmsHeader userDataHeader = SmsHeader.fromByteArray(udh);
+                    languageTable = userDataHeader.languageTable;
+                    languageShiftTable = userDataHeader.languageShiftTable;
+
+                    int headerBits = (userDataHeaderLength + 1) * 8;
+                    int headerSeptets = headerBits / 7;
+                    headerSeptets += (headerBits % 7) > 0 ? 1 : 0;
+                    userDataSeptetPadding = (headerSeptets * 7) - headerBits;
+                    msgSeptetCount = userDataLength - headerSeptets;
+                }
+                userDataMsgOffset = gsmSubmitGetTpUdOffset() + userDataHeaderLength + 1; // Add the byte containing the length
+            }
+            else
+            {
+                userDataSeptetPadding = 0;
+                msgSeptetCount = userDataLength;
+                userDataMsgOffset = gsmSubmitGetTpUdOffset();
+            }
+            if(V) {
+                Log.v(TAG, "encoding:" + encoding);
+                Log.v(TAG, "msgSeptetCount:" + msgSeptetCount);
+                Log.v(TAG, "userDataSeptetPadding:" + userDataSeptetPadding);
+                Log.v(TAG, "languageShiftTable:" + languageShiftTable);
+                Log.v(TAG, "languageTable:" + languageTable);
+                Log.v(TAG, "userDataMsgOffset:" + userDataMsgOffset);
+            }
+        }
+
+        private void gsmWriteDate(ByteArrayOutputStream header, long time) throws UnsupportedEncodingException {
+            SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");
+            Date date = new Date(time);
+            String timeStr = format.format(date); // Format to YYMMDDTHHMMSS UTC time
+            if(V) Log.v(TAG, "Generated time string: " + timeStr);
+            byte[] timeChars = timeStr.getBytes("US-ASCII");
+
+            for(int i = 0, n = timeStr.length(); i < n; i+=2) {
+                header.write((timeChars[i+1]-0x30) << 4 | (timeChars[i]-0x30)); // Offset from ascii char to decimal value
+            }
+
+            Calendar cal = Calendar.getInstance();
+            int offset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (15 * 60 * 1000); /* offset in quarters of an hour */
+            String offsetString;
+            if(offset < 0) {
+                offsetString = String.format("%1$02d", -(offset));
+                char[] offsetChars = offsetString.toCharArray();
+                header.write((offsetChars[1]-0x30) << 4 | 0x40 | (offsetChars[0]-0x30));
+            }
+            else {
+                offsetString = String.format("%1$02d", offset);
+                char[] offsetChars = offsetString.toCharArray();
+                header.write((offsetChars[1]-0x30) << 4 | (offsetChars[0]-0x30));
+            }
+        }
+
+/*        private void gsmSubmitExtractUserData() {
+            int userDataLength = data[gsmSubmitGetTpUdlOffset()];
+            userData = new byte[userDataLength];
+            System.arraycopy(userData, 0, data, gsmSubmitGetTpUdOffset(), userDataLength);
+
+        }*/
+
+        /**
+         * Change the GSM Submit Pdu data in this object to a deliver PDU:
+         *  - Build the new header with deliver PDU type, originator and time stamp.
+         *  - Extract encoding details from the submit PDU
+         *  - Extract user data length and user data from the submitPdu
+         *  - Build the new PDU
+         * @param date the time stamp to include (The value is the number of milliseconds since Jan. 1, 1970 GMT.)
+         * @param originator the phone number to include in the deliver PDU header. Any undesired characters,
+         *                    such as '-' will be striped from this string.
+         */
+        public void gsmChangeToDeliverPdu(long date, String originator)
+        {
+            ByteArrayOutputStream newPdu = new ByteArrayOutputStream(22); // 22 is the max length of the deliver pdu header
+            byte[] encodedAddress;
+            int userDataLength = 0;
+            try {
+                newPdu.write(TP_MIT_DELIVER | TP_MMS_NO_MORE | TP_RP_NO_REPLY_PATH | TP_SRI_NO_REPORT
+                             | (data[0] & 0xff)  & TP_UDHI_MASK);
+                encodedAddress = PhoneNumberUtils.networkPortionToCalledPartyBCDWithLength(originator);
+                if(encodedAddress != null) {
+                    int padding = (encodedAddress[encodedAddress.length-1] & 0xf0) == 0xf0 ? 1 : 0;
+                    encodedAddress[0] = (byte)((encodedAddress[0]-1)*2 - padding); // Convert from octet length to semi octet length
+                    // Insert originator address into the header - this includes the length
+                    newPdu.write(encodedAddress);
+                } else {
+                    newPdu.write(0);    /* zero length */
+                    newPdu.write(0x81); /* International type */
+                }
+
+                newPdu.write(data[gsmSubmitGetTpPidOffset()]);
+                newPdu.write(data[gsmSubmitGetTpDcsOffset()]);
+                // Generate service center time stamp
+                gsmWriteDate(newPdu, date);
+                userDataLength = (data[gsmSubmitGetTpUdlOffset()] & 0xff);
+                newPdu.write(userDataLength);
+                // Copy the pdu user data - keep in mind that the userDataLength is not the length in bytes for 7-bit encoding.
+                newPdu.write(data, gsmSubmitGetTpUdOffset(), data.length - gsmSubmitGetTpUdOffset());
+            } catch (IOException e) {
+                Log.e(TAG, "", e);
+                throw new IllegalArgumentException("Failed to change type to deliver PDU.");
+            }
+            data = newPdu.toByteArray();
+        }
+
+        /* SMS encoding to bmessage strings */
+        /** get the encoding type as a bMessage string */
+        public String getEncodingString(){
+            if(type == SMS_TYPE_GSM)
+            {
+                switch(encoding){
+                case SmsMessage.ENCODING_7BIT:
+                    if(languageTable == 0)
+                        return "G-7BIT";
+                    else
+                        return "G-7BITEXT";
+                case SmsMessage.ENCODING_8BIT:
+                    return "G-8BIT";
+                case SmsMessage.ENCODING_16BIT:
+                    return "G-16BIT";
+                case SmsMessage.ENCODING_UNKNOWN:
+                    default:
+                    return "";
+                }
+            } else /* SMS_TYPE_CDMA */ {
+                switch(encoding){
+                case SmsMessage.ENCODING_7BIT:
+                    return "C-7ASCII";
+                case SmsMessage.ENCODING_8BIT:
+                    return "C-8BIT";
+                case SmsMessage.ENCODING_16BIT:
+                    return "C-UNICODE";
+                case SmsMessage.ENCODING_KSC5601:
+                    return "C-KOREAN";
+                case SmsMessage.ENCODING_UNKNOWN:
+                    default:
+                    return "";
+                }
+            }
+        }
+    }
+
+    private static int sConcatenatedRef = new Random().nextInt(256);
+
+    protected static int getNextConcatenatedRef() {
+        sConcatenatedRef += 1;
+        return sConcatenatedRef;
+    }
+    public static ArrayList<SmsPdu> getSubmitPdus(String messageText, String address){
+        /* Use the generic GSM/CDMA SMS Message functionality within Android to generate the
+         * SMS PDU's as once generated to send the SMS message.
+         */
+
+        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType(); // TODO: Change to use: ((TelephonyManager)myContext.getSystemService(Context.TELEPHONY_SERVICE))
+        int phoneType;
+        GsmAlphabet.TextEncodingDetails ted = (PHONE_TYPE_CDMA == activePhone) ?
+            com.android.internal.telephony.cdma.SmsMessage.calculateLength((CharSequence)messageText, false) :
+            com.android.internal.telephony.gsm.SmsMessage.calculateLength((CharSequence)messageText, false);
+
+        SmsPdu newPdu;
+        String destinationAddress;
+        int msgCount = ted.msgCount;
+        int encoding;
+        int languageTable;
+        int languageShiftTable;
+        int refNumber = getNextConcatenatedRef() & 0x00FF;
+        ArrayList<String> smsFragments = SmsMessage.fragmentText(messageText);
+        ArrayList<SmsPdu> pdus = new ArrayList<SmsPdu>(msgCount);
+        byte[] data;
+
+        // Default to GSM, as this code should not be used, if we neither have CDMA not GSM.
+        phoneType = (activePhone == PHONE_TYPE_CDMA) ? SMS_TYPE_CDMA : SMS_TYPE_GSM;
+        encoding = ted.codeUnitSize;
+        languageTable = ted.languageTable;
+        languageShiftTable = ted.languageShiftTable;
+        destinationAddress = PhoneNumberUtils.stripSeparators(address);
+        if(destinationAddress == null || destinationAddress.length() < 2) {
+            destinationAddress = "12"; // Ensure we add a number at least 2 digits as specified in the GSM spec.
+        }
+
+        if(msgCount == 1){
+            data = SmsMessage.getSubmitPdu(null, destinationAddress, smsFragments.get(0), false).encodedMessage;
+            newPdu = new SmsPdu(data, encoding, phoneType, languageTable);
+            pdus.add(newPdu);
+        }
+        else
+        {
+            /* This code is a reduced copy of the actual code used in the Android SMS sub system,
+             * hence the comments have been left untouched. */
+            for(int i = 0; i < msgCount; i++){
+                SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+                concatRef.refNumber = refNumber;
+                concatRef.seqNumber = i + 1;  // 1-based sequence
+                concatRef.msgCount = msgCount;
+                // We currently set this to true since our messaging app will never
+                // send more than 255 parts (it converts the message to MMS well before that).
+                // However, we should support 3rd party messaging apps that might need 16-bit
+                // references
+                // Note:  It's not sufficient to just flip this bit to true; it will have
+                // ripple effects (several calculations assume 8-bit ref).
+                concatRef.isEightBits = true;
+                SmsHeader smsHeader = new SmsHeader();
+                smsHeader.concatRef = concatRef;
+
+                /* Depending on the type, call either GSM or CDMA getSubmitPdu(). The encoding
+                 * will be determined(again) by getSubmitPdu().
+                 * All packets need to be encoded using the same encoding, as the bMessage
+                 * only have one filed to describe the encoding for all messages in a concatenated
+                 * SMS... */
+                if (encoding == SmsConstants.ENCODING_7BIT) {
+                    smsHeader.languageTable = languageTable;
+                    smsHeader.languageShiftTable = languageShiftTable;
+                }
+
+                if(phoneType == SMS_TYPE_GSM){
+                    data = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(null, destinationAddress,
+                            smsFragments.get(i), false, SmsHeader.toByteArray(smsHeader),
+                            encoding, languageTable, languageShiftTable).encodedMessage;
+                } else { // SMS_TYPE_CDMA
+                    UserData uData = new UserData();
+                    uData.payloadStr = smsFragments.get(i);
+                    uData.userDataHeader = smsHeader;
+                    if (encoding == SmsConstants.ENCODING_7BIT) {
+                        uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
+                    } else { // assume UTF-16
+                        uData.msgEncoding = UserData.ENCODING_UNICODE_16;
+                    }
+                    uData.msgEncodingSet = true;
+                    data = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(destinationAddress,
+                            uData, false).encodedMessage;
+                }
+                newPdu = new SmsPdu(data, encoding, phoneType, languageTable);
+                pdus.add(newPdu);
+            }
+        }
+
+        return pdus;
+    }
+
+    /**
+     * Generate a list of deliver PDUs. The messageText and address parameters must be different from null,
+     * for CDMA the date can be omitted (and will be ignored if supplied)
+     * @param messageText The text to include.
+     * @param address The originator address.
+     * @param date The delivery time stamp.
+     * @return
+     */
+    public static ArrayList<SmsPdu> getDeliverPdus(String messageText, String address, long date){
+        ArrayList<SmsPdu> deliverPdus = getSubmitPdus(messageText, address);
+
+        /*
+         * For CDMA the only difference between deliver and submit pdus are the messageType,
+         * which is set in encodeMessageId, (the higher 4 bits of the 1st byte
+         * of the Message identification sub parameter data.) and the address type.
+         *
+         * For GSM, a larger part of the header needs to be generated.
+         */
+        for(SmsPdu currentPdu : deliverPdus){
+            if(currentPdu.getType() == SMS_TYPE_CDMA){
+                currentPdu.cdmaChangeToDeliverPdu(date);
+            } else { /* SMS_TYPE_GSM */
+                currentPdu.gsmChangeToDeliverPdu(date, address);
+            }
+        }
+
+        return deliverPdus;
+    }
+
+    public static void testSendRawPdu(SmsPdu pdu){
+        if(pdu.getType() == SMS_TYPE_CDMA){
+            /* TODO: Try to send the message using SmsManager.sendData()?*/
+        }else {
+
+        }
+    }
+
+    /**
+     * The decoding only supports decoding the actual textual content of the PDU received
+     * from the MAP client. (As the Android system has no interface to send pre encoded PDUs)
+     * The destination address must be extracted from the bmessage vCard(s).
+     */
+    public static String decodePdu(byte[] data, int type) {
+        String ret;
+        if(type == SMS_TYPE_CDMA) {
+            /* This is able to handle both submit and deliver PDUs */
+            ret = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(0, data).getMessageBody();
+        } else {
+            /* For GSM, there is no submit pdu decoder, and most parser utils are private, and only minded for submit pdus */
+            ret = gsmParseSubmitPdu(data);
+        }
+        return ret;
+    }
+
+    /* At the moment we do not support using a SC-address. Use this function to strip off
+     * the SC-address before parsing it to the SmsPdu. (this was added in errata 4335)
+     */
+    private static byte[] gsmStripOffScAddress(byte[] data) {
+        /* The format of a native GSM SMS is: <sc-address><pdu> where sc-address is:
+         * <length-byte><type-byte><number-bytes> */
+        int addressLength = data[0] & 0xff; // Treat the byte value as an unsigned value
+        if(addressLength >= data.length) // We could verify that the address-length is no longer than 11 bytes
+            throw new IllegalArgumentException("Length of address exeeds the length of the PDU data.");
+        int pduLength = data.length-(1+addressLength);
+        byte[] newData = new byte[pduLength];
+        System.arraycopy(data, 1+addressLength, newData, 0, pduLength);
+        return newData;
+    }
+
+    private static String gsmParseSubmitPdu(byte[] data) {
+        /* Things to do:
+         *  - extract hasUsrData bit
+         *  - extract TP-DCS -> Character set, compressed etc.
+         *  - extract user data header to get the language properties
+         *  - extract user data
+         *  - decode the string */
+        //Strip off the SC-address before parsing
+        SmsPdu pdu = new SmsPdu(gsmStripOffScAddress(data), SMS_TYPE_GSM);
+        boolean userDataCompressed = false;
+        int dataCodingScheme = pdu.gsmSubmitGetTpDcs();
+        int encodingType =  SmsConstants.ENCODING_UNKNOWN;
+        String messageBody = null;
+
+        // Look up the data encoding scheme
+        if ((dataCodingScheme & 0x80) == 0) {
+            // Bits 7..4 == 0xxx
+            userDataCompressed = (0 != (dataCodingScheme & 0x20));
+
+            if (userDataCompressed) {
+                Log.w(TAG, "4 - Unsupported SMS data coding scheme "
+                        + "(compression) " + (dataCodingScheme & 0xff));
+            } else {
+                switch ((dataCodingScheme >> 2) & 0x3) {
+                case 0: // GSM 7 bit default alphabet
+                    encodingType =  SmsConstants.ENCODING_7BIT;
+                    break;
+
+                case 2: // UCS 2 (16bit)
+                    encodingType =  SmsConstants.ENCODING_16BIT;
+                    break;
+
+                case 1: // 8 bit data
+                case 3: // reserved
+                    Log.w(TAG, "1 - Unsupported SMS data coding scheme "
+                            + (dataCodingScheme & 0xff));
+                    encodingType =  SmsConstants.ENCODING_8BIT;
+                    break;
+                }
+            }
+        } else if ((dataCodingScheme & 0xf0) == 0xf0) {
+            userDataCompressed = false;
+
+            if (0 == (dataCodingScheme & 0x04)) {
+                // GSM 7 bit default alphabet
+                encodingType =  SmsConstants.ENCODING_7BIT;
+            } else {
+                // 8 bit data
+                encodingType =  SmsConstants.ENCODING_8BIT;
+            }
+        } else if ((dataCodingScheme & 0xF0) == 0xC0
+                || (dataCodingScheme & 0xF0) == 0xD0
+                || (dataCodingScheme & 0xF0) == 0xE0) {
+            // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
+
+            // 0xC0 == 7 bit, don't store
+            // 0xD0 == 7 bit, store
+            // 0xE0 == UCS-2, store
+
+            if ((dataCodingScheme & 0xF0) == 0xE0) {
+                encodingType =  SmsConstants.ENCODING_16BIT;
+            } else {
+                encodingType =  SmsConstants.ENCODING_7BIT;
+            }
+
+            userDataCompressed = false;
+
+            // bit 0x04 reserved
+        } else if ((dataCodingScheme & 0xC0) == 0x80) {
+            // 3GPP TS 23.038 V7.0.0 (2006-03) section 4
+            // 0x80..0xBF == Reserved coding groups
+            if (dataCodingScheme == 0x84) {
+                // This value used for KSC5601 by carriers in Korea.
+                encodingType =  SmsConstants.ENCODING_KSC5601;
+            } else {
+                Log.w(TAG, "5 - Unsupported SMS data coding scheme "
+                        + (dataCodingScheme & 0xff));
+            }
+        } else {
+            Log.w(TAG, "3 - Unsupported SMS data coding scheme "
+                    + (dataCodingScheme & 0xff));
+        }
+
+        /* TODO: This is NOT good design - to have the pdu class being depending on these two function calls.
+         *        - move the encoding extraction into the pdu class */
+        pdu.setEncoding(encodingType);
+        pdu.gsmDecodeUserDataHeader();
+
+        try {
+            switch (encodingType) {
+            case  SmsConstants.ENCODING_UNKNOWN:
+            case  SmsConstants.ENCODING_8BIT:
+                Log.w(TAG, "Unknown encoding type: " + encodingType);
+                messageBody = null;
+                break;
+
+            case  SmsConstants.ENCODING_7BIT:
+                messageBody = GsmAlphabet.gsm7BitPackedToString(pdu.getData(), pdu.getUserDataMsgOffset(),
+                                pdu.getMsgSeptetCount(), pdu.getUserDataSeptetPadding(), pdu.getLanguageTable(),
+                                pdu.getLanguageShiftTable());
+                Log.i(TAG, "Decoded as 7BIT: " + messageBody);
+
+                break;
+
+            case  SmsConstants.ENCODING_16BIT:
+                messageBody = new String(pdu.getData(), pdu.getUserDataMsgOffset(), pdu.getUserDataMsgSize(), "utf-16");
+                Log.i(TAG, "Decoded as 16BIT: " + messageBody);
+                break;
+
+            case SmsConstants.ENCODING_KSC5601:
+                messageBody = new String(pdu.getData(), pdu.getUserDataMsgOffset(), pdu.getUserDataMsgSize(), "KSC5601");
+                Log.i(TAG, "Decoded as KSC5601: " + messageBody);
+                break;
+            }
+        } catch (UnsupportedEncodingException e) {
+            Log.e(TAG, "Unsupported encoding type???", e); // This should never happen.
+            return null;
+        }
+
+        return messageBody;
+    }
+
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapUtils.java b/src/com/android/bluetooth/map/BluetoothMapUtils.java
new file mode 100644
index 0000000..e57cf16
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapUtils.java
@@ -0,0 +1,116 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+
+/**
+ * Various utility methods and generic defines that can be used throughout MAPS
+ */
+public class BluetoothMapUtils {
+
+    private static final String TAG = "MapUtils";
+    private static final boolean V = BluetoothMapService.VERBOSE;
+    /* We use the upper 5 bits for the type mask - avoid using the top bit, since it
+     * indicates a negative value, hence corrupting the formatter when converting to
+     * type String. (I really miss the unsigned type in Java:))
+     */
+    private static final long HANDLE_TYPE_MASK            = 0xf<<59;
+    private static final long HANDLE_TYPE_MMS_MASK        = 0x1<<59;
+    private static final long HANDLE_TYPE_EMAIL_MASK      = 0x2<<59;
+    private static final long HANDLE_TYPE_SMS_GSM_MASK    = 0x4<<59;
+    private static final long HANDLE_TYPE_SMS_CDMA_MASK   = 0x8<<59;
+
+    /**
+     * This enum is used to convert from the bMessage type property to a type safe
+     * type. Hence do not change the names of the enum values.
+     */
+    public enum TYPE{
+        EMAIL,
+        SMS_GSM,
+        SMS_CDMA,
+        MMS
+    }
+
+    /**
+     * Convert a Content Provider handle and a Messagetype into a unique handle
+     * @param cpHandle content provider handle
+     * @param messageType message type (TYPE_MMS/TYPE_SMS_GSM/TYPE_SMS_CDMA/TYPE_EMAIL)
+     * @return String Formatted Map Handle
+     */
+    static public String getMapHandle(long cpHandle, TYPE messageType){
+        String mapHandle = "-1";
+        switch(messageType)
+        {
+            case MMS:
+                mapHandle = String.format("%016X",(cpHandle | HANDLE_TYPE_MMS_MASK));
+                break;
+            case SMS_GSM:
+                mapHandle = String.format("%016X",cpHandle | HANDLE_TYPE_SMS_GSM_MASK);
+                break;
+            case SMS_CDMA:
+                mapHandle = String.format("%016X",cpHandle | HANDLE_TYPE_SMS_CDMA_MASK);
+                break;
+            case EMAIL:
+                mapHandle = String.format("%016X",(cpHandle | HANDLE_TYPE_EMAIL_MASK)); //TODO correct when email support is implemented
+                break;
+                default:
+                    throw new IllegalArgumentException("Message type not supported");
+        }
+        return mapHandle;
+
+    }
+
+    /**
+     * Convert a handle string the the raw long representation, including the type bit.
+     * @param mapHandle the handle string
+     * @return the handle value
+     */
+    static public long getMsgHandleAsLong(String mapHandle){
+        return Long.parseLong(mapHandle, 16);
+    }
+    /**
+     * Convert a Map Handle into a content provider Handle
+     * @param mapHandle handle to convert from
+     * @return content provider handle without message type mask
+     */
+    static public long getCpHandle(String mapHandle)
+    {
+        long cpHandle = getMsgHandleAsLong(mapHandle);
+        /* remove masks as the call should already know what type of message this handle is for */
+        cpHandle &= ~HANDLE_TYPE_MASK;
+        return cpHandle;
+    }
+
+    /**
+     * Extract the message type from the handle.
+     * @param mapHandle
+     * @return
+     */
+    static public TYPE getMsgTypeFromHandle(String mapHandle) {
+        long cpHandle = getMsgHandleAsLong(mapHandle);
+
+        if((cpHandle & HANDLE_TYPE_MMS_MASK) != 0)
+            return TYPE.MMS;
+        if((cpHandle & HANDLE_TYPE_EMAIL_MASK) != 0)
+            return TYPE.EMAIL;
+        if((cpHandle & HANDLE_TYPE_SMS_GSM_MASK) != 0)
+            return TYPE.SMS_GSM;
+        if((cpHandle & HANDLE_TYPE_SMS_CDMA_MASK) != 0)
+            return TYPE.SMS_CDMA;
+
+        throw new IllegalArgumentException("Message type not found in handle string.");
+    }
+}
+
diff --git a/src/com/android/bluetooth/map/BluetoothMapbMessage.java b/src/com/android/bluetooth/map/BluetoothMapbMessage.java
new file mode 100644
index 0000000..de3de66
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapbMessage.java
@@ -0,0 +1,876 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import android.os.Environment;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+
+public abstract class BluetoothMapbMessage {
+
+    protected static String TAG = "BluetoothMapbMessage";
+    protected static final boolean D = false;
+    protected static final boolean V = false;
+    private static final String VERSION = "VERSION:1.0";
+
+    public static int INVALID_VALUE = -1;
+
+    protected int appParamCharset = BluetoothMapAppParams.INVALID_VALUE_PARAMETER;
+
+    // TODO: Reevaluate if strings are the best types for the members.
+
+    /* BMSG attributes */
+    private String status = null; // READ/UNREAD
+    protected TYPE type = null;   // SMS/MMS/EMAIL
+
+    private String folder = null;
+
+    /* BBODY attributes */
+    private long partId = INVALID_VALUE;
+    protected String encoding = null;
+    protected String charset = null;
+    private String language = null;
+
+    private int bMsgLength = INVALID_VALUE;
+
+    private ArrayList<vCard> originator = null;
+    private ArrayList<vCard> recipient = null;
+
+
+    public static class vCard {
+        /* VCARD attributes */
+        private String version;
+        private String name = null;
+        private String formattedName = null;
+        private String[] phoneNumbers = {};
+        private String[] emailAddresses = {};
+        private int envLevel = 0;
+
+        /**
+         * Construct a version 3.0 vCard
+         * @param name Structured
+         * @param formattedName Formatted name
+         * @param phoneNumbers a String[] of phone numbers
+         * @param emailAddresses a String[] of email addresses
+         * @param the bmessage envelope level (0 is the top/most outer level)
+         */
+        public vCard(String name, String formattedName, String[] phoneNumbers,
+                String[] emailAddresses, int envLevel) {
+            this.envLevel = envLevel;
+            this.version = "3.0";
+            this.name = name != null ? name : "";
+            this.formattedName = formattedName != null ? formattedName : "";
+            setPhoneNumbers(phoneNumbers);
+            if (emailAddresses != null)
+                this.emailAddresses = emailAddresses;
+        }
+
+        /**
+         * Construct a version 2.1 vCard
+         * @param name Structured name
+         * @param phoneNumbers a String[] of phone numbers
+         * @param emailAddresses a String[] of email addresses
+         * @param the bmessage envelope level (0 is the top/most outer level)
+         */
+        public vCard(String name, String[] phoneNumbers,
+                String[] emailAddresses, int envLevel) {
+            this.envLevel = envLevel;
+            this.version = "2.1";
+            this.name = name != null ? name : "";
+            setPhoneNumbers(phoneNumbers);
+            if (emailAddresses != null)
+                this.emailAddresses = emailAddresses;
+        }
+
+        /**
+         * Construct a version 3.0 vCard
+         * @param name Structured name
+         * @param formattedName Formatted name
+         * @param phoneNumbers a String[] of phone numbers
+         * @param emailAddresses a String[] of email addresses
+         */
+        public vCard(String name, String formattedName, String[] phoneNumbers, String[] emailAddresses) {
+            this.version = "3.0";
+            this.name = name != null ? name : "";
+            this.formattedName = formattedName != null ? formattedName : "";
+            setPhoneNumbers(phoneNumbers);
+            if (emailAddresses != null)
+                this.emailAddresses = emailAddresses;
+        }
+
+        /**
+         * Construct a version 2.1 vCard
+         * @param name Structured Name
+         * @param phoneNumbers a String[] of phone numbers
+         * @param emailAddresses a String[] of email addresses
+         */
+        public vCard(String name, String[] phoneNumbers, String[] emailAddresses) {
+            this.version = "2.1";
+            this.name = name != null ? name : "";
+            setPhoneNumbers(phoneNumbers);
+            if (emailAddresses != null)
+                this.emailAddresses = emailAddresses;
+        }
+
+        private void setPhoneNumbers(String[] numbers) {
+            if(numbers != null && numbers.length > 0)
+            {
+                phoneNumbers = new String[numbers.length];
+                for(int i = 0, n = numbers.length; i < n; i++){
+                    phoneNumbers[i] = PhoneNumberUtils.extractNetworkPortion(numbers[i]);
+                }
+            }
+        }
+
+        public String getFirstPhoneNumber() {
+            if(phoneNumbers.length > 0) {
+                return phoneNumbers[0];
+            } else
+                throw new IllegalArgumentException("No Phone number");
+        }
+
+        public int getEnvLevel() {
+            return envLevel;
+        }
+
+        public void encode(StringBuilder sb)
+        {
+            sb.append("BEGIN:VCARD").append("\r\n");
+            sb.append("VERSION:").append(version).append("\r\n");
+            if(version.equals("3.0") && formattedName != null)
+            {
+                sb.append("FN:").append(formattedName).append("\r\n");
+            }
+            if (name != null)
+                sb.append("N:").append(name).append("\r\n");
+            for(String phoneNumber : phoneNumbers)
+            {
+                sb.append("TEL:").append(phoneNumber).append("\r\n");
+            }
+            for(String emailAddress : emailAddresses)
+            {
+                sb.append("EMAIL:").append(emailAddress).append("\r\n");
+            }
+            sb.append("END:VCARD").append("\r\n");
+        }
+
+        /**
+         * Parse a vCard from a BMgsReader, where a line containing "BEGIN:VCARD" have just been read.
+         * @param reader
+         * @param originator
+         * @return
+         */
+        public static vCard parseVcard(BMsgReader reader, int envLevel) {
+            String formattedName = null;
+            String name = null;
+            ArrayList<String> phoneNumbers = null;
+            ArrayList<String> emailAddresses = null;
+            String[] parts;
+            String line = reader.getLineEnforce();
+
+            while(!line.contains("END:VCARD")) {
+                line = line.trim();
+                if(line.startsWith("N:")){
+                    parts = line.split("[^\\\\]:"); // Split on "un-escaped" ':'
+                    if(parts.length == 2) {
+                        name = parts[1];
+                    } else
+                        name = "";
+                }
+                else if(line.startsWith("FN:")){
+                    parts = line.split("[^\\\\]:"); // Split on "un-escaped" ':'
+                    if(parts.length == 2) {
+                        formattedName = parts[1];
+                    } else
+                        formattedName = "";
+                }
+                else if(line.startsWith("TEL:")){
+                    parts = line.split("[^\\\\]:"); // Split on "un-escaped" ':'
+                    if(parts.length == 2) {
+                        String[] subParts = parts[1].split("[^\\\\];");
+                        if(phoneNumbers == null)
+                            phoneNumbers = new ArrayList<String>(1);
+                        phoneNumbers.add(subParts[subParts.length-1]); // only keep actual phone number
+                    } else {}
+                        // Empty phone number - ignore
+                }
+                else if(line.startsWith("EMAIL:")){
+                    parts = line.split("[^\\\\]:"); // Split on "un-escaped" :
+                    if(parts.length == 2) {
+                        String[] subParts = parts[1].split("[^\\\\];");
+                        if(emailAddresses == null)
+                            emailAddresses = new ArrayList<String>(1);
+                        emailAddresses.add(subParts[subParts.length-1]); // only keep actual email address
+                    } else {}
+                        // Empty email address entry - ignore
+                }
+                line = reader.getLineEnforce();
+            }
+            return new vCard(name, formattedName,
+                    phoneNumbers == null? null : phoneNumbers.toArray(new String[phoneNumbers.size()]),
+                    emailAddresses == null ? null : emailAddresses.toArray(new String[emailAddresses.size()]),
+                    envLevel);
+        }
+    };
+
+    private static class BMsgReader {
+        InputStream mInStream;
+        public BMsgReader(InputStream is)
+        {
+            this.mInStream = is;
+        }
+
+        private byte[] getLineAsBytes() {
+            int readByte;
+
+            /* TODO: Actually the vCard spec. allows to break lines by using a newLine
+             * followed by a white space character(space or tab). Not sure this is a good idea to implement
+             * as the Bluetooth MAP spec. illustrates vCards using tab alignment, hence actually
+             * showing an invalid vCard format...
+             * If we read such a folded line, the folded part will be skipped in the parser
+             */
+
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            try {
+                while ((readByte = mInStream.read()) != -1) {
+                    if (readByte == '\r') {
+                        if ((readByte = mInStream.read()) != -1 && readByte == '\n') {
+                            if(output.size() == 0)
+                                continue; /* Skip empty lines */
+                            else
+                                break;
+                        } else {
+                            output.write('\r');
+                        }
+                    } else if (readByte == '\n' && output.size() == 0) {
+                        /* Empty line - skip */
+                        continue;
+                    }
+
+                    output.write(readByte);
+                }
+            } catch (IOException e) {
+                Log.w(TAG, e);
+                return null;
+            }
+            return output.toByteArray();
+        }
+
+        /**
+         * Read a line of text from the BMessage.
+         * @return the next line of text, or null at end of file, or if UTF-8 is not supported.
+         */
+        public String getLine() {
+            try {
+                byte[] line = getLineAsBytes();
+                if (line.length == 0)
+                    return null;
+                else
+                    return new String(line, "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                Log.w(TAG, e);
+                return null;
+            }
+        }
+
+        /**
+         * same as getLine(), but throws an exception, if we run out of lines.
+         * Use this function when ever more lines are needed for the bMessage to be complete.
+         * @return the next line
+         */
+        public String getLineEnforce() {
+        String line = getLine();
+        if (line == null)
+            throw new IllegalArgumentException("Bmessage too short");
+
+        return line;
+        }
+
+
+        /**
+         * Reads a line from the InputStream, and examines if the subString
+         * matches the line read.
+         * @param subString
+         * The string to match against the line.
+         * @throws IllegalArgumentException
+         * If the expected substring is not found.
+         *
+         */
+        public void expect(String subString) throws IllegalArgumentException{
+            String line = getLine();
+            if(line == null || subString == null){
+                throw new IllegalArgumentException("Line or substring is null");
+            }else if(!line.toUpperCase().contains(subString.toUpperCase()))
+                throw new IllegalArgumentException("Expected \"" + subString + "\" in: \"" + line + "\"");
+        }
+
+        /**
+         * Same as expect(String), but with two strings.
+         * @param subString
+         * @param subString2
+         * @throws IllegalArgumentException
+         * If one or all of the strings are not found.
+         */
+        public void expect(String subString, String subString2) throws IllegalArgumentException{
+            String line = getLine();
+            if(!line.toUpperCase().contains(subString.toUpperCase()))
+                throw new IllegalArgumentException("Expected \"" + subString + "\" in: \"" + line + "\"");
+            if(!line.toUpperCase().contains(subString2.toUpperCase()))
+                throw new IllegalArgumentException("Expected \"" + subString + "\" in: \"" + line + "\"");
+        }
+
+        /**
+         * Read a part of the bMessage as raw data.
+         * @param length the number of bytes to read
+         * @return the byte[] containing the number of bytes or null if an error occurs or EOF is reached
+         * before length bytes have been read.
+         */
+        public byte[] getDataBytes(int length) {
+            byte[] data = new byte[length];
+            try {
+                int bytesRead;
+                int offset=0;
+                while ((bytesRead = mInStream.read(data, offset, length-offset)) != (length - offset)) {
+                    if(bytesRead == -1)
+                        return null;
+                    offset += bytesRead;
+                }
+            } catch (IOException e) {
+                Log.w(TAG, e);
+                return null;
+            }
+            return data;
+        }
+    };
+
+    public BluetoothMapbMessage(){
+
+    }
+
+    public static BluetoothMapbMessage parse(InputStream bMsgStream, int appParamCharset) throws IllegalArgumentException{
+        BMsgReader reader;
+        String line = "";
+        BluetoothMapbMessage newBMsg = null;
+        boolean status = false;
+        boolean statusFound = false;
+        TYPE type = null;
+        String folder = null;
+
+        /* This section is used for debug. It will write the incoming message to a file on the SD-card,
+         * hence should only be used for test/debug.
+         * If an error occurs, it will result in a OBEX_HTTP_PRECON_FAILED to be send to the client,
+         * even though the message might be formatted correctly, hence only enable this code for test. */
+        if(V) {
+            /* Read the entire stream into a file on the SD card*/
+            File sdCard = Environment.getExternalStorageDirectory();
+            File dir = new File (sdCard.getAbsolutePath() + "/bluetooth/log/");
+            dir.mkdirs();
+            File file = new File(dir, "receivedBMessage.txt");
+            FileOutputStream outStream = null;
+            boolean failed = false;
+            int writtenLen = 0;
+
+            try {
+                outStream = new FileOutputStream(file, false); /* overwrite if it does already exist */
+
+                byte[] buffer = new byte[4*1024];
+                int len = 0;
+                while ((len = bMsgStream.read(buffer)) > 0) {
+                    outStream.write(buffer, 0, len);
+                    writtenLen += len;
+                }
+            } catch (FileNotFoundException e) {
+                Log.e(TAG,"Unable to create output stream",e);
+            } catch (IOException e) {
+                Log.e(TAG,"Failed to copy the received message",e);
+                if(writtenLen != 0)
+                    failed = true; /* We failed to write the complete file, hence the received message is lost... */
+            } finally {
+                if(outStream != null)
+                    try {
+                        outStream.close();
+                    } catch (IOException e) {
+                    }
+            }
+
+            /* Return if we corrupted the incoming bMessage. */
+            if(failed) {
+                throw new IllegalArgumentException(); /* terminate this function with an error. */
+            }
+
+            if (outStream == null) {
+                /* We failed to create the the log-file, just continue using the original bMsgStream. */
+            } else {
+                /* overwrite the bMsgStream using the file written to the SD-Card */
+                try {
+                    bMsgStream.close();
+                } catch (IOException e) {
+                    /* Ignore if we cannot close the stream. */
+                }
+                /* Open the file and overwrite bMsgStream to read from the file */
+                try {
+                    bMsgStream = new FileInputStream(file);
+                } catch (FileNotFoundException e) {
+                    Log.e(TAG,"Failed to open the bMessage file", e);
+                    throw new IllegalArgumentException(); /* terminate this function with an error. */
+                }
+            }
+            Log.i(TAG, "The incoming bMessage have been dumped to " + file.getAbsolutePath());
+        } /* End of if(V) log-section */
+
+        reader = new BMsgReader(bMsgStream);
+        reader.expect("BEGIN:BMSG");
+        reader.expect("VERSION","1.0");
+
+        line = reader.getLineEnforce();
+        // Parse the properties - which end with either a VCARD or a BENV
+        while(!line.contains("BEGIN:VCARD") && !line.contains("BEGIN:BENV")) {
+            if(line.contains("STATUS")){
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    if (arg[1].trim().equals("READ")) {
+                        status = true;
+                    } else if (arg[1].trim().equals("UNREAD")) {
+                        status =false;
+                    } else {
+                        throw new IllegalArgumentException("Wrong value in 'STATUS': " + arg[1]);
+                    }
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'STATUS': " + line);
+                }
+            }
+            if(line.contains("TYPE")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    String value = arg[1].trim();
+                    type = TYPE.valueOf(value); // Will throw IllegalArgumentException if value is wrong
+                    if(appParamCharset == BluetoothMapAppParams.CHARSET_NATIVE
+                            && type != TYPE.SMS_CDMA && type != TYPE.SMS_GSM) {
+                        throw new IllegalArgumentException("Native appParamsCharset only supported for SMS");
+                    }
+                    switch(type) {
+                    case SMS_CDMA:
+                    case SMS_GSM:
+                        newBMsg = new BluetoothMapbMessageSms();
+                        break;
+                    case MMS:
+                    case EMAIL:
+                        newBMsg = new BluetoothMapbMessageMmsEmail();
+                        break;
+                    default:
+                        break;
+                    }
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'TYPE':" + line);
+                }
+            }
+            if(line.contains("FOLDER")) {
+                String[] arg = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    folder = arg[1].trim();
+                }
+                // This can be empty for push message - hence ignore if there is no value
+            }
+            line = reader.getLineEnforce();
+        }
+        if(newBMsg == null)
+            throw new IllegalArgumentException("Missing bMessage TYPE: - unable to parse body-content");
+        newBMsg.setType(type);
+        newBMsg.appParamCharset = appParamCharset;
+        if(folder != null)
+            newBMsg.setCompleteFolder(folder);
+        if(statusFound)
+            newBMsg.setStatus(status);
+
+        // Now check for originator VCARDs
+        while(line.contains("BEGIN:VCARD")){
+            if(D) Log.d(TAG,"Decoding vCard");
+            newBMsg.addOriginator(vCard.parseVcard(reader,0));
+            line = reader.getLineEnforce();
+        }
+        if(line.contains("BEGIN:BENV")) {
+            newBMsg.parseEnvelope(reader, 0);
+        } else
+            throw new IllegalArgumentException("Bmessage has no BEGIN:BENV - line:" + line);
+
+        /* TODO: Do we need to validate the END:* tags? They are only needed if someone puts additional info
+         *        below the END:MSG - in which case we don't handle it.
+         */
+
+        try {
+            bMsgStream.close();
+        } catch (IOException e) {
+            /* Ignore if we cannot close the stream. */
+        }
+
+        return newBMsg;
+    }
+
+    private void parseEnvelope(BMsgReader reader, int level) {
+        String line;
+        line = reader.getLineEnforce();
+        if(D) Log.d(TAG,"Decoding envelope level " + level);
+
+       while(line.contains("BEGIN:VCARD")){
+           if(D) Log.d(TAG,"Decoding recipient vCard level " + level);
+            if(recipient == null)
+                recipient = new ArrayList<vCard>(1);
+            recipient.add(vCard.parseVcard(reader, level));
+            line = reader.getLineEnforce();
+        }
+        if(line.contains("BEGIN:BENV")) {
+            if(D) Log.d(TAG,"Decoding nested envelope");
+            parseEnvelope(reader, ++level); // Nested BENV
+        }
+        if(line.contains("BEGIN:BBODY")){
+            if(D) Log.d(TAG,"Decoding bbody");
+            parseBody(reader);
+        }
+    }
+
+    private void parseBody(BMsgReader reader) {
+        String line;
+        line = reader.getLineEnforce();
+        while(!line.contains("END:")) {
+            if(line.contains("PARTID:")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    try {
+                    partId = Long.parseLong(arg[1].trim());
+                    } catch (NumberFormatException e) {
+                        throw new IllegalArgumentException("Wrong value in 'PARTID': " + arg[1]);
+                    }
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'PARTID': " + line);
+                }
+            }
+            else if(line.contains("ENCODING:")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    encoding = arg[1].trim(); // TODO: Validate ?
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'ENCODING': " + line);
+                }
+            }
+            else if(line.contains("CHARSET:")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    charset = arg[1].trim(); // TODO: Validate ?
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'CHARSET': " + line);
+                }
+            }
+            else if(line.contains("LANGUAGE:")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    language = arg[1].trim(); // TODO: Validate ?
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'LANGUAGE': " + line);
+                }
+            }
+            else if(line.contains("LENGTH:")) {
+                String arg[] = line.split(":");
+                if (arg != null && arg.length == 2) {
+                    try {
+                        bMsgLength = Integer.parseInt(arg[1].trim());
+                    } catch (NumberFormatException e) {
+                        throw new IllegalArgumentException("Wrong value in 'LENGTH': " + arg[1]);
+                    }
+                } else {
+                    throw new IllegalArgumentException("Missing value for 'LENGTH': " + line);
+                }
+            }
+            else if(line.contains("BEGIN:MSG")) {
+                if(bMsgLength == INVALID_VALUE)
+                    throw new IllegalArgumentException("Missing value for 'LENGTH'. Unable to read remaining part of the message");
+                // For SMS: Encoding of MSG is always UTF-8 compliant, regardless of any properties, since PDUs are encodes as hex-strings
+                /* PTS has a bug regarding the message length, and sets it 2 bytes too short, hence
+                 * using the length field to determine the amount of data to read, might not be the
+                 * best solution.
+                 * Since errata ???(bluetooth.org is down at the moment) introduced escaping of END:MSG
+                 * in the actual message content, it is now safe to use the END:MSG tag as terminator,
+                 * and simply ignore the length field.*/
+                byte[] rawData = reader.getDataBytes(bMsgLength - (line.getBytes().length + 2)); // 2 added to compensate for the removed \r\n
+                String data;
+                try {
+                    data = new String(rawData, "UTF-8");
+                    if(V) {
+                        Log.v(TAG,"MsgLength: " + bMsgLength);
+                        Log.v(TAG,"line.getBytes().length: " + line.getBytes().length);
+                        String debug = line.replaceAll("\\n", "<LF>\n");
+                        debug = debug.replaceAll("\\r", "<CR>");
+                        Log.v(TAG,"The line: \"" + debug + "\"");
+                        debug = data.replaceAll("\\n", "<LF>\n");
+                        debug = debug.replaceAll("\\r", "<CR>");
+                        Log.v(TAG,"The msgString: \"" + debug + "\"");
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    Log.w(TAG,e);
+                    throw new IllegalArgumentException("Unable to convert to UTF-8");
+                }
+                /* Decoding of MSG:
+                 * 1) split on "\r\nEND:MSG\r\n"
+                 * 2) delete "BEGIN:MSG\r\n" for each msg
+                 * 3) replace any occurrence of "\END:MSG" with "END:MSG"
+                 * 4) based on charset from application properties either store as String[] or decode to raw PDUs
+                 * */
+                String messages[] = data.split("\r\nEND:MSG\r\n");
+                parseMsgInit();
+                for(int i = 0; i < messages.length; i++) {
+                    messages[i] = messages[i].replaceFirst("^BEGIN:MSG\r\n", "");
+                    messages[i] = messages[i].replaceAll("\r\n([/]*)/END\\:MSG", "\r\n$1END:MSG");
+                    messages[i] = messages[i].trim();
+                    parseMsgPart(messages[i]);
+                }
+            }
+            line = reader.getLineEnforce();
+        }
+    }
+
+    /**
+     * Parse the 'message' part of <bmessage-body-content>"
+     * @param msgPart
+     */
+    public abstract void parseMsgPart(String msgPart);
+    /**
+     * Set initial values before parsing - will be called is a message body is found
+     * during parsing.
+     */
+    public abstract void parseMsgInit();
+
+    public abstract byte[] encode() throws UnsupportedEncodingException;
+
+    public void setStatus(boolean read) {
+        if(read)
+            this.status = "READ";
+        else
+            this.status = "UNREAD";
+    }
+
+    public void setType(TYPE type) {
+        this.type = type;
+    }
+
+    /**
+     * @return the type
+     */
+    public TYPE getType() {
+        return type;
+    }
+
+    public void setCompleteFolder(String folder) {
+        this.folder = folder;
+    }
+
+    public void setFolder(String folder) {
+        this.folder = "telecom/msg/" + folder;
+    }
+
+    public String getFolder() {
+        return folder;
+    }
+
+
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    public ArrayList<vCard> getOriginators() {
+        return originator;
+    }
+
+    public void addOriginator(vCard originator) {
+        if(this.originator == null)
+            this.originator = new ArrayList<vCard>();
+        this.originator.add(originator);
+    }
+
+    /**
+     * Add a version 3.0 vCard with a formatted name
+     * @param name e.g. Bonde;Casper
+     * @param formattedName e.g. "Casper Bonde"
+     * @param phoneNumbers
+     * @param emailAddresses
+     */
+    public void addOriginator(String name, String formattedName, String[] phoneNumbers, String[] emailAddresses) {
+        if(originator == null)
+            originator = new ArrayList<vCard>();
+        originator.add(new vCard(name, formattedName, phoneNumbers, emailAddresses));
+    }
+
+    /** Add a version 2.1 vCard with only a name.
+     *
+     * @param name e.g. Bonde;Casper
+     * @param phoneNumbers
+     * @param emailAddresses
+     */
+    public void addOriginator(String name, String[] phoneNumbers, String[] emailAddresses) {
+        if(originator == null)
+            originator = new ArrayList<vCard>();
+        originator.add(new vCard(name, phoneNumbers, emailAddresses));
+    }
+
+    public ArrayList<vCard> getRecipients() {
+        return recipient;
+    }
+
+    public void setRecipient(vCard recipient) {
+        if(this.recipient == null)
+            this.recipient = new ArrayList<vCard>();
+        this.recipient.add(recipient);
+    }
+
+    public void addRecipient(String name, String formattedName, String[] phoneNumbers, String[] emailAddresses) {
+        if(recipient == null)
+            recipient = new ArrayList<vCard>();
+        recipient.add(new vCard(name, formattedName, phoneNumbers, emailAddresses));
+    }
+
+    public void addRecipient(String name, String[] phoneNumbers, String[] emailAddresses) {
+        if(recipient == null)
+            recipient = new ArrayList<vCard>();
+        recipient.add(new vCard(name, phoneNumbers, emailAddresses));
+    }
+
+    /**
+     * Convert a byte[] of data to a hex string representation, converting each nibble to the corresponding
+     * hex char.
+     * NOTE: There is not need to escape instances of "\r\nEND:MSG" in the binary data represented as a string
+     *       as only the characters [0-9] and [a-f] is used.
+     * @param pduData the byte-array of data.
+     * @param scAddressData the byte-array of the encoded sc-Address.
+     * @return the resulting string.
+     */
+    protected String encodeBinary(byte[] pduData, byte[] scAddressData) {
+        StringBuilder out = new StringBuilder((pduData.length + scAddressData.length)*2);
+        for(int i = 0; i < scAddressData.length; i++) {
+            out.append(Integer.toString((scAddressData[i] >> 4) & 0x0f,16)); // MS-nibble first
+            out.append(Integer.toString( scAddressData[i]       & 0x0f,16));
+        }
+        for(int i = 0; i < pduData.length; i++) {
+            out.append(Integer.toString((pduData[i] >> 4) & 0x0f,16)); // MS-nibble first
+            out.append(Integer.toString( pduData[i]       & 0x0f,16));
+            /*out.append(Integer.toHexString(data[i]));*/ /* This is the same as above, but does not include the needed 0's
+                                                           e.g. it converts the value 3 to "3" and not "03" */
+        }
+        return out.toString();
+    }
+
+    /**
+     * Decodes a binary hex-string encoded UTF-8 string to the represented binary data set.
+     * @param data The string representation of the data - must have an even number of characters.
+     * @return the byte[] represented in the data.
+     */
+    protected byte[] decodeBinary(String data) {
+        byte[] out = new byte[data.length()/2];
+        String value;
+        if(D) Log.d(TAG,"Decoding binary data: START:" + data + ":END");
+        for(int i = 0, j = 0, n = out.length; i < n; i++)
+        {
+            value = data.substring(j++, ++j); // same as data.substring(2*i, 2*i+1+1) - substring() uses end-1 for last index
+            out[i] = (byte)(Integer.valueOf(value, 16) & 0xff);
+        }
+        if(D) {
+            StringBuilder sb = new StringBuilder(out.length);
+            for(int i = 0, n = out.length; i < n; i++)
+            {
+                sb.append(String.format("%02X",out[i] & 0xff));
+            }
+            Log.d(TAG,"Decoded binary data: START:" + sb.toString() + ":END");
+        }
+        return out;
+    }
+
+    public byte[] encodeGeneric(ArrayList<byte[]> bodyFragments) throws UnsupportedEncodingException
+    {
+        StringBuilder sb = new StringBuilder(256);
+        byte[] msgStart, msgEnd;
+        sb.append("BEGIN:BMSG").append("\r\n");
+        sb.append(VERSION).append("\r\n");
+        sb.append("STATUS:").append(status).append("\r\n");
+        sb.append("TYPE:").append(type.name()).append("\r\n");
+        if(folder.length() > 512)
+            sb.append("FOLDER:").append(folder.substring(folder.length()-512, folder.length())).append("\r\n");
+        else
+            sb.append("FOLDER:").append(folder).append("\r\n");
+        if(originator != null){
+            for(vCard element : originator)
+                element.encode(sb);
+        }
+        /* TODO: Do we need the three levels of env? - e.g. for e-mail. - we do have a level in the
+         *  vCards that could be used to determine the the levels of the envelope.
+         */
+
+        sb.append("BEGIN:BENV").append("\r\n");
+        if(recipient != null){
+            for(vCard element : recipient)
+                element.encode(sb);
+        }
+        sb.append("BEGIN:BBODY").append("\r\n");
+        if(encoding != null && encoding != "")
+            sb.append("ENCODING:").append(encoding).append("\r\n");
+        if(charset != null && charset != "")
+            sb.append("CHARSET:").append(charset).append("\r\n");
+
+
+        int length = 0;
+        /* 22 is the length of the 'BEGIN:MSG' and 'END:MSG' + 3*CRLF */
+        for (byte[] fragment : bodyFragments) {
+            length += fragment.length + 22;
+        }
+        sb.append("LENGTH:").append(length).append("\r\n");
+
+        // Extract the initial part of the bMessage string
+        msgStart = sb.toString().getBytes("UTF-8");
+
+        sb = new StringBuilder(31);
+        sb.append("END:BBODY").append("\r\n");
+        sb.append("END:BENV").append("\r\n");
+        sb.append("END:BMSG").append("\r\n");
+
+        msgEnd = sb.toString().getBytes("UTF-8");
+
+        try {
+
+            ByteArrayOutputStream stream = new ByteArrayOutputStream(msgStart.length + msgEnd.length + length);
+            stream.write(msgStart);
+
+            for (byte[] fragment : bodyFragments) {
+                stream.write("BEGIN:MSG\r\n".getBytes("UTF-8"));
+                stream.write(fragment);
+                stream.write("\r\nEND:MSG\r\n".getBytes("UTF-8"));
+            }
+            stream.write(msgEnd);
+
+            if(V) Log.v(TAG,stream.toString("UTF-8"));
+            return stream.toByteArray();
+        } catch (IOException e) {
+            Log.w(TAG,e);
+            return null;
+        }
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java b/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java
new file mode 100644
index 0000000..0f1feac
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapbMessageMmsEmail.java
@@ -0,0 +1,638 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Locale;
+import java.util.UUID;
+
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
+import android.util.Base64;
+import android.util.Log;
+
+public class BluetoothMapbMessageMmsEmail extends BluetoothMapbMessage {
+
+    public static class MimePart {
+        public long _id = INVALID_VALUE;   /* The _id from the content provider, can be used to sort the parts if needed */
+        public String contentType = null;  /* The mime type, e.g. text/plain */
+        public String contentId = null;
+        public String contentLocation = null;
+        public String contentDisposition = null;
+        public String partName = null;     /* e.g. text_1.txt*/
+        public String charsetName = null;  /* This seems to be a number e.g. 106 for UTF-8 CharacterSets
+                                                holds a method for the mapping. */
+        public String fileName = null;     /* Do not seem to be used */
+        public byte[] data = null;        /* The raw un-encoded data e.g. the raw jpeg data or the text.getBytes("utf-8") */
+
+
+
+        public void encode(StringBuilder sb, String boundaryTag, boolean last) throws UnsupportedEncodingException {
+            sb.append("--").append(boundaryTag).append("\r\n");
+            if(contentType != null)
+                sb.append("Content-Type: ").append(contentType);
+            if(charsetName != null)
+                sb.append("; ").append("charset=\"").append(charsetName).append("\"");
+            sb.append("\r\n");
+            if(contentLocation != null)
+                sb.append("Content-Location: ").append(contentLocation).append("\r\n");
+            if(contentId != null)
+                sb.append("Content-ID: ").append(contentId).append("\r\n");
+            if(contentDisposition != null)
+                sb.append("Content-Disposition: ").append(contentDisposition).append("\r\n");
+            if(data != null) {
+                /* TODO: If errata 4176 is adopted in the current form (it is not in either 1.1 or 1.2),
+                the below is not allowed, Base64 should be used for text. */
+
+                if(contentType != null &&
+                        (contentType.toUpperCase().contains("TEXT") ||
+                         contentType.toUpperCase().contains("SMIL") )) {
+                    sb.append("Content-Transfer-Encoding: 8BIT\r\n\r\n"); // Add the header split empty line
+                    sb.append(new String(data,"UTF-8")).append("\r\n");
+                }
+                else {
+                    sb.append("Content-Transfer-Encoding: Base64\r\n\r\n"); // Add the header split empty line
+                    sb.append(Base64.encodeToString(data, Base64.DEFAULT)).append("\r\n");
+                }
+            }
+            if(last) {
+                sb.append("--").append(boundaryTag).append("--").append("\r\n");
+            }
+        }
+
+        public void encodePlainText(StringBuilder sb) throws UnsupportedEncodingException {
+            if(contentType != null && contentType.toUpperCase().contains("TEXT")) {
+                sb.append(new String(data,"UTF-8")).append("\r\n");
+            } else if(contentType != null && contentType.toUpperCase().contains("/SMIL")) {
+                /* Skip the smil.xml, as no-one knows what it is. */
+            } else {
+                /* Not a text part, just print the filename or part name if they exist. */
+                if(partName != null)
+                    sb.append("<").append(partName).append(">\r\n");
+                else
+                    sb.append("<").append("attachment").append(">\r\n");
+            }
+        }
+    }
+
+    private long date = INVALID_VALUE;
+    private String subject = null;
+    private ArrayList<Rfc822Token> from = null;   // Shall not be empty
+    private ArrayList<Rfc822Token> sender = null;   // Shall not be empty
+    private ArrayList<Rfc822Token> to = null;     // Shall not be empty
+    private ArrayList<Rfc822Token> cc = null;     // Can be empty
+    private ArrayList<Rfc822Token> bcc = null;    // Can be empty
+    private ArrayList<Rfc822Token> replyTo = null;// Can be empty
+    private String messageId = null;
+    private ArrayList<MimePart> parts = null;
+    private String contentType = null;
+    private String boundary = null;
+    private boolean textOnly = false;
+    private boolean includeAttachments;
+    private boolean hasHeaders = false;
+    private String encoding = null;
+
+    private String getBoundary() {
+        if(boundary == null)
+            boundary = "----" + UUID.randomUUID();
+        return boundary;
+    }
+
+    /**
+     * @return the parts
+     */
+    public ArrayList<MimePart> getMimeParts() {
+        return parts;
+    }
+
+    public MimePart addMimePart() {
+        if(parts == null)
+            parts = new ArrayList<BluetoothMapbMessageMmsEmail.MimePart>();
+        MimePart newPart = new MimePart();
+        parts.add(newPart);
+        return newPart;
+    }
+    public String getDateString() {
+        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
+        Date dateObj = new Date(date);
+        return format.format(dateObj); // Format according to RFC 2822 page 14
+    }
+    public long getDate() {
+        return date;
+    }
+    public void setDate(long date) {
+        this.date = date;
+    }
+    public String getSubject() {
+        return subject;
+    }
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+    public ArrayList<Rfc822Token> getFrom() {
+        return from;
+    }
+    public void setFrom(ArrayList<Rfc822Token> from) {
+        this.from = from;
+    }
+    public void addFrom(String name, String address) {
+        if(this.from == null)
+            this.from = new ArrayList<Rfc822Token>(1);
+        this.from.add(new Rfc822Token(name, address, null));
+    }
+    public ArrayList<Rfc822Token> getSender() {
+        return sender;
+    }
+    public void setSender(ArrayList<Rfc822Token> sender) {
+        this.sender = sender;
+    }
+    public void addSender(String name, String address) {
+        if(this.sender == null)
+            this.sender = new ArrayList<Rfc822Token>(1);
+        this.sender.add(new Rfc822Token(name,address,null));
+    }
+    public ArrayList<Rfc822Token> getTo() {
+        return to;
+    }
+    public void setTo(ArrayList<Rfc822Token> to) {
+        this.to = to;
+    }
+    public void addTo(String name, String address) {
+        if(this.to == null)
+            this.to = new ArrayList<Rfc822Token>(1);
+        this.to.add(new Rfc822Token(name, address, null));
+    }
+    public ArrayList<Rfc822Token> getCc() {
+        return cc;
+    }
+    public void setCc(ArrayList<Rfc822Token> cc) {
+        this.cc = cc;
+    }
+    public void addCc(String name, String address) {
+        if(this.cc == null)
+            this.cc = new ArrayList<Rfc822Token>(1);
+        this.cc.add(new Rfc822Token(name, address, null));
+    }
+    public ArrayList<Rfc822Token> getBcc() {
+        return bcc;
+    }
+    public void setBcc(ArrayList<Rfc822Token> bcc) {
+        this.bcc = bcc;
+    }
+    public void addBcc(String name, String address) {
+        if(this.bcc == null)
+            this.bcc = new ArrayList<Rfc822Token>(1);
+        this.bcc.add(new Rfc822Token(name, address, null));
+    }
+    public ArrayList<Rfc822Token> getReplyTo() {
+        return replyTo;
+    }
+    public void setReplyTo(ArrayList<Rfc822Token> replyTo) {
+        this.replyTo = replyTo;
+    }
+    public void addReplyTo(String name, String address) {
+        if(this.replyTo == null)
+            this.replyTo = new ArrayList<Rfc822Token>(1);
+        this.replyTo.add(new Rfc822Token(name, address, null));
+    }
+    public void setMessageId(String messageId) {
+        this.messageId = messageId;
+    }
+    public String getMessageId() {
+        return messageId;
+    }
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+    public String getContentType() {
+        return contentType;
+    }
+    public void setTextOnly(boolean textOnly) {
+        this.textOnly = textOnly;
+    }
+    public boolean getTextOnly() {
+        return textOnly;
+    }
+    public void setIncludeAttachments(boolean includeAttachments) {
+        this.includeAttachments = includeAttachments;
+    }
+    public boolean getIncludeAttachments() {
+        return includeAttachments;
+    }
+    public void updateCharset() {
+        charset = null;
+        for(MimePart part : parts) {
+            if(part.contentType != null &&
+               part.contentType.toUpperCase().contains("TEXT")) {
+                charset = "UTF-8";
+                break;
+            }
+        }
+    }
+    public int getSize() {
+        int message_size = 0;
+        for(MimePart part : parts) {
+            message_size += part.data.length;
+        }
+        return message_size;
+    }
+
+    /**
+     * Encode an address header, and perform folding if needed.
+     * @param sb The stringBuilder to write to
+     * @param headerName The RFC 2822 header name
+     * @param addresses the reformatted address substrings to encode.
+     */
+    public void encodeHeaderAddresses(StringBuilder sb, String headerName,
+            ArrayList<Rfc822Token> addresses) {
+        /* TODO: Do we need to encode the addresses if they contain illegal characters?
+         * This depends of the outcome of errata 4176. The current spec. states to use UTF-8
+         * where possible, but the RFCs states to use US-ASCII for the headers - hence encoding
+         * would be needed to support non US-ASCII characters. But the MAP spec states not to
+         * use any encoding... */
+        int partLength, lineLength = 0;
+        lineLength += headerName.getBytes().length;
+        sb.append(headerName);
+        for(Rfc822Token address : addresses) {
+            partLength = address.toString().getBytes().length+1;
+            // Add folding if needed
+            if(lineLength + partLength >= 998) // max line length in RFC2822
+            {
+                sb.append("\r\n "); // Append a FWS (folding whitespace)
+                lineLength = 0;
+            }
+            sb.append(address.toString()).append(";");
+            lineLength += partLength;
+        }
+        sb.append("\r\n");
+    }
+
+    public void encodeHeaders(StringBuilder sb) throws UnsupportedEncodingException
+    {
+        /* TODO: From RFC-4356 - about the RFC-(2)822 headers:
+         *    "Current Internet Message format requires that only 7-bit US-ASCII
+         *     characters be present in headers.  Non-7-bit characters in an address
+         *     domain must be encoded with [IDN].  If there are any non-7-bit
+         *     characters in the local part of an address, the message MUST be
+         *     rejected.  Non-7-bit characters elsewhere in a header MUST be encoded
+         *     according to [Hdr-Enc]."
+         *    We need to add the address encoding in encodeHeaderAddresses, but it is not
+         *    straight forward, as it is unclear how to do this.  */
+        if (date != INVALID_VALUE)
+            sb.append("Date: ").append(getDateString()).append("\r\n");
+        /* According to RFC-2822 headers must use US-ASCII, where the MAP specification states
+         * UTF-8 should be used for the entire <bmessage-body-content>. We let the MAP specification
+         * take precedence above the RFC-2822. The code to
+         */
+        /* If we are to use US-ASCII anyway, here are the code for it.
+          if (subject != null){
+            // Use base64 encoding for the subject, as it may contain non US-ASCII characters or other
+            // illegal (RFC822 header), and android do not seem to have encoders/decoders for quoted-printables
+            sb.append("Subject:").append("=?utf-8?B?");
+            sb.append(Base64.encodeToString(subject.getBytes("utf-8"), Base64.DEFAULT));
+            sb.append("?=\r\n");
+        }*/
+        if (subject != null)
+            sb.append("Subject: ").append(subject).append("\r\n");
+        if(from != null)
+            encodeHeaderAddresses(sb, "From: ", from); // This includes folding if needed.
+        if(sender != null)
+            encodeHeaderAddresses(sb, "Sender: ", sender); // This includes folding if needed.
+        /* For MMS one recipient(to, cc or bcc) must exists, if none: 'To:  undisclosed-
+         * recipients:;' could be used.
+         * TODO: Is this a valid solution for E-Mail?
+         */
+        if(to == null && cc == null && bcc == null)
+            sb.append("To:  undisclosed-recipients:;\r\n");
+        if(to != null)
+            encodeHeaderAddresses(sb, "To: ", to); // This includes folding if needed.
+        if(cc != null)
+            encodeHeaderAddresses(sb, "Cc: ", cc); // This includes folding if needed.
+        if(bcc != null)
+            encodeHeaderAddresses(sb, "Bcc: ", bcc); // This includes folding if needed.
+        if(replyTo != null)
+            encodeHeaderAddresses(sb, "Reply-To: ", replyTo); // This includes folding if needed.
+        if(includeAttachments == true)
+        {
+            if(messageId != null)
+                sb.append("Message-Id: ").append(messageId).append("\r\n");
+            if(contentType != null)
+                sb.append("Content-Type: ").append(contentType).append("; boundary=").append(getBoundary()).append("\r\n");
+        }
+        sb.append("\r\n"); // If no headers exists, we still need two CRLF, hence keep it out of the if above.
+    }
+
+    /* Notes on MMS
+     * ------------
+     * According to rfc4356 all headers of a MMS converted to an E-mail must use
+     * 7-bit encoding. According the the MAP specification only 8-bit encoding is
+     * allowed - hence the bMessage-body should contain no SMTP headers. (Which makes
+     * sense, since the info is already present in the bMessage properties.)
+     * The result is that no information from RFC4356 is needed, since it does not
+     * describe any mapping between MMS content and E-mail content.
+     * Suggestion:
+     * Clearly state in the MAP specification that
+     * only the actual message content should be included in the <bmessage-body-content>.
+     * Correct the Example to not include the E-mail headers, and in stead show how to
+     * include a picture or another binary attachment.
+     *
+     * If the headers should be included, clearly state which, as the example clearly shows
+     * that some of the headers should be excluded.
+     * Additionally it is not clear how to handle attachments. There is a parameter in the
+     * get message to include attachments, but since only 8-bit encoding is allowed,
+     * (hence neither base64 nor binary) there is no mechanism to embed the attachment in
+     * the <bmessage-body-content>.
+     *
+     * UPDATE: Errata 4176 allows the needed encoding typed inside the <bmessage-body-content>
+     * including Base64 and Quoted Printables - hence it is possible to encode non-us-ascii
+     * messages - e.g. pictures and utf-8 strings with non-us-ascii content.
+     * It have not yet been adopted, but since the comments clearly suggest that it is allowed
+     * to use encoding schemes for non-text parts, it is still not clear what to do about non
+     * US-ASCII text in the headers.
+     * */
+
+    /**
+     * Encode the bMessage as a MMS
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+    public byte[] encodeMms() throws UnsupportedEncodingException
+    {
+        ArrayList<byte[]> bodyFragments = new ArrayList<byte[]>();
+        StringBuilder sb = new StringBuilder();
+        int count = 0;
+        String mmsBody;
+
+        encoding = "8BIT"; // The encoding used
+
+        encodeHeaders(sb);
+        if(getIncludeAttachments() == false) {
+            for(MimePart part : parts) {
+                part.encodePlainText(sb); /* We call encode on all parts, to include a tag, where an attachment is missing. */
+            }
+        } else {
+            for(MimePart part : parts) {
+                count++;
+                part.encode(sb, getBoundary(), (count == parts.size()));
+            }
+        }
+
+        mmsBody = sb.toString();
+
+        if(mmsBody != null) {
+            String tmpBody = mmsBody.replaceAll("END:MSG", "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG
+            bodyFragments.add(tmpBody.getBytes("UTF-8"));
+        } else {
+            bodyFragments.add(new byte[0]);
+        }
+
+        return encodeGeneric(bodyFragments);
+    }
+
+
+    /**
+     * Try to parse the hdrPart string as e-mail headers.
+     * @param hdrPart The string to parse.
+     * @return Null if the entire string were e-mail headers. The part of the string in which
+     * no headers were found.
+     */
+    private String parseMmsHeaders(String hdrPart) {
+        String[] headers = hdrPart.split("\r\n");
+        String header;
+        hasHeaders = false;
+
+        for(int i = 0, c = headers.length; i < c; i++) {
+            header = headers[i];
+
+            /* We need to figure out if any headers are present, in cases where devices do not follow the e-mail RFCs.
+             * Skip empty lines, and then parse headers until a non-header line is found, at which point we treat the
+             * remaining as plain text.
+             */
+            if(header.trim() == "")
+                continue;
+            String[] headerParts = header.split(":",2);
+            if(headerParts.length != 2) {
+                // We treat the remaining content as plain text.
+                StringBuilder remaining = new StringBuilder();
+                for(; i < c; i++)
+                    remaining.append(headers[i]);
+
+                return remaining.toString();
+            }
+
+            String headerType = headerParts[0].toUpperCase();
+            String headerValue = headerParts[1].trim();
+
+            // Address headers
+            /* TODO: If this is empty, the MSE needs to fill it in before sending the message.
+             * This happens when sending the MMS, not sure what happens for e-mail.
+             */
+            if(headerType.contains("FROM")) {
+                Rfc822Token tokens[] = Rfc822Tokenizer.tokenize(headerValue);
+                from = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
+            }
+            else if(headerType.contains("TO")) {
+                Rfc822Token tokens[] = Rfc822Tokenizer.tokenize(headerValue);
+                to = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
+            }
+            else if(headerType.contains("CC")) {
+                Rfc822Token tokens[] = Rfc822Tokenizer.tokenize(headerValue);
+                cc = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
+            }
+            else if(headerType.contains("BCC")) {
+                Rfc822Token tokens[] = Rfc822Tokenizer.tokenize(headerValue);
+                bcc = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
+            }
+            else if(headerType.contains("REPLY-TO")) {
+                Rfc822Token tokens[] = Rfc822Tokenizer.tokenize(headerValue);
+                replyTo = new ArrayList<Rfc822Token>(Arrays.asList(tokens));
+            }// Other headers
+            else if(headerType.contains("SUBJECT")) {
+                subject = headerValue;
+            }
+            else if(headerType.contains("MESSAGE-ID")) {
+                messageId = headerValue;
+            }
+            else if(headerType.contains("DATE")) {
+                /* TODO: Do we need the date? */
+            }
+            else if(headerType.contains("CONTENT-TYPE")) {
+                String[] contentTypeParts = headerValue.split(";");
+                contentType = contentTypeParts[0];
+                // Extract the boundary if it exists
+                for(int j=1, n=contentTypeParts.length; j<n; j++)
+                {
+                    if(contentTypeParts[j].contains("boundary")) {
+                        boundary = contentTypeParts[j].split("boundary[\\s]*=", 2)[1].trim();
+                    }
+                }
+            }
+            else if(headerType.contains("CONTENT-TRANSFER-ENCODING")) {
+                encoding = headerValue;
+            }
+            else {
+                if(D) Log.w(TAG,"Skipping unknown header: " + headerType + " (" + header + ")");
+            }
+        }
+        return null;
+    }
+
+    private void parseMmsMimePart(String partStr) {
+        String[] parts = partStr.split("\r\n\r\n", 2); // Split the header from the body
+        String body;
+        if(parts.length != 2) {
+            body = partStr;
+        } else {
+            body = parts[1];
+        }
+        String[] headers = parts[0].split("\r\n");
+        MimePart newPart = addMimePart();
+        String partEncoding = encoding; /* Use the overall encoding as default */
+
+        for(String header : headers) {
+            if(header.length() == 0)
+                continue;
+
+            if(header.trim() == "" || header.trim().equals("--")) // Skip empty lines(the \r\n after the boundary tag) and endBoundary tags
+                continue;
+            String[] headerParts = header.split(":",2);
+            if(headerParts.length != 2)
+                throw new IllegalArgumentException("part-Header not formatted correctly: " + header);
+            String headerType = headerParts[0].toUpperCase();
+            String headerValue = headerParts[1].trim();
+            if(headerType.contains("CONTENT-TYPE")) {
+                // TODO: extract charset? Only UTF-8 is allowed for TEXT typed parts
+                newPart.contentType = headerValue;
+                Log.d(TAG, "*** CONTENT-TYPE: " + newPart.contentType);
+            }
+            else if(headerType.contains("CONTENT-LOCATION")) {
+                // This is used if the smil refers to a file name in its src=
+                newPart.contentLocation = headerValue;
+                newPart.partName = headerValue;
+            }
+            else if(headerType.contains("CONTENT-TRANSFER-ENCODING")) {
+                partEncoding = headerValue;
+            }
+            else if(headerType.contains("CONTENT-ID")) {
+                // This is used if the smil refers to a cid:<xxx> in it's src=
+                newPart.contentId = headerValue;
+            }
+            else if(headerType.contains("CONTENT-DISPOSITION")) {
+                // This is used if the smil refers to a cid:<xxx> in it's src=
+                newPart.contentDisposition = headerValue;
+            }
+            else {
+                if(D) Log.w(TAG,"Skipping unknown part-header: " + headerType + " (" + header + ")");
+            }
+        }
+        // Now for the body
+        newPart.data = decodeBody(body, partEncoding);
+    }
+
+    private void parseMmsMimeBody(String body) {
+        MimePart newPart = addMimePart();
+        newPart.data = decodeBody(body, encoding);
+    }
+
+    private byte[] decodeBody(String body, String encoding) {
+        if(encoding != null && encoding.toUpperCase().contains("BASE64")) {
+            return Base64.decode(body, Base64.DEFAULT);
+        } else {
+            // TODO: handle other encoding types? - here we simply store the string data as bytes
+            try {
+                return body.getBytes("UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                // This will never happen, as UTF-8 is mandatory on Android platforms
+            }
+        }
+        return null;
+    }
+
+    private void parseMms(String message) {
+        /* Overall strategy for decoding:
+         * 1) split on first empty line to extract the header
+         * 2) unfold and parse headers
+         * 3) split on boundary to split into parts (or use the remaining as a part,
+         *    if part is not found)
+         * 4) parse each part
+         * */
+        String[] messageParts;
+        String[] mimeParts;
+        String remaining = null;
+        String messageBody = null;
+        message = message.replaceAll("\\r\\n[ \\\t]+", ""); // Unfold
+        messageParts = message.split("\r\n\r\n", 2); // Split the header from the body
+        if(messageParts.length != 2) {
+            // Handle entire message as plain text
+            messageBody = message;
+        }
+        else
+        {
+            remaining = parseMmsHeaders(messageParts[0]);
+            // If we have some text not being a header, add it to the message body.
+            if(remaining != null) {
+                messageBody = remaining + messageParts[1];
+            }
+            else {
+                messageBody = messageParts[1];
+            }
+        }
+
+        if(boundary == null)
+        {
+            // If the boundary is not set, handle as non-multi-part
+            parseMmsMimeBody(messageBody);
+            setTextOnly(true);
+            if(contentType == null)
+                contentType = "text/plain";
+            parts.get(0).contentType = contentType;
+        }
+        else
+        {
+            mimeParts = messageBody.split("--" + boundary);
+            for(int i = 0; i < mimeParts.length - 1; i++) {
+                String part = mimeParts[i];
+                if (part != null && (part.length() > 0))
+                    parseMmsMimePart(part);
+        }
+        }
+    }
+
+    /* Notes on SMIL decoding (from http://tools.ietf.org/html/rfc2557):
+     * src="filename.jpg" refers to a part with Content-Location: filename.jpg
+     * src="cid:1234@hest.net" refers to a part with Content-ID:<1234@hest.net>*/
+    @Override
+    public void parseMsgPart(String msgPart) {
+        parseMms(msgPart);
+
+    }
+
+    @Override
+    public void parseMsgInit() {
+        // Not used for e-mail
+
+    }
+
+    @Override
+    public byte[] encode() throws UnsupportedEncodingException {
+        return encodeMms();
+    }
+
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java b/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java
new file mode 100644
index 0000000..8107bd8
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMapbMessageSms.java
@@ -0,0 +1,93 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import android.util.Log;
+
+import com.android.bluetooth.map.BluetoothMapSmsPdu.SmsPdu;
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+
+public class BluetoothMapbMessageSms extends BluetoothMapbMessage {
+
+    private ArrayList<SmsPdu> smsBodyPdus = null;
+    private String smsBody = null;
+
+    public void setSmsBodyPdus(ArrayList<SmsPdu> smsBodyPdus) {
+        this.smsBodyPdus = smsBodyPdus;
+        this.charset = null;
+        if(smsBodyPdus.size() > 0)
+            this.encoding = smsBodyPdus.get(0).getEncodingString();
+    }
+
+    public String getSmsBody() {
+        return smsBody;
+    }
+
+    public void setSmsBody(String smsBody) {
+        this.smsBody = smsBody;
+        this.charset = "UTF-8";
+        this.encoding = null;
+    }
+
+    @Override
+    public void parseMsgPart(String msgPart) {
+        if(appParamCharset == BluetoothMapAppParams.CHARSET_NATIVE) {
+            if(D) Log.d(TAG, "Decoding \"" + msgPart + "\" as native PDU");
+            byte[] msgBytes = decodeBinary(msgPart);
+            if(msgBytes.length > 0 &&
+                    msgBytes[0] < msgBytes.length-1 &&
+                    (msgBytes[msgBytes[0]+1] & 0x03) != 0x01) {
+                if(D) Log.d(TAG, "Only submit PDUs are supported");
+                throw new IllegalArgumentException("Only submit PDUs are supported");
+            }
+
+            smsBody += BluetoothMapSmsPdu.decodePdu(msgBytes,
+                    type == TYPE.SMS_CDMA ? BluetoothMapSmsPdu.SMS_TYPE_CDMA
+                                          : BluetoothMapSmsPdu.SMS_TYPE_GSM);
+        } else {
+            smsBody += msgPart;
+        }
+    }
+    @Override
+    public void parseMsgInit() {
+        smsBody = "";
+    }
+
+    public byte[] encode() throws UnsupportedEncodingException
+    {
+        ArrayList<byte[]> bodyFragments = new ArrayList<byte[]>();
+
+        /* Store the messages in an ArrayList to be able to handle the different message types in a generic way.
+         * We use byte[] since we need to extract the length in bytes.
+         */
+        if(smsBody != null) {
+            String tmpBody = smsBody.replaceAll("END:MSG", "/END\\:MSG"); // Replace any occurrences of END:MSG with \END:MSG
+            bodyFragments.add(tmpBody.getBytes("UTF-8"));
+        }else if (smsBodyPdus != null && smsBodyPdus.size() > 0) {
+            for (SmsPdu pdu : smsBodyPdus) {
+                // This cannot(must not) contain END:MSG
+                bodyFragments.add(encodeBinary(pdu.getData(),pdu.getScAddress()).getBytes("UTF-8"));
+            }
+        } else {
+            bodyFragments.add(new byte[0]); // TODO: Is this allowed? (An empty message)
+        }
+
+        return encodeGeneric(bodyFragments);
+    }
+
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMnsObexClient.java b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
new file mode 100644
index 0000000..544c621
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMnsObexClient.java
@@ -0,0 +1,371 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.obex.ApplicationParameter;
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ObexTransport;
+import javax.obex.ResponseCodes;
+
+/**
+ * The Message Notification Service class runs its own message handler thread,
+ * to avoid executing long operations on the MAP service Thread.
+ * This handler context is passed to the content observers,
+ * hence all call-backs (and thereby transmission of data) is executed
+ * from this thread.
+ */
+public class BluetoothMnsObexClient {
+
+    private static final String TAG = "BluetoothMnsObexClient";
+    private static final boolean D = false;
+    private static final boolean V = false;
+
+    private ObexTransport mTransport;
+    private Context mContext;
+    public Handler mHandler = null;
+    private volatile boolean mWaitingForRemote;
+    private static final String TYPE_EVENT = "x-bt/MAP-event-report";
+    private ClientSession mClientSession;
+    private boolean mConnected = false;
+    BluetoothDevice mRemoteDevice;
+    private BluetoothMapContentObserver mObserver;
+    private boolean mObserverRegistered = false;
+
+    // Used by the MAS to forward notification registrations
+    public static final int MSG_MNS_NOTIFICATION_REGISTRATION = 1;
+
+
+    public static final ParcelUuid BluetoothUuid_ObexMns =
+            ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
+
+
+    public BluetoothMnsObexClient(Context context, BluetoothDevice remoteDevice) {
+        if (remoteDevice == null) {
+            throw new NullPointerException("Obex transport is null");
+        }
+        HandlerThread thread = new HandlerThread("BluetoothMnsObexClient");
+        thread.start();
+        Looper looper = thread.getLooper();
+        mHandler = new MnsObexClientHandler(looper);
+        mContext = context;
+        mRemoteDevice = remoteDevice;
+        mObserver = new BluetoothMapContentObserver(mContext);
+        mObserver.init();
+    }
+
+    public Handler getMessageHandler() {
+        return mHandler;
+    }
+
+    public BluetoothMapContentObserver getContentObserver() {
+        return mObserver;
+    }
+
+    private final class MnsObexClientHandler extends Handler {
+        private MnsObexClientHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+            case MSG_MNS_NOTIFICATION_REGISTRATION:
+                handleRegistration(msg.arg1 /*masId*/, msg.arg2 /*status*/);
+                break;
+            default:
+                break;
+            }
+        }
+    }
+
+    public boolean isConnected() {
+        return mConnected;
+    }
+
+    /**
+     * Disconnect the connection to MNS server.
+     * Call this when the MAS client requests a de-registration on events.
+     */
+    public void disconnect() {
+        try {
+            if (mClientSession != null) {
+                mClientSession.disconnect(null);
+                if (D) Log.d(TAG, "OBEX session disconnected");
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "OBEX session disconnect error " + e.getMessage());
+        }
+        try {
+            if (mClientSession != null) {
+                if (D) Log.d(TAG, "OBEX session close mClientSession");
+                mClientSession.close();
+                mClientSession = null;
+                if (D) Log.d(TAG, "OBEX session closed");
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "OBEX session close error:" + e.getMessage());
+        }
+        if (mTransport != null) {
+            try {
+                if (D) Log.d(TAG, "Close Obex Transport");
+                mTransport.close();
+                mTransport = null;
+                mConnected = false;
+                if (D) Log.d(TAG, "Obex Transport Closed");
+            } catch (IOException e) {
+                Log.e(TAG, "mTransport.close error: " + e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Shutdown the MNS.
+     */
+    public void shutdown() {
+        /* should shutdown handler thread first to make sure
+         * handleRegistration won't be called when disconnet
+         */
+        if (mHandler != null) {
+            // Shut down the thread
+            mHandler.removeCallbacksAndMessages(null);
+            Looper looper = mHandler.getLooper();
+            if (looper != null) {
+                looper.quit();
+            }
+            mHandler = null;
+        }
+
+        /* Disconnect if connected */
+        disconnect();
+
+        if(mObserverRegistered) {
+            mObserver.unregisterObserver();
+            mObserverRegistered = false;
+        }
+        if (mObserver != null) {
+            mObserver.deinit();
+            mObserver = null;
+        }
+    }
+
+    private HeaderSet hsConnect = null;
+
+    public void handleRegistration(int masId, int notificationStatus){
+        Log.d(TAG, "handleRegistration( " + masId + ", " + notificationStatus + ")");
+
+        if((isConnected() == false) &&
+           (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES)) {
+            Log.d(TAG, "handleRegistration: connect");
+            connect();
+        }
+
+        if(notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_NO) {
+            // Unregister - should we disconnect, or keep the connection? - the spec. says nothing about this.
+            if(mObserverRegistered == true) {
+                mObserver.unregisterObserver();
+                mObserverRegistered = false;
+                disconnect();
+            }
+        } else if(notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) {
+            /* Connect if we do not have a connection, and start the content observers providing
+             * this thread as Handler.
+             */
+            if(mObserverRegistered == false) {
+                mObserver.registerObserver(this, masId);
+                mObserverRegistered = true;
+            }
+        }
+    }
+
+    public void connect() {
+        Log.d(TAG, "handleRegistration: connect 2");
+
+        BluetoothSocket btSocket = null;
+        try {
+            btSocket = mRemoteDevice.createInsecureRfcommSocketToServiceRecord(
+                    BluetoothUuid_ObexMns.getUuid());
+            btSocket.connect();
+        } catch (IOException e) {
+            Log.e(TAG, "BtSocket Connect error " + e.getMessage(), e);
+            // TODO: do we need to report error somewhere?
+            return;
+        }
+
+        mTransport = new BluetoothMnsRfcommTransport(btSocket);
+
+        try {
+            mClientSession = new ClientSession(mTransport);
+            mConnected = true;
+        } catch (IOException e1) {
+            Log.e(TAG, "OBEX session create error " + e1.getMessage());
+        }
+        if (mConnected && mClientSession != null) {
+            mConnected = false;
+            HeaderSet hs = new HeaderSet();
+            // bb582b41-420c-11db-b0de-0800200c9a66
+            byte[] mnsTarget = { (byte) 0xbb, (byte) 0x58, (byte) 0x2b, (byte) 0x41,
+                                 (byte) 0x42, (byte) 0x0c, (byte) 0x11, (byte) 0xdb,
+                                 (byte) 0xb0, (byte) 0xde, (byte) 0x08, (byte) 0x00,
+                                 (byte) 0x20, (byte) 0x0c, (byte) 0x9a, (byte) 0x66 };
+            hs.setHeader(HeaderSet.TARGET, mnsTarget);
+
+            synchronized (this) {
+                mWaitingForRemote = true;
+            }
+            try {
+                hsConnect = mClientSession.connect(hs);
+                if (D) Log.d(TAG, "OBEX session created");
+                mConnected = true;
+            } catch (IOException e) {
+                Log.e(TAG, "OBEX session connect error " + e.getMessage());
+            }
+        }
+            synchronized (this) {
+                mWaitingForRemote = false;
+        }
+    }
+
+    public int sendEvent(byte[] eventBytes, int masInstanceId) {
+
+        boolean error = false;
+        int responseCode = -1;
+        HeaderSet request;
+        int maxChunkSize, bytesToWrite, bytesWritten = 0;
+        ClientSession clientSession = mClientSession;
+
+        if ((!mConnected) || (clientSession == null)) {
+            Log.w(TAG, "sendEvent after disconnect:" + mConnected);
+            return responseCode;
+        }
+
+        request = new HeaderSet();
+        BluetoothMapAppParams appParams = new BluetoothMapAppParams();
+        appParams.setMasInstanceId(masInstanceId);
+
+        ClientOperation putOperation = null;
+        OutputStream outputStream = null;
+
+        try {
+            request.setHeader(HeaderSet.TYPE, TYPE_EVENT);
+            request.setHeader(HeaderSet.APPLICATION_PARAMETER, appParams.EncodeParams());
+
+            if (hsConnect.mConnectionID != null) {
+                request.mConnectionID = new byte[4];
+                System.arraycopy(hsConnect.mConnectionID, 0, request.mConnectionID, 0, 4);
+            } else {
+                Log.w(TAG, "sendEvent: no connection ID");
+            }
+
+            synchronized (this) {
+                mWaitingForRemote = true;
+            }
+            // Send the header first and then the body
+            try {
+                if (V) Log.v(TAG, "Send headerset Event ");
+                putOperation = (ClientOperation)clientSession.put(request);
+                // TODO - Should this be kept or Removed
+
+            } catch (IOException e) {
+                Log.e(TAG, "Error when put HeaderSet " + e.getMessage());
+                error = true;
+            }
+            synchronized (this) {
+                mWaitingForRemote = false;
+            }
+            if (!error) {
+                try {
+                    if (V) Log.v(TAG, "Send headerset Event ");
+                    outputStream = putOperation.openOutputStream();
+                } catch (IOException e) {
+                    Log.e(TAG, "Error when opening OutputStream " + e.getMessage());
+                    error = true;
+                }
+            }
+
+            if (!error) {
+
+                maxChunkSize = putOperation.getMaxPacketSize();
+
+                while (bytesWritten < eventBytes.length) {
+                    bytesToWrite = Math.min(maxChunkSize, eventBytes.length - bytesWritten);
+                    outputStream.write(eventBytes, bytesWritten, bytesToWrite);
+                    bytesWritten += bytesToWrite;
+                }
+
+                if (bytesWritten == eventBytes.length) {
+                    Log.i(TAG, "SendEvent finished send length" + eventBytes.length);
+                } else {
+                    error = true;
+                    putOperation.abort();
+                    Log.i(TAG, "SendEvent interrupted");
+                }
+            }
+        } catch (IOException e) {
+            handleSendException(e.toString());
+            error = true;
+        } catch (IndexOutOfBoundsException e) {
+            handleSendException(e.toString());
+            error = true;
+        } finally {
+            try {
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing stream after send " + e.getMessage());
+            }
+            try {
+                if ((!error) && (putOperation != null)) {
+                    responseCode = putOperation.getResponseCode();
+                    if (responseCode != -1) {
+                        if (V) Log.v(TAG, "Put response code " + responseCode);
+                        if (responseCode != ResponseCodes.OBEX_HTTP_OK) {
+                            Log.i(TAG, "Response error code is " + responseCode);
+                        }
+                    }
+                }
+                if (putOperation != null) {
+                    putOperation.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing stream after send " + e.getMessage());
+            }
+        }
+
+        return responseCode;
+    }
+
+    private void handleSendException(String exception) {
+        Log.e(TAG, "Error when sending event: " + exception);
+    }
+}
diff --git a/src/com/android/bluetooth/map/BluetoothMnsRfcommTransport.java b/src/com/android/bluetooth/map/BluetoothMnsRfcommTransport.java
new file mode 100644
index 0000000..fc5d54a
--- /dev/null
+++ b/src/com/android/bluetooth/map/BluetoothMnsRfcommTransport.java
@@ -0,0 +1,79 @@
+/*
+* Copyright (C) 2013 Samsung System LSI
+* 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.map;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMnsRfcommTransport implements ObexTransport {
+
+    private final BluetoothSocket mSocket;
+
+    public BluetoothMnsRfcommTransport(BluetoothSocket socket) {
+        super();
+        this.mSocket = socket;
+    }
+
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    public void connect() throws IOException {
+    }
+
+    public void create() throws IOException {
+    }
+
+    public void disconnect() throws IOException {
+    }
+
+    public void listen() throws IOException {
+    }
+
+    public boolean isConnected() throws IOException {
+        // TODO: add implementation
+        return true;
+    }
+
+    public String getRemoteAddress() {
+        if (mSocket == null)
+            return null;
+        return mSocket.getRemoteDevice().getAddress();
+    }
+
+}
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java b/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
index fa0c8b2..d91d9a2 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapCallLogComposer.java
@@ -16,7 +16,6 @@
 package com.android.bluetooth.pbap;
 
 import com.android.bluetooth.R;
-import com.android.internal.telephony.CallerInfo;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -60,7 +59,7 @@
     /** The projection to use when querying the call log table */
     private static final String[] sCallLogProjection = new String[] {
             Calls.NUMBER, Calls.DATE, Calls.TYPE, Calls.CACHED_NAME, Calls.CACHED_NUMBER_TYPE,
-            Calls.CACHED_NUMBER_LABEL
+            Calls.CACHED_NUMBER_LABEL, Calls.NUMBER_PRESENTATION
     };
     private static final int NUMBER_COLUMN_INDEX = 0;
     private static final int DATE_COLUMN_INDEX = 1;
@@ -68,6 +67,7 @@
     private static final int CALLER_NAME_COLUMN_INDEX = 3;
     private static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 4;
     private static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 5;
+    private static final int NUMBER_PRESENTATION_COLUMN_INDEX = 6;
 
     // Property for call log entry
     private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME";
@@ -139,24 +139,22 @@
                 VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING;
         final VCardBuilder builder = new VCardBuilder(vcardType);
         String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX);
+        String number = mCursor.getString(NUMBER_COLUMN_INDEX);
+        final int numberPresentation = mCursor.getInt(NUMBER_PRESENTATION_COLUMN_INDEX);
         if (TextUtils.isEmpty(name)) {
             name = "";
         }
-        if (CallerInfo.UNKNOWN_NUMBER.equals(name) || CallerInfo.PRIVATE_NUMBER.equals(name) ||
-                CallerInfo.PAYPHONE_NUMBER.equals(name)) {
+        if (numberPresentation != Calls.PRESENTATION_ALLOWED) {
             // setting name to "" as FN/N must be empty fields in this case.
             name = "";
+            // TODO: there are really 3 possible strings that could be set here:
+            // "unknown", "private", and "payphone".
+            number = mContext.getString(R.string.unknownNumber);
         }
         final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name));
         builder.appendLine(VCardConstants.PROPERTY_FN, name, needCharset, false);
         builder.appendLine(VCardConstants.PROPERTY_N, name, needCharset, false);
 
-        String number = mCursor.getString(NUMBER_COLUMN_INDEX);
-        if (CallerInfo.UNKNOWN_NUMBER.equals(number) ||
-                CallerInfo.PRIVATE_NUMBER.equals(number) ||
-                CallerInfo.PAYPHONE_NUMBER.equals(number)) {
-            number = mContext.getString(R.string.unknownNumber);
-        }
         final int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
         String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
         if (TextUtils.isEmpty(label)) {
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index a45bc9a..2f577d5 100755
--- a/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -242,6 +242,8 @@
                     Intent timeoutIntent =
                         new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL);
                     timeoutIntent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
+                    timeoutIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                     BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
                     sendBroadcast(timeoutIntent, BLUETOOTH_ADMIN_PERM);
                 }
                 // Release all resources
@@ -250,7 +252,11 @@
                 removeTimeoutMsg = false;
             }
         } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
-            if (!isWaitingAuthorization) {
+            int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                           BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
+
+            if ((!isWaitingAuthorization) ||
+                (requestType != BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS)) {
                 // this reply is not for us
                 return;
             }
@@ -580,8 +586,9 @@
                         intent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, getPackageName());
                         intent.putExtra(BluetoothDevice.EXTRA_CLASS_NAME,
                                         BluetoothPbapReceiver.class.getName());
-                        sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+
                         isWaitingAuthorization = true;
+                        sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
 
                         if (VERBOSE) Log.v(TAG, "waiting for authorization for connection from: "
                                 + sRemoteDeviceName);
@@ -628,6 +635,8 @@
                 case USER_TIMEOUT:
                     Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL);
                     intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
+                    intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
+                                    BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);
                     sendBroadcast(intent);
                     isWaitingAuthorization = false;
                     stopObexServerSession();
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
index 001d4c2..3568299 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
@@ -51,7 +51,6 @@
 import com.android.bluetooth.R;
 import com.android.vcard.VCardComposer;
 import com.android.vcard.VCardConfig;
-import com.android.internal.telephony.CallerInfo;
 import com.android.vcard.VCardPhoneNumberTranslationCallback;
 
 import java.io.IOException;
@@ -200,10 +199,11 @@
         final Uri myUri = CallLog.Calls.CONTENT_URI;
         String selection = BluetoothPbapObexServer.createSelectionPara(type);
         String[] projection = new String[] {
-                Calls.NUMBER, Calls.CACHED_NAME
+                Calls.NUMBER, Calls.CACHED_NAME, Calls.NUMBER_PRESENTATION
         };
         final int CALLS_NUMBER_COLUMN_INDEX = 0;
         final int CALLS_NAME_COLUMN_INDEX = 1;
+        final int CALLS_NUMBER_PRESENTATION_COLUMN_INDEX = 2;
 
         Cursor callCursor = null;
         ArrayList<String> list = new ArrayList<String>();
@@ -216,11 +216,12 @@
                     String name = callCursor.getString(CALLS_NAME_COLUMN_INDEX);
                     if (TextUtils.isEmpty(name)) {
                         // name not found, use number instead
-                        name = callCursor.getString(CALLS_NUMBER_COLUMN_INDEX);
-                        if (CallerInfo.UNKNOWN_NUMBER.equals(name) ||
-                                CallerInfo.PRIVATE_NUMBER.equals(name) ||
-                                CallerInfo.PAYPHONE_NUMBER.equals(name)) {
+                        final int numberPresentation = callCursor.getInt(
+                                CALLS_NUMBER_PRESENTATION_COLUMN_INDEX);
+                        if (numberPresentation != Calls.PRESENTATION_ALLOWED) {
                             name = mContext.getString(R.string.unknownNumber);
+                        } else {
+                            name = callCursor.getString(CALLS_NUMBER_COLUMN_INDEX);
                         }
                     }
                     list.add(name);
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100755
index 0000000..ce9be11
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := optional
+LOCAL_CERTIFICATE := platform
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.emailcommon
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := BluetoothProfileTests
+
+LOCAL_INSTRUMENTATION_FOR := Bluetooth
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100755
index 0000000..c022b22
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.bluetooth.tests">
+
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+    <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.READ_CALL_LOG" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="com.android.permission.HANDOVER_STATUS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
+    <uses-permission android:name="android.permission.NET_ADMIN" />
+    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.NET_TUNNELING" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.BLUETOOTH_STACK" />
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+    <uses-permission android:name="android.permission.MANAGE_USERS"/>
+    <uses-permission android:name="com.google.android.gallery3d.permission.GALLERY_PROVIDER"/>
+    <uses-permission android:name="com.android.gallery3d.permission.GALLERY_PROVIDER"/>
+
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.READ_SMS" />
+    <uses-permission android:name="android.permission.WRITE_SMS" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+
+    <uses-permission android:name="com.android.email.permission.ACCESS_PROVIDER"/>
+
+    <!-- For PBAP Owner Vcard Info -->
+    <uses-permission android:name="android.permission.READ_PROFILE"/>
+
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" />
+        <uses-permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" />
+        <path-permission
+                android:path="/btopp"
+                android:permission="android.permission.ACCESS_BLUETOOTH_SHARE" />
+    </application>
+    <!--
+    This declares that this application uses the instrumentation test runner targeting
+    the package of com.android.bluetooth.  To run the tests use the command:
+    "adb shell am instrument -w com.android.bluetooth.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.bluetooth"
+                     android:label="Tests for com.android.bluetooth"/>
+</manifest>
+
diff --git a/tests/src/com/android/bluetooth/tests/BluetoothMapContentTest.java b/tests/src/com/android/bluetooth/tests/BluetoothMapContentTest.java
new file mode 100644
index 0000000..9e318c6
--- /dev/null
+++ b/tests/src/com/android/bluetooth/tests/BluetoothMapContentTest.java
@@ -0,0 +1,102 @@
+package com.android.bluetooth.tests;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.database.Cursor;
+import android.content.Context;
+import android.content.ContentResolver;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.android.bluetooth.map.BluetoothMapContent;
+import com.android.bluetooth.map.BluetoothMapContentObserver;
+
+import com.android.emailcommon.provider.EmailContent;
+import com.android.emailcommon.provider.EmailContent.Message;
+import com.android.emailcommon.provider.EmailContent.MessageColumns;
+import com.android.emailcommon.provider.EmailContent.SyncColumns;
+
+public class BluetoothMapContentTest extends AndroidTestCase {
+    private static final String TAG = "BluetoothMapContentTest";
+
+    private static final boolean D = true;
+    private static final boolean V = true;
+
+    private Context mContext;
+    private ContentResolver mResolver;
+
+    static final String[] EMAIL_PROJECTION = new String[] {
+        EmailContent.RECORD_ID,
+        MessageColumns.DISPLAY_NAME, MessageColumns.TIMESTAMP,
+        MessageColumns.SUBJECT, MessageColumns.FLAG_READ,
+        MessageColumns.FLAG_ATTACHMENT, MessageColumns.FLAGS,
+        SyncColumns.SERVER_ID, MessageColumns.DRAFT_INFO,
+        MessageColumns.MESSAGE_ID, MessageColumns.MAILBOX_KEY,
+        MessageColumns.ACCOUNT_KEY, MessageColumns.FROM_LIST,
+        MessageColumns.TO_LIST, MessageColumns.CC_LIST,
+        MessageColumns.BCC_LIST, MessageColumns.REPLY_TO_LIST,
+        SyncColumns.SERVER_TIMESTAMP, MessageColumns.MEETING_INFO,
+        MessageColumns.SNIPPET, MessageColumns.PROTOCOL_SEARCH_INFO,
+        MessageColumns.THREAD_TOPIC
+    };
+
+    private String getDateTimeString(long timestamp) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
+        Date date = new Date(timestamp);
+        return format.format(date); // Format to YYYYMMDDTHHMMSS local time
+    }
+
+    private void printEmail(Cursor c) {
+        if (D) Log.d(TAG, "printEmail " +
+            c.getLong(c.getColumnIndex(EmailContent.RECORD_ID)) +
+            "\n   " + MessageColumns.DISPLAY_NAME + " : " + c.getString(c.getColumnIndex(MessageColumns.DISPLAY_NAME)) +
+            "\n   " + MessageColumns.TIMESTAMP + " : " + getDateTimeString(c.getLong(c.getColumnIndex(MessageColumns.TIMESTAMP))) +
+            "\n   " + MessageColumns.SUBJECT + " : " + c.getString(c.getColumnIndex(MessageColumns.SUBJECT)) +
+            "\n   " + MessageColumns.FLAG_READ + " : " + c.getString(c.getColumnIndex(MessageColumns.FLAG_READ)) +
+            "\n   " + MessageColumns.FLAG_ATTACHMENT + " : " + c.getInt(c.getColumnIndex(MessageColumns.FLAG_ATTACHMENT)) +
+            "\n   " + MessageColumns.FLAGS + " : " + c.getInt(c.getColumnIndex(MessageColumns.FLAGS)) +
+            "\n   " + SyncColumns.SERVER_ID + " : " + c.getInt(c.getColumnIndex(SyncColumns.SERVER_ID)) +
+            "\n   " + MessageColumns.DRAFT_INFO + " : " + c.getInt(c.getColumnIndex(MessageColumns.DRAFT_INFO)) +
+            "\n   " + MessageColumns.MESSAGE_ID + " : " + c.getInt(c.getColumnIndex(MessageColumns.MESSAGE_ID)) +
+            "\n   " + MessageColumns.MAILBOX_KEY + " : " + c.getInt(c.getColumnIndex(MessageColumns.MAILBOX_KEY)) +
+            "\n   " + MessageColumns.ACCOUNT_KEY + " : " + c.getInt(c.getColumnIndex(MessageColumns.ACCOUNT_KEY)) +
+            "\n   " + MessageColumns.FROM_LIST + " : " + c.getString(c.getColumnIndex(MessageColumns.FROM_LIST)) +
+            "\n   " + MessageColumns.TO_LIST + " : " + c.getString(c.getColumnIndex(MessageColumns.TO_LIST)) +
+            "\n   " + MessageColumns.CC_LIST + " : " + c.getString(c.getColumnIndex(MessageColumns.CC_LIST)) +
+            "\n   " + MessageColumns.BCC_LIST + " : " + c.getString(c.getColumnIndex(MessageColumns.BCC_LIST)) +
+            "\n   " + MessageColumns.REPLY_TO_LIST + " : " + c.getString(c.getColumnIndex(MessageColumns.REPLY_TO_LIST)) +
+            "\n   " + SyncColumns.SERVER_TIMESTAMP + " : " + getDateTimeString(c.getLong(c.getColumnIndex(SyncColumns.SERVER_TIMESTAMP))) +
+            "\n   " + MessageColumns.MEETING_INFO + " : " + c.getString(c.getColumnIndex(MessageColumns.MEETING_INFO)) +
+            "\n   " + MessageColumns.SNIPPET + " : " + c.getString(c.getColumnIndex(MessageColumns.SNIPPET)) +
+            "\n   " + MessageColumns.PROTOCOL_SEARCH_INFO + " : " + c.getString(c.getColumnIndex(MessageColumns.PROTOCOL_SEARCH_INFO)) +
+            "\n   " + MessageColumns.THREAD_TOPIC + " : " + c.getString(c.getColumnIndex(MessageColumns.THREAD_TOPIC)));
+    }
+
+    public void dumpEmailMessageTable() {
+        Log.d(TAG, "**** Dump of email message table ****");
+
+        Cursor c = mResolver.query(Message.CONTENT_URI,
+            EMAIL_PROJECTION, null, null, "_id DESC");
+        if (c != null) {
+            Log.d(TAG, "c.getCount() = " + c.getCount());
+            c.moveToPosition(-1);
+            while (c.moveToNext()) {
+                printEmail(c);
+            }
+        } else {
+            Log.d(TAG, "query failed");
+            c.close();
+        }
+    }
+
+    public BluetoothMapContentTest() {
+        super();
+    }
+
+    public void testDumpMessages() {
+        mContext = this.getContext();
+        mResolver = mContext.getContentResolver();
+        dumpEmailMessageTable();
+    }
+}
diff --git a/tests/src/com/android/bluetooth/tests/BluetoothMapbMessageTest.java b/tests/src/com/android/bluetooth/tests/BluetoothMapbMessageTest.java
new file mode 100755
index 0000000..14c41da
--- /dev/null
+++ b/tests/src/com/android/bluetooth/tests/BluetoothMapbMessageTest.java
@@ -0,0 +1,505 @@
+package com.android.bluetooth.tests;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.apache.http.message.BasicHeaderValueFormatter;
+
+import android.preference.PreferenceFragment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.bluetooth.map.BluetoothMapAppParams;
+import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+import com.android.bluetooth.map.BluetoothMapSmsPdu;
+import com.android.bluetooth.map.BluetoothMapbMessage;
+import com.android.bluetooth.map.BluetoothMapbMessageMmsEmail;
+import com.android.bluetooth.map.BluetoothMapbMessageSms;
+import org.apache.http.message.BasicHeaderValueFormatter;
+import org.apache.http.message.BasicHeaderElement;
+
+/***
+ *
+ * Test cases for the bMessage class. (encoding and decoding)
+ *
+ */
+public class BluetoothMapbMessageTest extends AndroidTestCase {
+    protected static String TAG = "BluetoothMapbMessageTest";
+    protected static final boolean D = true;
+
+    public BluetoothMapbMessageTest() {
+        super();
+    }
+
+    /***
+     * Test encoding of a simple SMS text message (UTF8). This validates most parameters.
+     */
+    public void testSmsEncodeText() {
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        String str1 =
+                 "BEGIN:BMSG\r\n" +
+                    "VERSION:1.0\r\n" +
+                    "STATUS:UNREAD\r\n" +
+                    "TYPE:SMS_GSM\r\n" +
+                    "FOLDER:telecom/msg/inbox\r\n" +
+                    "BEGIN:VCARD\r\n" +
+                        "VERSION:3.0\r\n" +
+                        "FN:Casper Bonde\r\n" +
+                        "N:Bonde,Casper\r\n" +
+                        "TEL:+4512345678\r\n" +
+                        "TEL:+4587654321\r\n" +
+                        "EMAIL:casper@email.add\r\n" +
+                        "EMAIL:bonde@email.add\r\n" +
+                    "END:VCARD\r\n" +
+                    "BEGIN:BENV\r\n" +
+                        "BEGIN:VCARD\r\n" +
+                            "VERSION:3.0\r\n" +
+                            "FN:Jens Hansen\r\n" +
+                            "N:\r\n" +
+                            "TEL:+4512345678\r\n" +
+                            "TEL:+4587654321\r\n" +
+                            "EMAIL:casper@email.add\r\n" +
+                            "EMAIL:bonde@email.add\r\n" +
+                        "END:VCARD\r\n" +
+                        "BEGIN:BBODY\r\n" +
+                            "CHARSET:UTF-8\r\n" +
+                            "LENGTH:45\r\n" +
+                            "BEGIN:MSG\r\n" +
+                                "This is a short message\r\n" +
+                            "END:MSG\r\n" +
+                        "END:BBODY\r\n" +
+                    "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+
+        String encoded;
+        String[] phone = {"+4512345678", "+4587654321"};
+        String[] email = {"casper@email.add", "bonde@email.add"};
+        msg.addOriginator("Bonde,Casper", "Casper Bonde", phone, email);
+        msg.addRecipient("", "Jens Hansen", phone, email);
+        msg.setFolder("inbox");
+        msg.setSmsBody("This is a short message");
+        msg.setStatus(false);
+        msg.setType(TYPE.SMS_GSM);
+        try {
+            encoded = new String(msg.encode());
+            if(D) Log.d(TAG, encoded);
+            assertTrue(str1.equals(encoded));
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed.", true);
+        }
+    }
+
+    /***
+     * Test native Deliver PDU encoding (decoding not possible), based on the example in the MAP 1.1 specification.
+     * The difference between this PDU, and the one in the specification:
+     *  - The invalid SC address 0191 is replaced with no address 00
+     *  - The "No more messages flag" is set (bit 2 in the second byte)
+     *  - The phone number type is changed from private 91 to international 81
+     *  - The time is changed to local time, since the time zone cannot be controlled through the API
+     */
+    public void testSmsEncodeNativeDeliverPdu() {
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");
+        Date date = new Date(System.currentTimeMillis());
+        String timeStr = format.format(date); // Format to YYMMDDTHHMMSS UTC time
+        ByteArrayOutputStream scTime = new ByteArrayOutputStream(7);
+        StringBuilder scTimeSb = new StringBuilder();
+        byte[] timeChars;
+        try {
+            timeChars = timeStr.getBytes("US-ASCII");
+        } catch (UnsupportedEncodingException e1) {
+            assertTrue("Failed to extract bytes from string using US-ASCII", true);
+            return;
+        }
+
+        for(int i = 0, n = timeStr.length(); i < n; i+=2) {
+            scTime.write((timeChars[i+1]-0x30) << 4 | (timeChars[i]-0x30)); // Offset from ascii char to decimal value
+        }
+
+        Calendar cal = Calendar.getInstance();
+        int offset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (15 * 60 * 1000); /* offset in quarters of an hour */
+        String offsetString;
+        if(offset < 0) {
+            offsetString = String.format("%1$02d", -(offset));
+            char[] offsetChars = offsetString.toCharArray();
+            scTime.write((offsetChars[1]-0x30) << 4 | 0x40 | (offsetChars[0]-0x30));
+        }
+        else {
+            offsetString = String.format("%1$02d", offset);
+            char[] offsetChars = offsetString.toCharArray();
+            scTime.write((offsetChars[1]-0x30) << 4 | (offsetChars[0]-0x30));
+        }
+        byte[] scTimeData = scTime.toByteArray();
+        for(int i = 0; i < scTimeData.length; i++) {
+            scTimeSb.append(Integer.toString((scTimeData[i] >> 4) & 0x0f,16)); // MS-nibble first
+            scTimeSb.append(Integer.toString( scTimeData[i]       & 0x0f,16));
+        }
+        if(D) Log.v(TAG, "Generated time string: " + scTimeSb.toString());
+        String expected =
+                 "BEGIN:BMSG\r\n" +
+                    "VERSION:1.0\r\n" +
+                    "STATUS:UNREAD\r\n" +
+                    "TYPE:SMS_GSM\r\n" +
+                    "FOLDER:telecom/msg/inbox\r\n" +
+                    "BEGIN:VCARD\r\n" +
+                        "VERSION:3.0\r\n" +
+                        "FN:Casper Bonde\r\n" +
+                        "N:Bonde,Casper\r\n" +
+                        "TEL:00498912345678\r\n" +
+                        "TEL:+4587654321\r\n" +
+                        "EMAIL:casper@email.add\r\n" +
+                        "EMAIL:bonde@email.add\r\n" +
+                    "END:VCARD\r\n" +
+                    "BEGIN:BENV\r\n" +
+                        "BEGIN:VCARD\r\n" +
+                            "VERSION:3.0\r\n" +
+                            "FN:Jens Hansen\r\n" +
+                            "N:\r\n" +
+                            "TEL:00498912345678\r\n" +
+                            "TEL:+4587654321\r\n" +
+                            "EMAIL:casper@email.add\r\n" +
+                            "EMAIL:bonde@email.add\r\n" +
+                        "END:VCARD\r\n" +
+                        "BEGIN:BBODY\r\n" +
+                            "ENCODING:G-7BIT\r\n" +
+                            "LENGTH:94\r\n" +
+                            "BEGIN:MSG\r\n" +
+                                "00040E81009498214365870000" + scTimeSb.toString() +
+                                "11CC32FD34079DDF20737A8E4EBBCF21\r\n" +
+                            "END:MSG\r\n" +
+                        "END:BBODY\r\n" +
+                    "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+
+        String encoded;
+        String[] phone = {"00498912345678", "+4587654321"};
+        String[] email = {"casper@email.add", "bonde@email.add"};
+        msg.addOriginator("Bonde,Casper", "Casper Bonde", phone, email);
+        msg.addRecipient("", "Jens Hansen", phone, email);
+        msg.setFolder("inbox");
+        /* TODO: extract current time, and build the expected string */
+        msg.setSmsBodyPdus(BluetoothMapSmsPdu.getDeliverPdus("Let's go fishing!", "00498912345678", date.getTime()));
+        msg.setStatus(false);
+        msg.setType(TYPE.SMS_GSM);
+        try {
+            byte[] encodedBytes = msg.encode();
+//            InputStream is = new ByteArrayInputStream(encodedBytes);
+            encoded = new String(encodedBytes);
+//            BluetoothMapbMessage newMsg = BluetoothMapbMessage.parse(is, BluetoothMapAppParams.CHARSET_NATIVE);
+//            String decoded = ((BluetoothMapbMessageSms) newMsg).getSmsBody();
+            if(D) Log.d(TAG, "\nExpected: \n" + expected);
+            if(D) Log.d(TAG, "\nEncoded: \n" + encoded);
+//            if(D) Log.d(TAG, "\nDecoded: \n" + decoded);
+            assertTrue(expected.equalsIgnoreCase(encoded));
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed.", true);
+        }
+    }
+
+    /***
+     * Test native Submit PDU encoding and decoding, based on the example in the MAP 1.1 specification.
+     * The difference between this PDU, and the one in the specification:
+     *  - The invalid SC address 0191 is replaced with no address 00
+     *  - The PDU is converted to a submit PDU by adding the TP-MR and removing the service center time stamp.
+     *  - The phone number type is changed from private 91 to international 81
+     */
+    public void testSmsEncodeDecodeNativeSubmitPdu() {
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        String expected =
+                 "BEGIN:BMSG\r\n" +
+                    "VERSION:1.0\r\n" +
+                    "STATUS:UNREAD\r\n" +
+                    "TYPE:SMS_GSM\r\n" +
+                    "FOLDER:telecom/msg/outbox\r\n" +
+                    "BEGIN:VCARD\r\n" +
+                        "VERSION:3.0\r\n" +
+                        "FN:Casper Bonde\r\n" +
+                        "N:Bonde,Casper\r\n" +
+                        "TEL:00498912345678\r\n" +
+                        "TEL:+4587654321\r\n" +
+                        "EMAIL:casper@email.add\r\n" +
+                        "EMAIL:bonde@email.add\r\n" +
+                    "END:VCARD\r\n" +
+                    "BEGIN:BENV\r\n" +
+                        "BEGIN:VCARD\r\n" +
+                            "VERSION:3.0\r\n" +
+                            "FN:Jens Hansen\r\n" +
+                            "N:\r\n" +
+                            "TEL:00498912345678\r\n" +
+                            "TEL:+4587654321\r\n" +
+                            "EMAIL:casper@email.add\r\n" +
+                            "EMAIL:bonde@email.add\r\n" +
+                        "END:VCARD\r\n" +
+                        "BEGIN:BBODY\r\n" +
+                            "ENCODING:G-7BIT\r\n" +
+                            "LENGTH:82\r\n" +
+                            "BEGIN:MSG\r\n" + /*Length 11 */
+                                "0001000E8100949821436587000011CC32FD34079DDF20737A8E4EBBCF21\r\n" + /* Length 62 */
+                            "END:MSG\r\n" + /* Length 9 */
+                        "END:BBODY\r\n" +
+                    "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+
+        String encoded;
+        String[] phone = {"00498912345678", "+4587654321"};
+        String[] email = {"casper@email.add", "bonde@email.add"};
+        msg.addOriginator("Bonde,Casper", "Casper Bonde", phone, email);
+        msg.addRecipient("", "Jens Hansen", phone, email);
+        msg.setFolder("outbox");
+        /* TODO: extract current time, and build the expected string */
+        msg.setSmsBodyPdus(BluetoothMapSmsPdu.getSubmitPdus("Let's go fishing!", "00498912345678"));
+        msg.setStatus(false);
+        msg.setType(TYPE.SMS_GSM);
+        try {
+            byte[] encodedBytes = msg.encode();
+            InputStream is = new ByteArrayInputStream(encodedBytes);
+            encoded = new String(encodedBytes);
+            BluetoothMapbMessage newMsg = BluetoothMapbMessage.parse(is, BluetoothMapAppParams.CHARSET_NATIVE);
+            String decoded = ((BluetoothMapbMessageSms) newMsg).getSmsBody();
+            if(D) Log.d(TAG, "\nCalling encoder on decoded message to log its content");
+            newMsg.encode();
+            if(D) Log.d(TAG, "\nExpected: \n" + expected);
+            if(D) Log.d(TAG, "\nEncoded: \n" + encoded);
+            if(D) Log.d(TAG, "\nDecoded: \n" + decoded);
+            assertTrue("The encoded bMessage do not match the expected.", expected.equalsIgnoreCase(encoded));
+            assertTrue("The decoded text is \"" + decoded + "\" - expected \"Let's go fishing!\"", decoded.equalsIgnoreCase("Let's go fishing!"));
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed.", true);
+        }
+    }
+
+    /***
+     * Test native Submit PDU encoding and decoding, based on the example in the MAP 1.1 specification.
+     * The difference between this PDU, and the one in the specification:
+     *  - The invalid SC address 0191 is replaced with no address 00
+     *  - The PDU is converted to a submit PDU by adding the TP-MR and removing the service center time stamp.
+     *  - The phone number type is changed from private 91 to international 81
+     */
+    public void testSmsEncodeDecodeNativeSubmitPduWithSc() {
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        String encoded =
+                 "BEGIN:BMSG\r\n" +
+                    "VERSION:1.0\r\n" +
+                    "STATUS:UNREAD\r\n" +
+                    "TYPE:SMS_GSM\r\n" +
+                    "FOLDER:telecom/msg/outbox\r\n" +
+                    "BEGIN:VCARD\r\n" +
+                        "VERSION:3.0\r\n" +
+                        "FN:Casper Bonde\r\n" +
+                        "N:Bonde,Casper\r\n" +
+                        "TEL:00498912345678\r\n" +
+                        "TEL:+4587654321\r\n" +
+                        "EMAIL:casper@email.add\r\n" +
+                        "EMAIL:bonde@email.add\r\n" +
+                    "END:VCARD\r\n" +
+                    "BEGIN:BENV\r\n" +
+                        "BEGIN:VCARD\r\n" +
+                            "VERSION:3.0\r\n" +
+                            "FN:Jens Hansen\r\n" +
+                            "N:\r\n" +
+                            "TEL:00498912345678\r\n" +
+                            "TEL:+4587654321\r\n" +
+                            "EMAIL:casper@email.add\r\n" +
+                            "EMAIL:bonde@email.add\r\n" +
+                        "END:VCARD\r\n" +
+                        "BEGIN:BBODY\r\n" +
+                            "ENCODING:G-7BIT\r\n" +
+                            "LENGTH:58 \r\n" +
+                            "BEGIN:MSG\r\n" + /*Length 11 */
+                                "018001000B912184254590F500000346F61B\r\n" + /* Length 38 */
+                            "END:MSG\r\n" + /* Length 9 */
+                        "END:BBODY\r\n" +
+                    "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+        try {
+            String expected = "Flo";
+            InputStream is = new ByteArrayInputStream(encoded.getBytes("UTF-8"));
+            BluetoothMapbMessage newMsg = BluetoothMapbMessage.parse(is, BluetoothMapAppParams.CHARSET_NATIVE);
+            String decoded = ((BluetoothMapbMessageSms) newMsg).getSmsBody();
+            if(D) Log.d(TAG, "\nEncoded: \n" + encoded);
+            if(D) Log.d(TAG, "\nDecoded: \n" + decoded);
+            assertTrue("Decoded string (" + decoded + ") did not match expected (" + expected + ")", expected.equals(decoded));
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed.", false);
+        }
+    }
+
+    /***
+     * Validate that the folder is correctly truncated to 512 bytes, if a longer folder path
+     * is supplied.
+     */
+    public void testFolderLengthTruncation() {
+        String folder = "";
+        int levelCount = 0;
+        while(folder.length()<640)
+            folder += "/folder" + levelCount++;
+
+        String expected = folder.substring(folder.length()-512, folder.length());
+
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        msg.setFolder(folder);
+        msg.setStatus(false);
+        msg.setType(TYPE.SMS_GSM);
+
+        try {
+            byte[] encoded = msg.encode();
+            InputStream is = new ByteArrayInputStream(encoded);
+            if(D) Log.d(TAG, new String(encoded));
+            BluetoothMapbMessage newMsg = BluetoothMapbMessage.parse(is, BluetoothMapAppParams.CHARSET_UTF8);
+            assertTrue("Wrong length expected 512, got " + expected.length(), expected.length() == 512);
+            Log.d(TAG, "expected:           " + expected);
+            Log.d(TAG, "newMsg.getFolder(): " + newMsg.getFolder());
+            assertTrue("Folder string did not match", expected.equals(newMsg.getFolder()));
+
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed", false);
+        }
+    }
+
+    /***
+     * Test multipart message decoding.
+     */
+    public void testSmsMultipartDecode() {
+        BluetoothMapbMessageSms msg = new BluetoothMapbMessageSms();
+        String encoded =
+                 "BEGIN:BMSG\r\n" +
+                 "VERSION:1.0\r\n" +
+                 "STATUS:READ\r\n" +
+                 "TYPE:SMS_GSM\r\n" +
+                 "FOLDER:/telecom/msg/outbox\r\n" +
+                 "BEGIN:VCARD\r\n" +
+                 "VERSION:2.1\r\n" +
+                 "N:12485254094 \r\n" +
+                 "TEL:12485254094\r\n" +
+                 "END:VCARD\r\n" +
+                 "BEGIN:BENV\r\n" +
+                 "BEGIN:VCARD\r\n" +
+                 "VERSION:2.1\r\n" +
+                 "N:+12485254095 \r\n" +
+                 "TEL:+12485254095\r\n" +
+                 "END:VCARD\r\n" +
+                 "BEGIN:BBODY\r\n" +
+                 "ENCODING:G-7BIT\r\n" +
+                 "LENGTH:762\r\n" +
+                 "BEGIN:MSG\r\n" +
+                 "018041000B912184254590F50000A0050003010301A8E8F41C949E83C220F69B0E7A9B41F7B79C3C07D1DF20F35BDE068541E3B77B1CA697DD617A990C6A97E7F3F0B90C0ABBC9203ABA0C32A7E5733A889E6E9741F437888E2E83E66537B92C07A5DBED32391DA697D97990FB4D4F9BF3A07619B476BFEFA03B3A4C07E5DF7550585E06B9DF74D0BC2E2F83F2EF3A681C7683C86F509A0EBABFEB\r\n" +
+                 "END:MSG\r\n" +
+                 "BEGIN:MSG\r\n" +
+                 "018041000B912184254590F50000A0050003010302C820767A5D06D1D16550DA4D2FBBC96532485E1EA7E1E9B29B0E82B3CBE17919644EBBC9A0779D0EA2A3CB20735A3EA783E8E8B4FB0CA2BF41E437C8FDA683E6757919947FD741E3B01B447E83D274D0FD5D679341ECB7BD0C4AD341F7F01C44479741E6B47C4E0791C379D0DB0C6AE741F2F2BCDE2E83CC6F3928FFAECB41E57638CD06A5E7\r\n" +
+                 "END:MSG\r\n" +
+                 "BEGIN:MSG\r\n" +
+                 "018041000B912184254590F500001A050003010303DC6F3A685E979741F9771D340EBB41E437\r\n" +
+                 "END:MSG\r\n" +
+                 "END:BBODY\r\n" +
+                 "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+        try {
+            InputStream is = new ByteArrayInputStream(encoded.getBytes("UTF-8"));
+            BluetoothMapbMessage newMsg = BluetoothMapbMessage.parse(is, BluetoothMapAppParams.CHARSET_NATIVE);
+            String decoded = ((BluetoothMapbMessageSms) newMsg).getSmsBody();
+            if(D) Log.d(TAG, "\nEncoded: \n" + encoded);
+            if(D) Log.d(TAG, "\nDecoded: \n" + decoded);
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Decoding failed.",e);
+            assertTrue("Decoding failed.", false);
+        }
+    }
+
+    /***
+     * Test encoding of a simple MMS text message (UTF8). This validates most parameters.
+     */
+    public void testMmsEncodeText() {
+        BluetoothMapbMessageMmsEmail msg = new BluetoothMapbMessageMmsEmail();
+        String str1 =
+                 "BEGIN:BMSG\r\n" +
+                    "VERSION:1.0\r\n" +
+                    "STATUS:UNREAD\r\n" +
+                    "TYPE:MMS\r\n" +
+                    "FOLDER:telecom/msg/inbox\r\n" +
+                    "BEGIN:VCARD\r\n" +
+                        "VERSION:3.0\r\n" +
+                        "FN:Casper Bonde\r\n" +
+                        "N:Bonde,Casper\r\n" +
+                        "TEL:+4512345678\r\n" +
+                        "TEL:+4587654321\r\n" +
+                        "EMAIL:casper@email.add\r\n" +
+                        "EMAIL:bonde@email.add\r\n" +
+                    "END:VCARD\r\n" +
+                    "BEGIN:BENV\r\n" +
+                        "BEGIN:VCARD\r\n" +
+                            "VERSION:3.0\r\n" +
+                            "FN:Jørn Hansen\r\n" +
+                            "N:\r\n" +
+                            "TEL:+4512345678\r\n" +
+                            "TEL:+4587654321\r\n" +
+                            "EMAIL:casper@email.add\r\n" +
+                            "EMAIL:bonde@email.add\r\n" +
+                        "END:VCARD\r\n" +
+                        "BEGIN:BBODY\r\n" +
+                            "CHARSET:UTF-8\r\n" +
+                            "LENGTH:45\r\n" +
+                            "BEGIN:MSG\r\n" +
+                                "This is a short message\r\n" +
+                            "END:MSG\r\n" +
+                        "END:BBODY\r\n" +
+                    "END:BENV\r\n" +
+                 "END:BMSG\r\n";
+
+        String encoded;
+        String[] phone = {"+4512345678", "+4587654321"};
+        String[] email = {"casper@email.add", "bonde@email.add"};
+        msg.addOriginator("Bonde,Casper", "Casper Bonde", phone, email);
+        msg.addRecipient("", "Jørn Hansen", phone, email);
+        msg.setFolder("inbox");
+        msg.setIncludeAttachments(false);
+        msg.addTo("Jørn Hansen", "bonde@email.add");
+        msg.addCc("Jens Hansen", "bonde@email.add");
+        msg.addFrom("Jørn Hansen", "bonde@email.add");
+        BluetoothMapbMessageMmsEmail.MimePart part = msg.addMimePart();
+        part.partName = "partNameText";
+        part.contentType ="dsfajfdlk/text/asdfafda";
+        try {
+            part.data = new String("This is a short message\r\n").getBytes("UTF-8");
+        }
+        catch (UnsupportedEncodingException e) {
+            if(D) Log.e(TAG, "UnsupportedEncodingException should never happen???", e);
+            assertTrue(false);
+        }
+
+        part = msg.addMimePart();
+        part.partName = "partNameimage";
+        part.contentType = "dsfajfdlk/image/asdfafda";
+        part.data = null;
+
+        msg.setStatus(false);
+        msg.setType(TYPE.MMS);
+        try {
+            encoded = new String(msg.encode());
+            if(D) Log.d(TAG, encoded);
+            assertTrue(str1.equals(encoded));
+        } catch (UnsupportedEncodingException e) {
+            Log.d(TAG, "Encoding failed.",e);
+            assertTrue("Encoding failed.", true);
+        }
+    }
+
+    public void testHeaderEncode() {
+        BasicHeaderElement header = new BasicHeaderElement("To","Jørgen <joergen@hest.com>");
+        String headerStr = BasicHeaderValueFormatter.formatHeaderElement(header, true, BasicHeaderValueFormatter.DEFAULT);
+        if(D) Log.i(TAG, "The encoded header: " + headerStr);
+    }
+
+}
+