summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRockchip2015-03-11 12:16:44 +0800
committerRockchip2015-03-11 12:16:44 +0800
commit934619bbfb5db8c1b99136916522f1bee2c19cb6 (patch)
tree0540c010ef53456876e395f0733033c2404584b2
parentdbd4096880391b804da9d85b344afa88bcf34013 (diff)
parent2ab3133a5c3a70fe1184ba8ff63ac3365f648a4e (diff)
Android 5.1.0 release 1
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlT0j0AACgkQ6K0/gZqxDnhYwACdEiy9JSDrwvkKoDDwK5mXtuzA MO0AoIATFpN1NiG582sL+xrew2MyEeWj =WLK4 -----END PGP SIGNATURE----- Merge tag 'android-5.1.0_r1' into android-5.0.2_r1 Android 5.1.0 release 1
-rwxr-xr-xjni/com_android_bluetooth_btservice_AdapterService.cpp6
-rw-r--r--jni/com_android_bluetooth_gatt.cpp16
-rw-r--r--res/values-bn-rBD/strings.xml5
-rw-r--r--res/values-eu-rES/strings.xml7
-rw-r--r--res/values-gl-rES/strings.xml5
-rw-r--r--res/values-hi/test_strings.xml2
-rw-r--r--res/values-is-rIS/strings.xml5
-rw-r--r--res/values-kk-rKZ/strings.xml5
-rw-r--r--res/values-km-rKH/strings.xml12
-rw-r--r--res/values-kn-rIN/strings.xml5
-rw-r--r--res/values-ky-rKG/strings.xml5
-rw-r--r--res/values-mk-rMK/strings.xml5
-rw-r--r--res/values-ml-rIN/strings.xml43
-rw-r--r--res/values-ml-rIN/strings_pbap.xml2
-rw-r--r--res/values-ml-rIN/test_strings.xml2
-rw-r--r--res/values-mr-rIN/strings.xml43
-rw-r--r--res/values-mr-rIN/strings_pbap.xml2
-rw-r--r--res/values-mr-rIN/test_strings.xml2
-rw-r--r--res/values-my-rMM/strings.xml15
-rw-r--r--res/values-ne-rNP/strings.xml5
-rw-r--r--res/values-si-rLK/strings.xml5
-rw-r--r--res/values-sl/strings.xml4
-rw-r--r--res/values-ta-rIN/strings.xml5
-rw-r--r--res/values-te-rIN/strings.xml5
-rw-r--r--res/values-ur-rPK/strings.xml5
-rw-r--r--res/values-uz-rUZ/strings.xml5
-rw-r--r--res/values-zh-rCN/strings_pbap.xml10
-rw-r--r--res/values-zh-rCN/test_strings.xml6
-rw-r--r--src/com/android/bluetooth/Utils.java46
-rwxr-xr-xsrc/com/android/bluetooth/a2dp/A2dpService.java11
-rw-r--r--src/com/android/bluetooth/a2dp/A2dpSinkService.java8
-rw-r--r--src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java9
-rwxr-xr-xsrc/com/android/bluetooth/a2dp/A2dpStateMachine.java8
-rwxr-xr-xsrc/com/android/bluetooth/avrcp/Avrcp.java27
-rw-r--r--src/com/android/bluetooth/avrcp/AvrcpControllerService.java5
-rw-r--r--src/com/android/bluetooth/btservice/AdapterService.java154
-rw-r--r--src/com/android/bluetooth/btservice/ProfileService.java34
-rw-r--r--src/com/android/bluetooth/gatt/AdvertiseManager.java102
-rw-r--r--src/com/android/bluetooth/gatt/ContextMap.java34
-rw-r--r--src/com/android/bluetooth/gatt/GattDebugUtils.java22
-rw-r--r--src/com/android/bluetooth/gatt/GattService.java113
-rw-r--r--src/com/android/bluetooth/gatt/HandleMap.java23
-rw-r--r--src/com/android/bluetooth/gatt/ScanManager.java5
-rw-r--r--src/com/android/bluetooth/hdp/HealthService.java17
-rw-r--r--[-rwxr-xr-x]src/com/android/bluetooth/hfp/HeadsetPhoneState.java270
-rwxr-xr-xsrc/com/android/bluetooth/hfp/HeadsetService.java9
-rw-r--r--[-rwxr-xr-x]src/com/android/bluetooth/hfp/HeadsetStateMachine.java35
-rw-r--r--src/com/android/bluetooth/hfpclient/HeadsetClientService.java8
-rw-r--r--src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java29
-rwxr-xr-xsrc/com/android/bluetooth/hid/HidService.java10
-rw-r--r--src/com/android/bluetooth/map/BluetoothMapContent.java679
-rw-r--r--src/com/android/bluetooth/map/BluetoothMapContentObserver.java380
-rw-r--r--src/com/android/bluetooth/map/BluetoothMapEmailSettingsLoader.java39
-rw-r--r--src/com/android/bluetooth/map/BluetoothMapObexServer.java10
-rwxr-xr-xsrc/com/android/bluetooth/map/BluetoothMapService.java26
-rw-r--r--src/com/android/bluetooth/map/BluetoothMapSmsPdu.java2
-rw-r--r--src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java4
-rw-r--r--src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java3
-rwxr-xr-xsrc/com/android/bluetooth/opp/BluetoothOppService.java14
-rwxr-xr-xsrc/com/android/bluetooth/opp/BluetoothOppTransfer.java8
-rwxr-xr-xsrc/com/android/bluetooth/pan/PanService.java35
-rw-r--r--src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java364
-rw-r--r--src/com/android/bluetooth/util/NumberUtils.java46
-rw-r--r--tests/src/com/android/bluetooth/gatt/GattServiceTest.java22
-rw-r--r--tests/src/com/android/bluetooth/util/NumberUtilsTest.java43
65 files changed, 1547 insertions, 1344 deletions
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index 861a235..a4016a4 100755
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -937,7 +937,7 @@ static jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
return result;
}
-static jboolean isConnectedNative(JNIEnv* env, jobject obj, jbyteArray address) {
+static int getConnectionStateNative(JNIEnv* env, jobject obj, jbyteArray address) {
ALOGV("%s:",__FUNCTION__);
if (!sBluetoothInterface) return JNI_FALSE;
@@ -950,7 +950,7 @@ static jboolean isConnectedNative(JNIEnv* env, jobject obj, jbyteArray address)
int ret = sBluetoothInterface->get_connection_state((bt_bdaddr_t *)addr);
env->ReleaseByteArrayElements(address, addr, 0);
- return (ret != 0 ? JNI_TRUE : JNI_FALSE);
+ return ret;
}
static jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
@@ -1268,7 +1268,7 @@ static JNINativeMethod sMethods[] = {
{"createBondNative", "([BI)Z", (void*) createBondNative},
{"removeBondNative", "([B)Z", (void*) removeBondNative},
{"cancelBondNative", "([B)Z", (void*) cancelBondNative},
- {"isConnectedNative", "([B)Z", (void*) isConnectedNative},
+ {"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative},
{"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
{"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
{"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index 921ad83..02a0669 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -191,6 +191,7 @@ static jmethodID method_onAttributeWrite;
static jmethodID method_onExecuteWrite;
static jmethodID method_onNotificationSent;
static jmethodID method_onServerCongestion;
+static jmethodID method_onServerMtuChanged;
/**
* Static variables
@@ -774,6 +775,13 @@ void btgatts_congestion_cb(int conn_id, bool congested)
checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}
+void btgatts_mtu_changed_cb(int conn_id, int mtu)
+{
+ CHECK_CALLBACK_ENV
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged, conn_id, mtu);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+}
+
static const btgatt_server_callbacks_t sGattServerCallbacks = {
btgatts_register_app_cb,
btgatts_connection_cb,
@@ -789,7 +797,8 @@ static const btgatt_server_callbacks_t sGattServerCallbacks = {
btgatts_request_exec_write_cb,
btgatts_response_confirmation_cb,
btgatts_indication_sent_cb,
- btgatts_congestion_cb
+ btgatts_congestion_cb,
+ btgatts_mtu_changed_cb
};
/**
@@ -859,6 +868,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
method_onExecuteWrite= env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
method_onNotificationSent = env->GetMethodID(clazz, "onNotificationSent", "(II)V");
method_onServerCongestion = env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
+ method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
info("classInitNative: Success!");
}
@@ -1715,6 +1725,8 @@ static JNINativeMethod sAdvertiseMethods[] = {
{"gattClientUpdateAdvNative", "(IIIIIII)V", (void *) gattClientUpdateAdvNative},
{"gattClientSetAdvDataNative", "(IZZZI[B[B[B)V", (void *) gattClientSetAdvDataNative},
{"gattClientDisableAdvNative", "(I)V", (void *) gattClientDisableAdvNative},
+ {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
+ {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
};
// JNI functions defined in ScanManager class.
@@ -1758,7 +1770,6 @@ static JNINativeMethod sMethods[] = {
{"gattClientExecuteWriteNative", "(IZ)V", (void *) gattClientExecuteWriteNative},
{"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IIJJIJJZ)V", (void *) gattClientRegisterForNotificationsNative},
{"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V", (void *) gattClientReadRemoteRssiNative},
- {"gattAdvertiseNative", "(IZ)V", (void *) gattAdvertiseNative},
{"gattClientConfigureMTUNative", "(II)V", (void *) gattClientConfigureMTUNative},
{"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIII)V", (void *) gattConnectionParameterUpdateNative},
{"gattServerRegisterAppNative", "(JJ)V", (void *) gattServerRegisterAppNative},
@@ -1776,7 +1787,6 @@ static JNINativeMethod sMethods[] = {
{"gattServerSendNotificationNative", "(III[B)V", (void *) gattServerSendNotificationNative},
{"gattServerSendResponseNative", "(IIIIII[BI)V", (void *) gattServerSendResponseNative},
- {"gattSetAdvDataNative", "(IZZZIII[B[B[B)V", (void *) gattSetAdvDataNative},
{"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void *) gattTestNative},
};
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index ebf586c..a4e2976 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -31,7 +31,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="2752605552743148036">"আগত ফাইল স্বীকার করবেন?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ফাইল প্রাপ্ত হচ্ছে…"</string>
<string name="download_cancel" msgid="9177305996747500768">"থামান"</string>
<string name="download_ok" msgid="5000360731674466039">"লুকান"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"প্রেরক"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ফাইলের নাম"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"আকার"</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>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index e8a60a1..833b7d8 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -20,7 +20,7 @@
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Bluetooth bidezko partekatzeen kudeatzailea atzitzea eta fitxategiak transferitzeko erabiltzea baimentzen die aplikazioei."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Sartu sarbidedunen zerrendan Bluetooth gailua."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Bluetooth gailu bat aldi baterako sarbidedunen zerrendan sartzea baimentzen die aplikazioei, gailu honetara fitxategiak bidaltzeko baimena izan dezan, baina gailu honen erabiltzaileari berrespena eskatu beharrik gabe."</string>
- <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+ <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetootha"</string>
<string name="unknown_device" msgid="9221903979877041009">"Gailu ezezaguna"</string>
<string name="unknownNumber" msgid="4994750948072751566">"Ezezaguna"</string>
<string name="airplane_error_title" msgid="2683839635115739939">"Hegaldi modua"</string>
@@ -31,7 +31,7 @@
<string name="bt_enable_cancel" msgid="1988832367505151727">"Utzi"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Aktibatu"</string>
<string name="incoming_file_confirm_title" msgid="8139874248612182627">"Fitxategi-transferentzia"</string>
- <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Sarrerako fitxategia onartu nahi duzu?"</string>
+ <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" igorleak <xliff:g id="FILE">%2$s</xliff:g> fitxategia bidali nahi dizu (<xliff:g id="SIZE">%3$s</xliff:g>).\n\nFitxategia onartu nahi duzu?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Baztertu"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"Onartu"</string>
<string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Ados"</string>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Fitxategia jasotzen…"</string>
<string name="download_cancel" msgid="9177305996747500768">"Gelditu"</string>
<string name="download_ok" msgid="5000360731674466039">"Ezkutatu"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Igorlea"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Fitxategi-izena"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Tamaina"</string>
<string name="download_fail_line1" msgid="3846450148862894552">"Ez da fitxategia jaso"</string>
<string name="download_fail_line2" msgid="8950394574689971071">"Fitxategia: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_fail_line3" msgid="3451040656154861722">"Arrazoia: <xliff:g id="REASON">%1$s</xliff:g>"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 45aa484..f3b207c 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -31,7 +31,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 ficheiros"</string>
- <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Queres aceptar o ficheiro entrante?"</string>
+ <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" quere enviarche <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Queres aceptar o ficheiro?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rexeitar"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"Aceptar"</string>
<string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Aceptar"</string>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Recibindo ficheiro..."</string>
<string name="download_cancel" msgid="9177305996747500768">"Deter"</string>
<string name="download_ok" msgid="5000360731674466039">"Ocultar"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"De"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Nome do ficheiro"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Tamaño"</string>
<string name="download_fail_line1" msgid="3846450148862894552">"Ficheiro non recibido"</string>
<string name="download_fail_line2" msgid="8950394574689971071">"Ficheiro: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_fail_line3" msgid="3451040656154861722">"Motivo: <xliff:g id="REASON">%1$s</xliff:g>"</string>
diff --git a/res/values-hi/test_strings.xml b/res/values-hi/test_strings.xml
index 80aa680..5c49180 100644
--- a/res/values-hi/test_strings.xml
+++ b/res/values-hi/test_strings.xml
@@ -4,7 +4,7 @@
<string name="hello" msgid="1740533743008967039">"नमस्ते दुनिया, परीक्षण गतिविधि"</string>
<string name="app_name" msgid="1203877025577761792">"ब्लूटूथ शेयर"</string>
<string name="insert_record" msgid="1450997173838378132">"रिकॉर्ड सम्मिलित करें"</string>
- <string name="update_record" msgid="2480425402384910635">"रिकॉर्ड की दुबारा पूछें"</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>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 401edd2..9285fca 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -31,7 +31,7 @@
<string name="bt_enable_cancel" msgid="1988832367505151727">"Hætta við"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Kveikja"</string>
<string name="incoming_file_confirm_title" msgid="8139874248612182627">"Skráaflutningur"</string>
- <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Samþykkja skrá sem berst?"</string>
+ <string name="incoming_file_confirm_content" msgid="6673812334377911289">"„<xliff:g id="SENDER">%1$s</xliff:g>“ vill senda þér <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>). \n\n Samþykkja þessa skrá?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Hafna"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"Samþykkja"</string>
<string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"Í lagi"</string>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Tekur á móti skrá…"</string>
<string name="download_cancel" msgid="9177305996747500768">"Stöðva"</string>
<string name="download_ok" msgid="5000360731674466039">"Fela"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Frá"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Skráarheiti"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Stærð"</string>
<string name="download_fail_line1" msgid="3846450148862894552">"Skrá ekki móttekin"</string>
<string name="download_fail_line2" msgid="8950394574689971071">"Skrá: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_fail_line3" msgid="3451040656154861722">"Ástæða: <xliff:g id="REASON">%1$s</xliff:g>"</string>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index c342f17..cb49914 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -31,7 +31,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="2752605552743148036">"Кіріс файлды қабылдау керек пе?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Файлды қабылдауда…"</string>
<string name="download_cancel" msgid="9177305996747500768">"Тоқтату"</string>
<string name="download_ok" msgid="5000360731674466039">"Жасыру"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Кімнен"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Файл атауы"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Өлшем"</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>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 769567b..e53db4b 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -28,13 +28,13 @@
<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="2752605552743148036">"ទទួល​ឯកសារ​ចូល?"</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">"ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ឯកសារ​ចូល"</string>
<string name="incoming_file_confirm_Notification_caption" msgid="6671081128475981157">"តើ​អ្នក​ចង់​ទទួល​ឯកសារ​នេះ​ឬ​?"</string>
@@ -60,19 +60,19 @@
<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="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>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 381fa7c..4eb0178 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -31,7 +31,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="2752605552743148036">"ಒಳಬರುವ ಫೈಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸುವುದೇ?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲಾಗುತ್ತಿದೆ…"</string>
<string name="download_cancel" msgid="9177305996747500768">"ನಿಲ್ಲಿಸು"</string>
<string name="download_ok" msgid="5000360731674466039">"ಮರೆಮಾಡು"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"ಇವರಿಂದ"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ಫೈಲ್‌ಹೆಸರು"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"ಗಾತ್ರ"</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>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 497db31..6ca5b6d 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -31,7 +31,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="2752605552743148036">"Келүүчү файл кабыл алынсынбы?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Файл алынууда…"</string>
<string name="download_cancel" msgid="9177305996747500768">"Токтотуу"</string>
<string name="download_ok" msgid="5000360731674466039">"Жашыруу"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Кимден"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Файлдын аталышы"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Өлчөмү"</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>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 1c19c91..52c2521 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -31,7 +31,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="2752605552743148036">"Да се прифати дојдовната датотека?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Примање датотеки..."</string>
<string name="download_cancel" msgid="9177305996747500768">"Запри"</string>
<string name="download_ok" msgid="5000360731674466039">"Сокриј"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Од"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Име на датотека"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Големина"</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>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 809e4b3..94166a4 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -18,34 +18,34 @@
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="bt_share_picker_label" msgid="6268100924487046932">"ബ്ലൂടൂത്ത്"</string>
+ <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"വൈറ്റ്‌ലിസ്റ്റ് bluetooth ഉപകരണ ആക്‌സസ്സ്."</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ഒരു 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">"നിങ്ങൾക്ക് വിമാന മോഡിൽ ബ്ലൂടൂത്ത് ഉപയോഗിക്കാനാകില്ല."</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">"ബ്ലൂടൂത്ത് സേവനങ്ങൾ ഉപയോഗിക്കാൻ, നിങ്ങൾ ആദ്യം ബ്ലൂടൂത്ത് ഓൺ ചെയ്യണം."</string>
- <string name="bt_enable_line2" msgid="4341936569415937994">"ഇപ്പോൾ ബ്ലൂടൂത്ത് ഓണാക്കണോ?"</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="2752605552743148036">"ഇൻകമിംഗ് ഫയൽ അംഗീകരിക്കണോ?"</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_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">"ബ്ലൂടൂത്ത് പങ്കിടൽ: <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_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">"ബ്ലൂടൂത്ത് പങ്കിടൽ: <xliff:g id="FILE">%1$s</xliff:g> എന്ന ഫയൽ അയച്ചില്ല"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ഫയൽ നേടുന്നു…"</string>
<string name="download_cancel" msgid="9177305996747500768">"നിര്‍ത്തുക"</string>
<string name="download_ok" msgid="5000360731674466039">"മറയ്‌ക്കുക"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"അയച്ചയാൾ"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ഫയല്‍നാമം"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"വലുപ്പം"</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>
@@ -78,7 +75,7 @@
<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="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>
@@ -101,15 +98,15 @@
<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="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">"ബ്ലൂടൂത്ത് പങ്കിടൽ: അയച്ച ഫയലുകൾ"</string>
- <string name="inbound_noti_title" msgid="4143352641953027595">"ബ്ലൂടൂത്ത് പങ്കിടൽ: ലഭിച്ച ഫയലുകൾ"</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>
@@ -117,9 +114,9 @@
<string name="transfer_clear_dlg_title" msgid="2953444575556460386">"മായ്‌ക്കുക"</string>
<string name="bluetooth_map_email_settings_save" msgid="5349902976213455385">"സംരക്ഷിക്കുക"</string>
<string name="bluetooth_map_email_settings_cancel" msgid="5019472404940038118">"റദ്ദാക്കുക"</string>
- <string name="bluetooth_map_email_settings_intro" msgid="6219461401455143988">"ബ്ലൂടൂത്ത് വഴി പങ്കിടേണ്ട ഇമെയിൽ അക്കൗണ്ടുകൾ തിരഞ്ഞെടുക്കുക. കണക്‌റ്റുചെയ്യുമ്പോൾ അക്കൗണ്ടുകളിലേക്കുള്ള എല്ലാ ആക്‌സസ്സും നിങ്ങൾ തുടർന്നും അംഗീകരിക്കേണ്ടതുണ്ട്."</string>
+ <string name="bluetooth_map_email_settings_intro" msgid="6219461401455143988">"Bluetooth വഴി പങ്കിടേണ്ട ഇമെയിൽ അക്കൗണ്ടുകൾ തിരഞ്ഞെടുക്കുക. കണക്‌റ്റുചെയ്യുമ്പോൾ അക്കൗണ്ടുകളിലേക്കുള്ള എല്ലാ ആക്‌സസ്സും നിങ്ങൾ തുടർന്നും അംഗീകരിക്കേണ്ടതുണ്ട്."</string>
<string name="bluetooth_map_email_settings_count" msgid="8884933619108905375">"ശേഷിക്കുന്ന സ്ലോട്ടുകൾ:"</string>
<string name="bluetooth_map_email_settings_app_icon" msgid="6905622365985483669">"അപ്ലിക്കേഷൻ ഐക്കൺ"</string>
- <string name="bluetooth_map_email_settings_title" msgid="2181388147513118336">"ബ്ലൂടൂത്ത് സന്ദേശം പങ്കിടൽ ക്രമീകരണങ്ങൾ"</string>
+ <string name="bluetooth_map_email_settings_title" msgid="2181388147513118336">"Bluetooth സന്ദേശം പങ്കിടൽ ക്രമീകരണങ്ങൾ"</string>
<string name="bluetooth_map_email_settings_no_account_slots_left" msgid="5989596869950397488">"അക്കൗണ്ട് തിരഞ്ഞെടുക്കാനാകില്ല. 0 സ്ലോട്ടുകൾ ശേഷിക്കുന്നു"</string>
</resources>
diff --git a/res/values-ml-rIN/strings_pbap.xml b/res/values-ml-rIN/strings_pbap.xml
index f6d8a12..3acf7fc 100644
--- a/res/values-ml-rIN/strings_pbap.xml
+++ b/res/values-ml-rIN/strings_pbap.xml
@@ -2,7 +2,7 @@
<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_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>
diff --git a/res/values-ml-rIN/test_strings.xml b/res/values-ml-rIN/test_strings.xml
index fe0a192..493e180 100644
--- a/res/values-ml-rIN/test_strings.xml
+++ b/res/values-ml-rIN/test_strings.xml
@@ -2,7 +2,7 @@
<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="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>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 53bb625..bb8ac59 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -18,34 +18,34 @@
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="bt_share_picker_label" msgid="6268100924487046932">"ब"</string>
+ <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"श्वेतसूची bluetooth डिव्‍हाइस प्रवेश."</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"अ‍ॅपला त्या डिव्‍हाइसला वापरकर्ता पुष्‍टीशिवाय या डिव्‍हासवर फायली पाठविण्‍याची अनुमती देऊन तात्पुरते 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">"आपण विमान मोड मध्ये ब वापरू शकत नाही."</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">"ब सेवांचा वापर करण्‍यासाठी, आपण प्रथम ब चालू करा."</string>
- <string name="bt_enable_line2" msgid="4341936569415937994">"आता ब चालू करायचे?"</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="2752605552743148036">"येणारी फाईल स्‍वीकारायची?"</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_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">"ब शेअर: <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_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">"ब शेअर: <xliff:g id="FILE">%1$s</xliff:g> फाइल पाठविली नाही"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"फाइल प्राप्त करीत आहे..."</string>
<string name="download_cancel" msgid="9177305996747500768">"थांबा"</string>
<string name="download_ok" msgid="5000360731674466039">"लपवा"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"प्रेषक"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"फाईलनाव"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"आकार"</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>
@@ -78,7 +75,7 @@
<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="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>
@@ -101,15 +98,15 @@
<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="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">"ब शेअर: पाठविलेल्‍या फायली"</string>
- <string name="inbound_noti_title" msgid="4143352641953027595">"ब शेअर: प्राप्त केलेल्‍या फायली"</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>
@@ -117,9 +114,9 @@
<string name="transfer_clear_dlg_title" msgid="2953444575556460386">"साफ करा"</string>
<string name="bluetooth_map_email_settings_save" msgid="5349902976213455385">"जतन करा"</string>
<string name="bluetooth_map_email_settings_cancel" msgid="5019472404940038118">"रद्द करा"</string>
- <string name="bluetooth_map_email_settings_intro" msgid="6219461401455143988">"आपण ब द्वारे सामायिक करू इच्छित असलेली ईमेल खाती निवडा. कनेक्‍ट करताना आपल्याला खात्यांवरील कोणतेही प्रवेश अद्याप स्वीकारावे लागतील."</string>
+ <string name="bluetooth_map_email_settings_intro" msgid="6219461401455143988">"आपण Bluetooth द्वारे सामायिक करू इच्छित असलेली ईमेल खाती निवडा. कनेक्‍ट करताना आपल्याला खात्यांवरील कोणतेही प्रवेश अद्याप स्वीकारावे लागतील."</string>
<string name="bluetooth_map_email_settings_count" msgid="8884933619108905375">"स्लॉट शिल्लक:"</string>
<string name="bluetooth_map_email_settings_app_icon" msgid="6905622365985483669">"अनुप्रयोग चिन्ह"</string>
- <string name="bluetooth_map_email_settings_title" msgid="2181388147513118336">"ब संदेश सामायिकरण सेटिंग्ज"</string>
+ <string name="bluetooth_map_email_settings_title" msgid="2181388147513118336">"Bluetooth संदेश सामायिकरण सेटिंग्ज"</string>
<string name="bluetooth_map_email_settings_no_account_slots_left" msgid="5989596869950397488">"खाते निवडू शकले नाही. 0 स्लॉट शिल्लक"</string>
</resources>
diff --git a/res/values-mr-rIN/strings_pbap.xml b/res/values-mr-rIN/strings_pbap.xml
index 57b3f1d..9f7e71e 100644
--- a/res/values-mr-rIN/strings_pbap.xml
+++ b/res/values-mr-rIN/strings_pbap.xml
@@ -2,7 +2,7 @@
<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_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>
diff --git a/res/values-mr-rIN/test_strings.xml b/res/values-mr-rIN/test_strings.xml
index 1650fc4..e380885 100644
--- a/res/values-mr-rIN/test_strings.xml
+++ b/res/values-mr-rIN/test_strings.xml
@@ -2,7 +2,7 @@
<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="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>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index aca9f3f..76101f3 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -23,15 +23,15 @@
<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_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_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="2752605552743148036">"ဝင်လာသည့် ဖိုင်ကို လက်ခံမလား?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ဖိုင် လက်ခံနေပြီ"</string>
<string name="download_cancel" msgid="9177305996747500768">"ရပ်ဆိုင်းရန်"</string>
<string name="download_ok" msgid="5000360731674466039">"ဖျောက်ထားမည်"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"မှ"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ဖိုင်အမည်"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"ဆိုက်"</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>
@@ -102,7 +99,7 @@
<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="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>
@@ -115,8 +112,8 @@
<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>
- <string name="bluetooth_map_email_settings_save" msgid="5349902976213455385">"သိမ်းပါ"</string>
- <string name="bluetooth_map_email_settings_cancel" msgid="5019472404940038118">"ထားတော့"</string>
+ <string name="bluetooth_map_email_settings_save" msgid="5349902976213455385">"သိမ်းဆည်းရန်"</string>
+ <string name="bluetooth_map_email_settings_cancel" msgid="5019472404940038118">"ပယ်ဖျက်ရန်"</string>
<string name="bluetooth_map_email_settings_intro" msgid="6219461401455143988">"သင်က ဘလူးတုသ် မှတစ်ဆင့် မျှဝေလိုသည့် အီးမေးလ် အကောင့်ကို ရွေးပါ။ သင်သည် အကောင့်အား ရယူသုံးလိုမှု မှန်သမျှကို ချိတ်ဆက်လာသည့် အခါမှာ လက်ခံပေးရန် လိုဦးမည်။"</string>
<string name="bluetooth_map_email_settings_count" msgid="8884933619108905375">"ကျန်နေသည့် အပေါက်များ:"</string>
<string name="bluetooth_map_email_settings_app_icon" msgid="6905622365985483669">"အပလီကေးရှင်း အိုင်ကွန်"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index f196602..225afc0 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -31,7 +31,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="2752605552743148036">"आगमन फाइल स्वीकार गर्नुहुन्छ?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"फाइल प्राप्त गर्दै..."</string>
<string name="download_cancel" msgid="9177305996747500768">"रोक्नुहोस्"</string>
<string name="download_ok" msgid="5000360731674466039">"लुकाउनुहोस्"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"प्रेषक"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"फाइलको नाम"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"आकार"</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>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 4d781b6..38b109b 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -31,7 +31,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="2752605552743148036">"ඇතුළට එන ගොනුව පිළිගන්නද?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ගොනුව ලැබේ…"</string>
<string name="download_cancel" msgid="9177305996747500768">"නතර කරන්න"</string>
<string name="download_ok" msgid="5000360731674466039">"සඟවන්න"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"වෙතින්"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ගොනුවේ නම"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"ප්‍රමාණය"</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>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 56e035d..e6afecf 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/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">"Dostop do upravitelja prenosov."</string>
- <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Aplikaciji omogoča dostop do upravitelja BluetoothShare in njegovo uporabo za prenašanje datotek."</string>
+ <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Programu omogoča dostop do upravitelja BluetoothShare in njegovo uporabo za prenašanje datotek."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Doda napravo Bluetooth na seznam z dovoljenim dostopom."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Aplikaciji omogoča, da začasno uvrsti napravo Bluetooth na seznam dovoljenih, kar omogoči napravi pošiljanje datotek v to napravo brez potrditve uporabnika."</string>
<string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
@@ -74,7 +74,7 @@
<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 aplikacije, s katero 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="enabling_progress_title" msgid="436157952334723406">"Počakajte ..."</string>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index 0ce8b1c..9651521 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -31,7 +31,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="2752605552743148036">"உள்வரும் கோப்பை ஏற்கவா?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"கோப்பைப் பெறுகிறது…"</string>
<string name="download_cancel" msgid="9177305996747500768">"நிறுத்து"</string>
<string name="download_ok" msgid="5000360731674466039">"மறை"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"அனுப்புநர்"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"கோப்புப்பெயர்"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"அளவு"</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>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index f83cf0c..459be43 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -31,7 +31,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="2752605552743148036">"ఇన్‌కమింగ్ ఫైల్‌ను ఆమోదించాలా?"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"ఫైల్‌ను స్వీకరిస్తోంది…"</string>
<string name="download_cancel" msgid="9177305996747500768">"ఆపివేయి"</string>
<string name="download_ok" msgid="5000360731674466039">"దాచు"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"దీని నుండి"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"ఫైల్ పేరు"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"పరిమాణం"</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>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 2adbe97..246d91b 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -31,7 +31,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="2752605552743148036">"اِن کمنگ فائل قبول کریں؟"</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>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"فائل موصول ہو رہی ہے…"</string>
<string name="download_cancel" msgid="9177305996747500768">"روکیں"</string>
<string name="download_ok" msgid="5000360731674466039">"چھپائیں"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"منجانب"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"فائل کا نام"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"سائز"</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>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index aafe740..7d5f48e 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -31,7 +31,7 @@
<string name="bt_enable_cancel" msgid="1988832367505151727">"Bekor qilish"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Yoqish"</string>
<string name="incoming_file_confirm_title" msgid="8139874248612182627">"Fayl uzatish"</string>
- <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Yuborilgan faylni qabul qilasizmi?"</string>
+ <string name="incoming_file_confirm_content" msgid="6673812334377911289">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" sizga <xliff:g id="FILE">%2$s</xliff:g> (<xliff:g id="SIZE">%3$s</xliff:g>)ni jo‘natmoqchi. \n\n Fayl qabul qilinsinmi?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rad qilish"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"Roziman"</string>
<string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"OK"</string>
@@ -54,9 +54,6 @@
<string name="download_line5" msgid="3069560415845295386">"Fayl qabul qilinmoqda…"</string>
<string name="download_cancel" msgid="9177305996747500768">"To‘xtatish"</string>
<string name="download_ok" msgid="5000360731674466039">"Yashirish"</string>
- <string name="incoming_line1" msgid="2127419875681087545">"Kimdan"</string>
- <string name="incoming_line2" msgid="3348994249285315873">"Fayl nomi"</string>
- <string name="incoming_line3" msgid="7954237069667474024">"Hajmi"</string>
<string name="download_fail_line1" msgid="3846450148862894552">"Fayl qabul qilinmadi"</string>
<string name="download_fail_line2" msgid="8950394574689971071">"Fayl: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_fail_line3" msgid="3451040656154861722">"Sababi: <xliff:g id="REASON">%1$s</xliff:g>"</string>
diff --git a/res/values-zh-rCN/strings_pbap.xml b/res/values-zh-rCN/strings_pbap.xml
index dda67e4..93c4d90 100644
--- a/res/values-zh-rCN/strings_pbap.xml
+++ b/res/values-zh-rCN/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">"Carkit"</string>
<string name="unknownName" msgid="2841414754740600042">"未知名称"</string>
<string name="localPhoneName" msgid="2349001318925409159">"我的名字"</string>
diff --git a/res/values-zh-rCN/test_strings.xml b/res/values-zh-rCN/test_strings.xml
index fd0a0fc..93d0f70 100644
--- a/res/values-zh-rCN/test_strings.xml
+++ b/res/values-zh-rCN/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/src/com/android/bluetooth/Utils.java b/src/com/android/bluetooth/Utils.java
index 56d5a64..0b2f836 100644
--- a/src/com/android/bluetooth/Utils.java
+++ b/src/com/android/bluetooth/Utils.java
@@ -17,12 +17,17 @@
package com.android.bluetooth;
import android.app.ActivityManager;
+import android.app.ActivityThread;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.ParcelUuid;
+import android.os.Process;
import android.os.UserHandle;
+import android.os.UserManager;
import android.util.Log;
import java.io.IOException;
@@ -193,12 +198,19 @@ final public class Utils {
// Get the caller's user id then clear the calling identity
// which will be restored in the finally clause.
int callingUser = UserHandle.getCallingUserId();
+ int callingUid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
try {
// With calling identity cleared the current user is the foreground user.
int foregroundUser = ActivityManager.getCurrentUser();
ok = (foregroundUser == callingUser);
+ if (!ok) {
+ // Always allow SystemUI/System access.
+ int systemUiUid = ActivityThread.getPackageManager().getPackageUid(
+ "com.android.systemui", UserHandle.USER_OWNER);
+ ok = (systemUiUid == callingUid) || (Process.SYSTEM_UID == callingUid);
+ }
} catch (Exception ex) {
Log.e(TAG, "checkIfCallerIsSelfOrForegroundUser: Exception ex=" + ex);
ok = false;
@@ -208,6 +220,40 @@ final public class Utils {
return ok;
}
+ public static boolean checkCallerAllowManagedProfiles(Context mContext) {
+ if (mContext == null) {
+ return checkCaller();
+ }
+ boolean ok;
+ // Get the caller's user id and if it's a managed profile, get it's parents
+ // id, then clear the calling identity
+ // which will be restored in the finally clause.
+ int callingUser = UserHandle.getCallingUserId();
+ int callingUid = Binder.getCallingUid();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ UserInfo ui = um.getProfileParent(callingUser);
+ int parentUser = (ui != null) ? ui.id : UserHandle.USER_NULL;
+ // With calling identity cleared the current user is the foreground user.
+ int foregroundUser = ActivityManager.getCurrentUser();
+ ok = (foregroundUser == callingUser) ||
+ (foregroundUser == parentUser);
+ if (!ok) {
+ // Always allow SystemUI/System access.
+ int systemUiUid = ActivityThread.getPackageManager().getPackageUid(
+ "com.android.systemui", UserHandle.USER_OWNER);
+ ok = (systemUiUid == callingUid) || (Process.SYSTEM_UID == callingUid);
+ }
+ } catch (Exception ex) {
+ Log.e(TAG, "checkCallerAllowManagedProfiles: Exception ex=" + ex);
+ ok = false;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return ok;
+ }
+
/**
* Enforce the context has android.Manifest.permission.BLUETOOTH_ADMIN permission. A
* {@link SecurityException} would be thrown if neither the calling process or the application
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 808ec98..bae6373 100755
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -297,4 +297,15 @@ public class A2dpService extends ProfileService {
return service.isA2dpPlaying(device);
}
};
+
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ if (mStateMachine != null) {
+ mStateMachine.dump(sb);
+ }
+ if (mAvrcp != null) {
+ mAvrcp.dump(sb);
+ }
+ }
}
diff --git a/src/com/android/bluetooth/a2dp/A2dpSinkService.java b/src/com/android/bluetooth/a2dp/A2dpSinkService.java
index bd27952..5dcec73 100644
--- a/src/com/android/bluetooth/a2dp/A2dpSinkService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpSinkService.java
@@ -210,4 +210,12 @@ public class A2dpSinkService extends ProfileService {
return service.getAudioConfig(device);
}
};
+
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ if (mStateMachine != null) {
+ mStateMachine.dump(sb);
+ }
+ }
}
diff --git a/src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java
index 929676f..d57a0ca 100644
--- a/src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java
+++ b/src/com/android/bluetooth/a2dp/A2dpSinkStateMachine.java
@@ -156,7 +156,14 @@ final class A2dpSinkStateMachine extends StateMachine {
mAudioConfigs.clear();
}
- private class Disconnected extends State {
+ public void dump(StringBuilder sb) {
+ ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
+ ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
+ ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);
+ ProfileService.println(sb, "StateMachine: " + this.toString());
+ }
+
+ private class Disconnected extends State {
@Override
public void enter() {
log("Enter Disconnected: " + getCurrentMessage().what);
diff --git a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index 94cc391..19d4ebd 100755
--- a/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -134,7 +134,6 @@ final class A2dpStateMachine extends StateMachine {
mIntentBroadcastHandler = new IntentBroadcastHandler();
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-
}
static A2dpStateMachine make(A2dpService svc, Context context) {
@@ -753,6 +752,13 @@ final class A2dpStateMachine extends StateMachine {
}
}
+ public void dump(StringBuilder sb) {
+ ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
+ ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
+ ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);
+ ProfileService.println(sb, "mPlayingA2dpDevice: " + mPlayingA2dpDevice);
+ ProfileService.println(sb, "StateMachine: " + this.toString());
+ }
// Event types for STACK_EVENT message
final private static int EVENT_TYPE_NONE = 0;
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java
index 618ff8f..f514b6c 100755
--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -832,6 +832,33 @@ public final class Avrcp {
mHandler.sendMessage(msg);
}
+ public void dump(StringBuilder sb) {
+ sb.append("AVRCP:\n");
+ ProfileService.println(sb, "mMetadata: " + mMetadata);
+ ProfileService.println(sb, "mTransportControlFlags: " + mTransportControlFlags);
+ ProfileService.println(sb, "mCurrentPlayState: " + mCurrentPlayState);
+ ProfileService.println(sb, "mPlayStatusChangedNT: " + mPlayStatusChangedNT);
+ ProfileService.println(sb, "mTrackChangedNT: " + mTrackChangedNT);
+ ProfileService.println(sb, "mTrackNumber: " + mTrackNumber);
+ ProfileService.println(sb, "mCurrentPosMs: " + mCurrentPosMs);
+ ProfileService.println(sb, "mPlayStartTimeMs: " + mPlayStartTimeMs);
+ ProfileService.println(sb, "mSongLengthMs: " + mSongLengthMs);
+ ProfileService.println(sb, "mPlaybackIntervalMs: " + mPlaybackIntervalMs);
+ ProfileService.println(sb, "mPlayPosChangedNT: " + mPlayPosChangedNT);
+ ProfileService.println(sb, "mNextPosMs: " + mNextPosMs);
+ ProfileService.println(sb, "mPrevPosMs: " + mPrevPosMs);
+ ProfileService.println(sb, "mSkipStartTime: " + mSkipStartTime);
+ ProfileService.println(sb, "mFeatures: " + mFeatures);
+ ProfileService.println(sb, "mAbsoluteVolume: " + mAbsoluteVolume);
+ ProfileService.println(sb, "mLastSetVolume: " + mLastSetVolume);
+ ProfileService.println(sb, "mLastDirection: " + mLastDirection);
+ ProfileService.println(sb, "mVolumeStep: " + mVolumeStep);
+ ProfileService.println(sb, "mAudioStreamMax: " + mAudioStreamMax);
+ ProfileService.println(sb, "mVolCmdInProgress: " + mVolCmdInProgress);
+ ProfileService.println(sb, "mAbsVolRetryTimes: " + mAbsVolRetryTimes);
+ ProfileService.println(sb, "mSkipAmount: " + mSkipAmount);
+ }
+
// Do not modify without updating the HAL bt_rc.h files.
// match up with btrc_play_status_t enum of bt_rc.h
diff --git a/src/com/android/bluetooth/avrcp/AvrcpControllerService.java b/src/com/android/bluetooth/avrcp/AvrcpControllerService.java
index b7275d6..0c7e0b6 100644
--- a/src/com/android/bluetooth/avrcp/AvrcpControllerService.java
+++ b/src/com/android/bluetooth/avrcp/AvrcpControllerService.java
@@ -265,6 +265,11 @@ public class AvrcpControllerService extends ProfileService {
return Utils.getBytesFromAddress(device.getAddress());
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ }
+
private native static void classInitNative();
private native void initNative();
private native void cleanupNative();
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index a0404e9..0c3e501 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -52,16 +52,19 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
+import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
+
import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.hid.HidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.hdp.HealthService;
import com.android.bluetooth.pan.PanService;
-import com.android.bluetooth.R;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.RemoteDevices.DeviceProperties;
+import com.android.internal.R;
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
@@ -71,6 +74,7 @@ import java.util.Map;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.List;
+
import android.content.pm.PackageManager;
import android.os.ServiceManager;
@@ -90,6 +94,8 @@ public class AdapterService extends Service {
private int mIdleTimeTotalMs;
private int mEnergyUsedTotalVoltAmpSecMicro;
+ private final ArrayList<ProfileService> mProfiles = new ArrayList<ProfileService>();
+
public static final String ACTION_LOAD_ADAPTER_PROPERTIES =
"com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES";
public static final String ACTION_SERVICE_STATE_CHANGED =
@@ -254,6 +260,18 @@ public class AdapterService extends Service {
}
}
+ public void addProfile(ProfileService profile) {
+ synchronized (mProfiles) {
+ mProfiles.add(profile);
+ }
+ }
+
+ public void removeProfile(ProfileService profile) {
+ synchronized (mProfiles) {
+ mProfiles.remove(profile);
+ }
+ }
+
public void onProfileServiceStateChanged(String serviceName, int state) {
Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED);
m.obj=serviceName;
@@ -492,6 +510,8 @@ public class AdapterService extends Service {
private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20;
private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30;
private static final int MESSAGE_PROFILE_INIT_PRIORITIES=40;
+ private static final int MESSAGE_SET_WAKE_ALARM = 100;
+ private static final int MESSAGE_RELEASE_WAKE_ALARM = 110;
private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000;
private final Handler mHandler = new Handler() {
@@ -525,6 +545,17 @@ public class AdapterService extends Service {
processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1);
}
break;
+ case MESSAGE_SET_WAKE_ALARM: {
+ debugLog( "handleMessage() - MESSAGE_SET_WAKE_ALARM");
+ processSetWakeAlarm((Long) msg.obj, msg.arg1);
+ }
+ break;
+ case MESSAGE_RELEASE_WAKE_ALARM: {
+ debugLog( "handleMessage() - MESSAGE_RELEASE_WAKE_ALARM");
+ mPendingAlarm = null;
+ alarmFiredNative();
+ }
+ break;
}
}
};
@@ -547,7 +578,7 @@ public class AdapterService extends Service {
String serviceName = services[i].getName();
Integer serviceState = mProfileServicesState.get(serviceName);
if(serviceState != null && serviceState != expectedCurrentState) {
- debugLog("setProfileServiceState() - Unable to "
+ debugLog("setProfileServiceState() - Unable to "
+ (state == BluetoothAdapter.STATE_OFF ? "start" : "stop" )
+ " service " + serviceName
+ ". Invalid state: " + serviceState);
@@ -667,7 +698,7 @@ public class AdapterService extends Service {
public String getAddress() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
- (!Utils.checkCaller())) {
+ (!Utils.checkCallerAllowManagedProfiles(mService))) {
Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user");
return null;
}
@@ -712,7 +743,7 @@ public class AdapterService extends Service {
}
public int getScanMode() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getScanMode() - Not allowed for non-active user");
return BluetoothAdapter.SCAN_MODE_NONE;
}
@@ -777,7 +808,7 @@ public class AdapterService extends Service {
return service.cancelDiscovery();
}
public boolean isDiscovering() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "isDiscovering() - Not allowed for non-active user");
return false;
}
@@ -802,7 +833,7 @@ public class AdapterService extends Service {
}
public int getProfileConnectionState(int profile) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user");
return BluetoothProfile.STATE_DISCONNECTED;
}
@@ -852,16 +883,14 @@ public class AdapterService extends Service {
return service.getBondState(device);
}
- public boolean isConnected(BluetoothDevice device) {
+ public int getConnectionState(BluetoothDevice device) {
AdapterService service = getService();
- if (service == null) {
- return false;
- }
- return service.isConnected(device);
+ if (service == null) return 0;
+ return service.getConnectionState(device);
}
public String getRemoteName(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteName() - Not allowed for non-active user");
return null;
}
@@ -872,7 +901,7 @@ public class AdapterService extends Service {
}
public int getRemoteType(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteType() - Not allowed for non-active user");
return BluetoothDevice.DEVICE_TYPE_UNKNOWN;
}
@@ -883,7 +912,7 @@ public class AdapterService extends Service {
}
public String getRemoteAlias(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user");
return null;
}
@@ -905,7 +934,7 @@ public class AdapterService extends Service {
}
public int getRemoteClass(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteClass() - Not allowed for non-active user");
return 0;
}
@@ -916,7 +945,7 @@ public class AdapterService extends Service {
}
public ParcelUuid[] getRemoteUuids(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user");
return new ParcelUuid[0];
}
@@ -927,7 +956,7 @@ public class AdapterService extends Service {
}
public boolean fetchRemoteUuids(BluetoothDevice device) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user");
return false;
}
@@ -1034,7 +1063,7 @@ public class AdapterService extends Service {
public ParcelFileDescriptor connectSocket(BluetoothDevice device, int type,
ParcelUuid uuid, int port, int flag) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "connectSocket() - Not allowed for non-active user");
return null;
}
@@ -1046,7 +1075,7 @@ public class AdapterService extends Service {
public ParcelFileDescriptor createSocketChannel(int type, String serviceName,
ParcelUuid uuid, int port, int flag) {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG, "createSocketChannel() - Not allowed for non-active user");
return null;
}
@@ -1057,9 +1086,9 @@ public class AdapterService extends Service {
}
public boolean configHciSnoopLog(boolean enable) {
- if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
- (!Utils.checkCaller())) {
- Log.w(TAG, "configHciSnoopLog() - Not allowed for non-active user");
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ EventLog.writeEvent(0x534e4554 /* SNET */, "Bluetooth", Binder.getCallingUid(),
+ "configHciSnoopLog() - Not allowed for non-active user b/18643224");
return false;
}
@@ -1083,8 +1112,13 @@ public class AdapterService extends Service {
public boolean isMultiAdvertisementSupported() {
AdapterService service = getService();
if (service == null) return false;
- int val = service.getNumOfAdvertisementInstancesSupported();
- return (val >= MIN_ADVT_INSTANCES_FOR_MA);
+ return service.isMultiAdvertisementSupported();
+ }
+
+ public boolean isPeripheralModeSupported() {
+ AdapterService service = getService();
+ if (service == null) return false;
+ return service.isPeripheralModeSupported();
}
public boolean isOffloadedFilteringSupported() {
@@ -1118,6 +1152,14 @@ public class AdapterService extends Service {
if (service == null) return null;
return service.reportActivityInfo();
}
+
+ public String dump() {
+ AdapterService service = getService();
+ if (service == null) {
+ return "AdapterService is null";
+ }
+ return service.dump();
+ }
};
@@ -1443,10 +1485,10 @@ public class AdapterService extends Service {
return deviceProp.getBondState();
}
- boolean isConnected(BluetoothDevice device) {
+ int getConnectionState(BluetoothDevice device) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
byte[] addr = Utils.getBytesFromAddress(device.getAddress());
- return isConnectedNative(addr);
+ return getConnectionStateNative(addr);
}
String getRemoteName(BluetoothDevice device) {
@@ -1644,6 +1686,11 @@ public class AdapterService extends Service {
return mAdapterProperties.getNumOfAdvertisementInstancesSupported();
}
+ public boolean isMultiAdvertisementSupported() {
+ enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA;
+ }
+
public boolean isRpaOffloadSupported() {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mAdapterProperties.isRpaOffloadSupported();
@@ -1659,6 +1706,10 @@ public class AdapterService extends Service {
return mAdapterProperties.getNumOfOffloadedScanFilterSupported();
}
+ public boolean isPeripheralModeSupported() {
+ return getResources().getBoolean(R.bool.config_bluetooth_le_peripheral_mode_supported);
+ }
+
public int getOffloadedScanResultStorage() {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mAdapterProperties.getOffloadedScanResultStorage();
@@ -1691,6 +1742,16 @@ public class AdapterService extends Service {
return info;
}
+ private String dump() {
+ StringBuilder sb = new StringBuilder();
+ synchronized (mProfiles) {
+ for (ProfileService profile : mProfiles) {
+ profile.dump(sb);
+ }
+ }
+ return sb.toString();
+ }
+
private static int convertScanModeToHal(int mode) {
switch (mode) {
case BluetoothAdapter.SCAN_MODE_NONE:
@@ -1718,24 +1779,30 @@ public class AdapterService extends Service {
}
// This function is called from JNI. It allows native code to set a single wake
- // alarm. If an alarm is already pending and a new request comes in, the alarm
- // will be rescheduled (i.e. the previously set alarm will be cancelled).
+ // alarm.
private boolean setWakeAlarm(long delayMillis, boolean shouldWake) {
- synchronized (this) {
- if (mPendingAlarm != null) {
- mAlarmManager.cancel(mPendingAlarm);
- }
+ Message m = mHandler.obtainMessage(MESSAGE_SET_WAKE_ALARM);
+ m.obj = new Long(delayMillis);
+ // alarm type
+ m.arg1 = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP
+ : AlarmManager.ELAPSED_REALTIME;
+ mHandler.sendMessage(m);
- long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
- int type = shouldWake
- ? AlarmManager.ELAPSED_REALTIME_WAKEUP
- : AlarmManager.ELAPSED_REALTIME;
+ return true;
+ }
- Intent intent = new Intent(ACTION_ALARM_WAKEUP);
- mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
- mAlarmManager.setExact(type, wakeupTime, mPendingAlarm);
- return true;
+ // If an alarm is already pending and a new request comes in, the alarm
+ // will be rescheduled (i.e. the previously set alarm will be cancelled).
+ private void processSetWakeAlarm(long delayMillis, int alarmType) {
+ if (mPendingAlarm != null) {
+ mAlarmManager.cancel(mPendingAlarm);
}
+
+ long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
+
+ Intent intent = new Intent(ACTION_ALARM_WAKEUP);
+ mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+ mAlarmManager.setExact(alarmType, wakeupTime, mPendingAlarm);
}
// This function is called from JNI. It allows native code to acquire a single wake lock.
@@ -1813,10 +1880,7 @@ public class AdapterService extends Service {
private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- synchronized (AdapterService.this) {
- mPendingAlarm = null;
- alarmFiredNative();
- }
+ mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_RELEASE_WAKE_ALARM));
}
};
@@ -1837,7 +1901,7 @@ public class AdapterService extends Service {
/*package*/ native boolean removeBondNative(byte[] address);
/*package*/ native boolean cancelBondNative(byte[] address);
- /*package*/ native boolean isConnectedNative(byte[] address);
+ /*package*/ native int getConnectionStateNative(byte[] address);
private native boolean startDiscoveryNative();
private native boolean cancelDiscoveryNative();
diff --git a/src/com/android/bluetooth/btservice/ProfileService.java b/src/com/android/bluetooth/btservice/ProfileService.java
index 0c1b70e..1b70944 100644
--- a/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/src/com/android/bluetooth/btservice/ProfileService.java
@@ -32,6 +32,8 @@ import android.util.Log;
public abstract class ProfileService extends Service {
private static final boolean DBG = false;
+ private static final String TAG = "BluetoothProfileService";
+
//For Debugging only
private static HashMap<String, Integer> sReferenceCount = new HashMap<String,Integer>();
@@ -53,6 +55,8 @@ public abstract class ProfileService extends Service {
protected boolean mStartError=false;
private boolean mCleaningUp = false;
+ private AdapterService mAdapterService;
+
protected String getName() {
return getClass().getSimpleName();
}
@@ -105,6 +109,12 @@ public abstract class ProfileService extends Service {
super.onCreate();
mAdapter = BluetoothAdapter.getDefaultAdapter();
mBinder = initBinder();
+ mAdapterService = AdapterService.getAdapterService();
+ if (mAdapterService != null) {
+ mAdapterService.addProfile(this);
+ } else {
+ Log.w(TAG, "onCreate, null mAdapterService");
+ }
}
public int onStartCommand(Intent intent, int flags, int startId) {
@@ -149,9 +159,23 @@ public abstract class ProfileService extends Service {
return super.onUnbind(intent);
}
+ // for dumpsys support
+ public void dump(StringBuilder sb) {
+ sb.append("Profile: " + mName + "\n");
+ }
+
+ // with indenting for subclasses
+ public static void println(StringBuilder sb, String s) {
+ sb.append(" ");
+ sb.append(s);
+ sb.append("\n");
+ }
+
@Override
public void onDestroy() {
if (DBG) log("Destroying service.");
+ if (mAdapterService != null) mAdapterService.removeProfile(this);
+
if (mCleaningUp) {
if (DBG) log("Cleanup already started... Skipping cleanup()...");
} else {
@@ -194,17 +218,15 @@ public abstract class ProfileService extends Service {
protected void notifyProfileServiceStateChanged(int state) {
//Notify adapter service
- AdapterService sAdapter = AdapterService.getAdapterService();
- if (sAdapter!= null) {
- sAdapter.onProfileServiceStateChanged(getClass().getName(), state);
+ if (mAdapterService != null) {
+ mAdapterService.onProfileServiceStateChanged(getClass().getName(), state);
}
}
public void notifyProfileConnectionStateChanged(BluetoothDevice device,
int profileId, int newState, int prevState) {
- AdapterService svc = AdapterService.getAdapterService();
- if (svc != null) {
- svc.onProfileConnectionStateChanged(device, profileId, newState, prevState);
+ if (mAdapterService != null) {
+ mAdapterService.onProfileConnectionStateChanged(device, profileId, newState, prevState);
}
}
diff --git a/src/com/android/bluetooth/gatt/AdvertiseManager.java b/src/com/android/bluetooth/gatt/AdvertiseManager.java
index a2c8593..91932bb 100644
--- a/src/com/android/bluetooth/gatt/AdvertiseManager.java
+++ b/src/com/android/bluetooth/gatt/AdvertiseManager.java
@@ -40,7 +40,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
- * Manages Bluetooth LE advertising operations and interacts with bluedroid stack.
+ * Manages Bluetooth LE advertising operations and interacts with bluedroid stack. TODO: add tests.
*
* @hide
*/
@@ -56,6 +56,7 @@ class AdvertiseManager {
private static final int MSG_STOP_ADVERTISING = 1;
private final GattService mService;
+ private final AdapterService mAdapterService;
private final Set<AdvertiseClient> mAdvertiseClients;
private final AdvertiseNative mAdvertiseNative;
@@ -68,9 +69,10 @@ class AdvertiseManager {
/**
* Constructor of {@link AdvertiseManager}.
*/
- AdvertiseManager(GattService service) {
- mService = service;
+ AdvertiseManager(GattService service, AdapterService adapterService) {
logd("advertise manager created");
+ mService = service;
+ mAdapterService = adapterService;
mAdvertiseClients = new HashSet<AdvertiseClient>();
mAdvertiseNative = new AdvertiseNative();
}
@@ -218,13 +220,17 @@ class AdvertiseManager {
}
// Returns maximum advertise instances supported by controller.
- private int maxAdvertiseInstances() {
- AdapterService adapter = AdapterService.getAdapterService();
- int numOfAdvtInstances = adapter.getNumOfAdvertisementInstancesSupported();
+ int maxAdvertiseInstances() {
// Note numOfAdvtInstances includes the standard advertising instance.
// TODO: remove - 1 once the stack is able to include standard instance for multiple
// advertising.
- return numOfAdvtInstances - 1;
+ if (mAdapterService.isMultiAdvertisementSupported()) {
+ return mAdapterService.getNumOfAdvertisementInstancesSupported() - 1;
+ }
+ if (mAdapterService.isPeripheralModeSupported()) {
+ return 1;
+ }
+ return 0;
}
}
@@ -258,21 +264,33 @@ class AdvertiseManager {
private static final int ADVERTISING_EVENT_TYPE_SCANNABLE = 2;
private static final int ADVERTISING_EVENT_TYPE_NON_CONNECTABLE = 3;
+ // TODO: Extract advertising logic into interface as we have multiple implementations now.
boolean startAdverising(AdvertiseClient client) {
- int clientIf = client.clientIf;
+ if (!mAdapterService.isMultiAdvertisementSupported() &&
+ !mAdapterService.isPeripheralModeSupported()) {
+ return false;
+ }
+ if (mAdapterService.isMultiAdvertisementSupported()) {
+ return startMultiAdvertising(client);
+ }
+ return startSingleAdvertising(client);
+ }
+
+ boolean startMultiAdvertising(AdvertiseClient client) {
+ logd("starting multi advertising");
resetCountDownLatch();
- mAdvertiseNative.enableAdvertising(client);
+ enableAdvertising(client);
if (!waitForCallback()) {
return false;
}
resetCountDownLatch();
- mAdvertiseNative.setAdvertisingData(clientIf, client.advertiseData, false);
+ setAdvertisingData(client, client.advertiseData, false);
if (!waitForCallback()) {
return false;
}
if (client.scanResponse != null) {
resetCountDownLatch();
- mAdvertiseNative.setAdvertisingData(clientIf, client.scanResponse, true);
+ setAdvertisingData(client, client.scanResponse, true);
if (!waitForCallback()) {
return false;
}
@@ -280,8 +298,29 @@ class AdvertiseManager {
return true;
}
+ boolean startSingleAdvertising(AdvertiseClient client) {
+ logd("starting single advertising");
+ resetCountDownLatch();
+ enableAdvertising(client);
+ if (!waitForCallback()) {
+ return false;
+ }
+ setAdvertisingData(client, client.advertiseData, false);
+ return true;
+ }
+
void stopAdvertising(AdvertiseClient client) {
- gattClientDisableAdvNative(client.clientIf);
+ if (mAdapterService.isMultiAdvertisementSupported()) {
+ gattClientDisableAdvNative(client.clientIf);
+ } else {
+ gattAdvertiseNative(client.clientIf, false);
+ try {
+ mService.onAdvertiseInstanceDisabled(
+ AdvertiseCallback.ADVERTISE_SUCCESS, client.clientIf);
+ } catch (RemoteException e) {
+ Log.d(TAG, "failed onAdvertiseInstanceDisabled", e);
+ }
+ }
}
private void resetCountDownLatch() {
@@ -305,16 +344,21 @@ class AdvertiseManager {
int txPowerLevel = getTxPowerLevel(client.settings);
int advertiseTimeoutSeconds = (int) TimeUnit.MILLISECONDS.toSeconds(
client.settings.getTimeout());
- gattClientEnableAdvNative(
- clientIf,
- minAdvertiseUnit, maxAdvertiseUnit,
- advertiseEventType,
- ADVERTISING_CHANNEL_ALL,
- txPowerLevel,
- advertiseTimeoutSeconds);
+ if (mAdapterService.isMultiAdvertisementSupported()) {
+ gattClientEnableAdvNative(
+ clientIf,
+ minAdvertiseUnit, maxAdvertiseUnit,
+ advertiseEventType,
+ ADVERTISING_CHANNEL_ALL,
+ txPowerLevel,
+ advertiseTimeoutSeconds);
+ } else {
+ gattAdvertiseNative(client.clientIf, true);
+ }
}
- private void setAdvertisingData(int clientIf, AdvertiseData data, boolean isScanResponse) {
+ private void setAdvertisingData(AdvertiseClient client, AdvertiseData data,
+ boolean isScanResponse) {
if (data == null) {
return;
}
@@ -340,9 +384,15 @@ class AdvertiseManager {
}
serviceUuids = advertisingUuidBytes.array();
}
- gattClientSetAdvDataNative(clientIf, isScanResponse, includeName, includeTxPower,
- appearance,
- manufacturerData, serviceData, serviceUuids);
+ if (mAdapterService.isMultiAdvertisementSupported()) {
+ gattClientSetAdvDataNative(client.clientIf, isScanResponse, includeName,
+ includeTxPower, appearance,
+ manufacturerData, serviceData, serviceUuids);
+ } else {
+ gattSetAdvDataNative(client.clientIf, isScanResponse, includeName,
+ includeTxPower, 0, 0, appearance,
+ manufacturerData, serviceData, serviceUuids);
+ }
}
// Combine manufacturer id and manufacturer data.
@@ -441,6 +491,12 @@ class AdvertiseManager {
private native void gattClientSetAdvDataNative(int client_if,
boolean set_scan_rsp, boolean incl_name, boolean incl_txpower, int appearance,
byte[] manufacturer_data, byte[] service_data, byte[] service_uuid);
+
+ private native void gattSetAdvDataNative(int serverIf, boolean setScanRsp, boolean inclName,
+ boolean inclTxPower, int minSlaveConnectionInterval, int maxSlaveConnectionInterval,
+ int appearance, byte[] manufacturerData, byte[] serviceData, byte[] serviceUuid);
+
+ private native void gattAdvertiseNative(int client_if, boolean start);
}
private void logd(String s) {
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index 65f8dce..1b40bc0 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -134,6 +134,23 @@ import java.util.UUID;
}
/**
+ * Remove the context for a given UUID
+ */
+ void remove(UUID uuid) {
+ synchronized (mApps) {
+ Iterator<App> i = mApps.iterator();
+ while(i.hasNext()) {
+ App entry = i.next();
+ if (entry.uuid.equals(uuid)) {
+ entry.unlinkToDeath();
+ i.remove();
+ break;
+ }
+ }
+ }
+ }
+
+ /**
* Remove the context for a given application ID.
*/
void remove(int id) {
@@ -291,28 +308,23 @@ import java.util.UUID;
/**
* Logs debug information.
*/
- void dump() {
- StringBuilder b = new StringBuilder();
- b.append( "-------------- GATT Context Map ----------------");
- b.append("\nEntries: " + mApps.size());
+ void dump(StringBuilder sb) {
+ sb.append(" Entries: " + mApps.size() + "\n");
Iterator<App> i = mApps.iterator();
while(i.hasNext()) {
App entry = i.next();
List<Connection> connections = getConnectionByApp(entry.id);
- b.append("\n\nApplication Id: " + entry.id);
- b.append("\nUUID: " + entry.uuid);
- b.append("\nConnections: " + connections.size());
+ sb.append("\n Application Id: " + entry.id + "\n");
+ sb.append(" UUID: " + entry.uuid + "\n");
+ sb.append(" Connections: " + connections.size() + "\n");
Iterator<Connection> ii = connections.iterator();
while(ii.hasNext()) {
Connection connection = ii.next();
- b.append("\n " + connection.connId + ": " + connection.address);
+ sb.append(" " + connection.connId + ": " + connection.address + "\n");
}
}
-
- b.append("\n------------------------------------------------");
- Log.d(TAG, b.toString());
}
}
diff --git a/src/com/android/bluetooth/gatt/GattDebugUtils.java b/src/com/android/bluetooth/gatt/GattDebugUtils.java
index 5c42db6..a1b37a2 100644
--- a/src/com/android/bluetooth/gatt/GattDebugUtils.java
+++ b/src/com/android/bluetooth/gatt/GattDebugUtils.java
@@ -28,13 +28,6 @@ import java.util.UUID;
private static final String TAG = GattServiceConfig.TAG_PREFIX + "DebugUtils";
private static final boolean DEBUG_ADMIN = GattServiceConfig.DEBUG_ADMIN;
- private static final String ACTION_DEBUG_DUMP_CLIENTMAP =
- "android.bluetooth.action.DEBUG_DUMP_CLIENTMAP";
- private static final String ACTION_DEBUG_DUMP_SERVERMAP =
- "android.bluetooth.action.DEBUG_DUMP_SERVERMAP";
- private static final String ACTION_DEBUG_DUMP_HANDLEMAP =
- "android.bluetooth.action.DEBUG_DUMP_HANDLEMAP";
-
private static final String ACTION_GATT_PAIRING_CONFIG =
"android.bluetooth.action.GATT_PAIRING_CONFIG";
@@ -82,23 +75,10 @@ import java.util.UUID;
Log.d(TAG, "handleDebugAction() action=" + action);
/*
- * Debug log functinos
- */
-
- if (ACTION_DEBUG_DUMP_CLIENTMAP.equals(action)) {
- svc.mClientMap.dump();
-
- } else if (ACTION_DEBUG_DUMP_SERVERMAP.equals(action)) {
- svc.mServerMap.dump();
-
- } else if (ACTION_DEBUG_DUMP_HANDLEMAP.equals(action)) {
- svc.mHandleMap.dump();
-
- /*
* PTS test commands
*/
- } else if (ACTION_GATT_TEST_USAGE.equals(action)) {
+ if (ACTION_GATT_TEST_USAGE.equals(action)) {
logUsageInfo();
} else if (ACTION_GATT_TEST_ENABLE.equals(action)) {
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 982fd16..c428cf8 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -40,7 +40,10 @@ import android.os.SystemClock;
import android.util.Log;
import com.android.bluetooth.Utils;
+import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
+import com.android.bluetooth.util.NumberUtils;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Arrays;
@@ -75,6 +78,13 @@ public class GattService extends ProfileService {
private static final int ADVT_STATE_ONFOUND = 0;
private static final int ADVT_STATE_ONLOST = 1;
+ private static final UUID[] HID_UUIDS = {
+ UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
+ UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
+ UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"),
+ UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB")
+ };
+
/**
* Search queue to serialize remote onbject inspection.
*/
@@ -160,7 +170,7 @@ public class GattService extends ProfileService {
protected boolean start() {
if (DBG) Log.d(TAG, "start()");
initializeNative();
- mAdvertiseManager = new AdvertiseManager(this);
+ mAdvertiseManager = new AdvertiseManager(this, AdapterService.getAdapterService());
mAdvertiseManager.start();
mScanManager = new ScanManager(this);
@@ -546,7 +556,6 @@ public class GattService extends ProfileService {
void onScanResult(String address, int rssi, byte[] adv_data) {
if (VDBG) Log.d(TAG, "onScanResult() - address=" + address
+ ", rssi=" + rssi);
- ScanRecord record = ScanRecord.parseFromBytes(adv_data);
List<UUID> remoteUuids = parseUuids(adv_data);
for (ScanClient client : mScanManager.getRegularScanQueue()) {
if (client.uuids.length > 0) {
@@ -615,9 +624,7 @@ public class GattService extends ProfileService {
if (client.filters == null || client.filters.isEmpty()) {
return true;
}
- if (DBG) Log.d(TAG, "result: " + scanResult.toString());
for (ScanFilter filter : client.filters) {
- if (DBG) Log.d(TAG, "filter: " + filter.toString());
if (filter.matches(scanResult)) {
return true;
}
@@ -631,8 +638,12 @@ public class GattService extends ProfileService {
if (DBG) Log.d(TAG, "onClientRegistered() - UUID=" + uuid + ", clientIf=" + clientIf);
ClientMap.App app = mClientMap.getByUuid(uuid);
if (app != null) {
- app.id = clientIf;
- app.linkToDeath(new ClientDeathRecipient(clientIf));
+ if (status == 0) {
+ app.id = clientIf;
+ app.linkToDeath(new ClientDeathRecipient(clientIf));
+ } else {
+ mClientMap.remove(uuid);
+ }
app.callback.onClientRegistered(status, clientIf);
}
}
@@ -807,6 +818,12 @@ public class GattService extends ProfileService {
if (VDBG) Log.d(TAG, "onNotify() - address=" + address
+ ", charUuid=" + charUuid + ", length=" + data.length);
+
+ if (isHidUuid(charUuid) &&
+ (0 != checkCallingOrSelfPermission(BLUETOOTH_PRIVILEGED))) {
+ return;
+ }
+
ClientMap.App app = mClientMap.getByConnId(connId);
if (app != null) {
app.callback.onNotify(address, srvcType,
@@ -1031,33 +1048,33 @@ public class GattService extends ProfileService {
private Set<ScanResult> parseTruncatedResults(int numRecords, byte[] batchRecord) {
if (DBG) Log.d(TAG, "batch record " + Arrays.toString(batchRecord));
Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
+ long now = SystemClock.elapsedRealtimeNanos();
for (int i = 0; i < numRecords; ++i) {
byte[] record = extractBytes(batchRecord, i * TRUNCATED_RESULT_SIZE,
TRUNCATED_RESULT_SIZE);
byte[] address = extractBytes(record, 0, 6);
- // TODO: remove temp hack.
reverse(address);
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int rssi = record[8];
- // Timestamp is in every 50 ms.
- long timestampNanos = parseTimestampNanos(extractBytes(record, 9, 2));
+ long timestampNanos = now - parseTimestampNanos(extractBytes(record, 9, 2));
results.add(new ScanResult(device, ScanRecord.parseFromBytes(new byte[0]),
rssi, timestampNanos));
}
return results;
}
- private long parseTimestampNanos(byte[] data) {
- long timestampUnit = data[1] & 0xFF << 8 + data[0];
- long timestampNanos = SystemClock.elapsedRealtimeNanos() -
- TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
- return timestampNanos;
+ @VisibleForTesting
+ long parseTimestampNanos(byte[] data) {
+ long timestampUnit = NumberUtils.littleEndianByteArrayToInt(data);
+ // Timestamp is in every 50 ms.
+ return TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
}
private Set<ScanResult> parseFullResults(int numRecords, byte[] batchRecord) {
Log.d(TAG, "Batch record : " + Arrays.toString(batchRecord));
Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
int position = 0;
+ long now = SystemClock.elapsedRealtimeNanos();
while (position < batchRecord.length) {
byte[] address = extractBytes(batchRecord, position, 6);
// TODO: remove temp hack.
@@ -1069,7 +1086,7 @@ public class GattService extends ProfileService {
// Skip tx power level.
position++;
int rssi = batchRecord[position++];
- long timestampNanos = parseTimestampNanos(extractBytes(batchRecord, position, 2));
+ long timestampNanos = now - parseTimestampNanos(extractBytes(batchRecord, position, 2));
position += 2;
// Combine advertise packet and scan response packet.
@@ -1175,6 +1192,7 @@ public class GattService extends ProfileService {
// Callback for standard advertising instance.
void onAdvertiseCallback(int status, int clientIf) {
if (DBG) Log.d(TAG, "onAdvertiseCallback,- clientIf=" + clientIf + ", status=" + status);
+ mAdvertiseManager.callbackDone(clientIf, status);
}
// Followings are callbacks for Bluetooth LE Advertise operations.
@@ -1404,6 +1422,7 @@ public class GattService extends ProfileService {
int srvcInstanceId, UUID srvcUuid,
int charInstanceId, UUID charUuid, int authReq) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (isHidUuid(charUuid)) enforcePrivilegedPermission();
if (VDBG) Log.d(TAG, "readCharacteristic() - address=" + address);
@@ -1423,6 +1442,7 @@ public class GattService extends ProfileService {
int charInstanceId, UUID charUuid, int writeType,
int authReq, byte[] value) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (isHidUuid(charUuid)) enforcePrivilegedPermission();
if (VDBG) Log.d(TAG, "writeCharacteristic() - address=" + address);
@@ -1445,6 +1465,7 @@ public class GattService extends ProfileService {
int descrInstanceId, UUID descrUuid,
int authReq) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (isHidUuid(charUuid)) enforcePrivilegedPermission();
if (VDBG) Log.d(TAG, "readDescriptor() - address=" + address);
@@ -1468,6 +1489,7 @@ public class GattService extends ProfileService {
int descrInstanceId, UUID descrUuid,
int writeType, int authReq, byte[] value) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (isHidUuid(charUuid)) enforcePrivilegedPermission();
if (VDBG) Log.d(TAG, "writeDescriptor() - address=" + address);
@@ -1508,6 +1530,7 @@ public class GattService extends ProfileService {
int charInstanceId, UUID charUuid,
boolean enable) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (isHidUuid(charUuid)) enforcePrivilegedPermission();
if (DBG) Log.d(TAG, "registerForNotification() - address=" + address + " enable: " + enable);
@@ -1688,9 +1711,6 @@ public class GattService extends ProfileService {
HandleMap.Entry entry = mHandleMap.getByHandle(attrHandle);
if (entry == null) return;
- if (DBG) Log.d(TAG, "onAttributeRead() UUID=" + entry.uuid
- + ", serverIf=" + entry.serverIf + ", type=" + entry.type);
-
mHandleMap.addRequest(transId, attrHandle);
ServerMap.App app = mServerMap.getById(entry.serverIf);
@@ -1738,9 +1758,6 @@ public class GattService extends ProfileService {
HandleMap.Entry entry = mHandleMap.getByHandle(attrHandle);
if (entry == null) return;
- if (DBG) Log.d(TAG, "onAttributeWrite() UUID=" + entry.uuid
- + ", serverIf=" + entry.serverIf + ", type=" + entry.type);
-
mHandleMap.addRequest(transId, attrHandle);
ServerMap.App app = mServerMap.getById(entry.serverIf);
@@ -1793,7 +1810,7 @@ public class GattService extends ProfileService {
}
void onNotificationSent(int connId, int status) throws RemoteException {
- if (DBG) Log.d(TAG, "onNotificationSent() connId=" + connId + ", status=" + status);
+ if (VDBG) Log.d(TAG, "onNotificationSent() connId=" + connId + ", status=" + status);
String address = mServerMap.addressByConnId(connId);
if (address == null) return;
@@ -1825,6 +1842,18 @@ public class GattService extends ProfileService {
}
}
+ void onMtuChanged(int connId, int mtu) throws RemoteException {
+ if (DBG) Log.d(TAG, "onMtuChanged() - connId=" + connId + ", mtu=" + mtu);
+
+ String address = mServerMap.addressByConnId(connId);
+ if (address == null) return;
+
+ ServerMap.App app = mServerMap.getByConnId(connId);
+ if (app == null) return;
+
+ app.callback.onMtuChanged(address, mtu);
+ }
+
/**************************************************************************
* GATT Service functions - SERVER
*************************************************************************/
@@ -1975,6 +2004,13 @@ public class GattService extends ProfileService {
* Private functions
*************************************************************************/
+ private boolean isHidUuid(final UUID uuid) {
+ for (UUID hid_uuid : HID_UUIDS) {
+ if (hid_uuid.equals(uuid)) return true;
+ }
+ return false;
+ }
+
private int getDeviceType(BluetoothDevice device) {
int type = gattClientGetDeviceTypeNative(device.getAddress());
if (DBG) Log.d(TAG, "getDeviceType() - device=" + device
@@ -2181,6 +2217,33 @@ public class GattService extends ProfileService {
return uuids;
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ println(sb, "mAdvertisingServiceUuids:");
+ for (UUID uuid : mAdvertisingServiceUuids) {
+ println(sb, " " + uuid);
+ }
+ println(sb, "mOnFoundResults:");
+ for (ScanResult result : mOnFoundResults.values()) {
+ println(sb, " " + result);
+ }
+ println(sb, "mOnFoundResults:");
+ for (ServiceDeclaration declaration : mServiceDeclarations) {
+ println(sb, " " + declaration);
+ }
+ println(sb, "mMaxScanFilters: " + mMaxScanFilters);
+
+ sb.append("\nGATT Client Map\n");
+ mClientMap.dump(sb);
+
+ sb.append("\nGATT Server Map\n");
+ mServerMap.dump(sb);
+
+ sb.append("\nGATT Handle Map\n");
+ mHandleMap.dump(sb);
+ }
+
/**************************************************************************
* GATT Test functions
*************************************************************************/
@@ -2274,17 +2337,11 @@ public class GattService extends ProfileService {
private native void gattClientReadRemoteRssiNative(int clientIf,
String address);
- private native void gattAdvertiseNative(int client_if, boolean start);
-
private native void gattClientConfigureMTUNative(int conn_id, int mtu);
private native void gattConnectionParameterUpdateNative(int client_if, String address,
int minInterval, int maxInterval, int latency, int timeout);
- private native void gattSetAdvDataNative(int serverIf, boolean setScanRsp, boolean inclName,
- boolean inclTxPower, int minInterval, int maxInterval,
- int appearance, byte[] manufacturerData, byte[] serviceData, byte[] serviceUuid);
-
private native void gattServerRegisterAppNative(long app_uuid_lsb,
long app_uuid_msb);
diff --git a/src/com/android/bluetooth/gatt/HandleMap.java b/src/com/android/bluetooth/gatt/HandleMap.java
index 187625a..4a20639 100644
--- a/src/com/android/bluetooth/gatt/HandleMap.java
+++ b/src/com/android/bluetooth/gatt/HandleMap.java
@@ -196,31 +196,28 @@ class HandleMap {
/**
* Logs debug information.
*/
- void dump() {
- StringBuilder b = new StringBuilder();
- b.append( "-------------- GATT Handle Map -----------------");
- b.append("\nEntries: " + mEntries.size());
- b.append("\nRequests: " + mRequestMap.size());
+ void dump(StringBuilder sb) {
+ sb.append(" Entries: " + mEntries.size() + "\n");
+ sb.append(" Requests: " + mRequestMap.size() + "\n");
for (Entry entry : mEntries) {
- b.append("\n" + entry.serverIf + ": [" + entry.handle + "] ");
+ sb.append(" " + entry.serverIf + ": [" + entry.handle + "] ");
switch(entry.type) {
case TYPE_SERVICE:
- b.append("Service " + entry.uuid);
- b.append(", started " + entry.started);
+ sb.append("Service " + entry.uuid);
+ sb.append(", started " + entry.started);
break;
case TYPE_CHARACTERISTIC:
- b.append(" Characteristic " + entry.uuid);
+ sb.append(" Characteristic " + entry.uuid);
break;
case TYPE_DESCRIPTOR:
- b.append(" Descriptor " + entry.uuid);
+ sb.append(" Descriptor " + entry.uuid);
break;
}
- }
- b.append("\n------------------------------------------------");
- Log.d(TAG, b.toString());
+ sb.append("\n");
+ }
}
}
diff --git a/src/com/android/bluetooth/gatt/ScanManager.java b/src/com/android/bluetooth/gatt/ScanManager.java
index 27e492f..af5eeb0 100644
--- a/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/src/com/android/bluetooth/gatt/ScanManager.java
@@ -441,7 +441,8 @@ public class ScanManager {
}
void startRegularScan(ScanClient client) {
- if (mFilterIndexStack.isEmpty() && isFilteringSupported()) {
+ if (isFilteringSupported() && mFilterIndexStack.isEmpty() &&
+ mClientFilterIndexMap.isEmpty()) {
initFilterIndexStack();
}
if (isFilteringSupported()) {
@@ -748,7 +749,7 @@ public class ScanManager {
if (client.filters == null || client.filters.isEmpty()) {
return true;
}
- return client.filters.size() < mClientFilterIndexMap.size();
+ return client.filters.size() > mFilterIndexStack.size();
}
private void addFilterToController(int clientIf, ScanFilterQueue.Entry entry,
diff --git a/src/com/android/bluetooth/hdp/HealthService.java b/src/com/android/bluetooth/hdp/HealthService.java
index 21846c6..8d8eff7 100644
--- a/src/com/android/bluetooth/hdp/HealthService.java
+++ b/src/com/android/bluetooth/hdp/HealthService.java
@@ -788,6 +788,23 @@ public class HealthService extends ProfileService {
return healthDevices;
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ println(sb, "mHealthChannels:");
+ for (HealthChannel channel : mHealthChannels) {
+ println(sb, " " + channel);
+ }
+ println(sb, "mApps:");
+ for (BluetoothHealthAppConfiguration conf : mApps.keySet()) {
+ println(sb, " " + conf + " : " + mApps.get(conf));
+ }
+ println(sb, "mHealthDevices:");
+ for (BluetoothDevice device : mHealthDevices.keySet()) {
+ println(sb, " " + device + " : " + mHealthDevices.get(device));
+ }
+ }
+
private static class AppInfo {
private IBluetoothHealthCallback mCallback;
private BluetoothHealthDeathRecipient mRcpObj;
diff --git a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
index 2f8821a..ee81e62 100755..100644
--- a/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
+++ b/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
@@ -21,6 +21,8 @@ import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.util.Log;
import android.bluetooth.BluetoothDevice;
@@ -63,30 +65,78 @@ class HeadsetPhoneState {
private boolean mListening = false;
+ // when HFP Service Level Connection is established
+ private boolean mSlcReady = false;
+
+ private Context mContext = null;
+
+ private PhoneStateListener mPhoneStateListener = null;
+
+ private SubscriptionManager mSubMgr;
+
+ private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
+ new OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ listenForPhoneState(false);
+ listenForPhoneState(true);
+ }
+ };
+
+
HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) {
mStateMachine = stateMachine;
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ mContext = context;
+
+ // Register for SubscriptionInfo list changes which is guaranteed
+ // to invoke onSubscriptionInfoChanged and which in turns calls
+ // loadInBackgroud.
+ mSubMgr = SubscriptionManager.from(mContext);
+ mSubMgr.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
}
public void cleanup() {
listenForPhoneState(false);
+ mSubMgr.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
+
mTelephonyManager = null;
mStateMachine = null;
}
void listenForPhoneState(boolean start) {
+
+ mSlcReady = start;
+
if (start) {
- if (!mListening) {
+ startListenForPhoneState();
+ } else {
+ stopListenForPhoneState();
+ }
+
+ }
+
+ private void startListenForPhoneState() {
+ if (!mListening && mSlcReady) {
+
+ int subId = SubscriptionManager.getDefaultSubId();
+
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
+ mPhoneStateListener = getPhoneStateListener(subId);
+
mTelephonyManager.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE |
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
mListening = true;
}
- } else {
- if (mListening) {
- mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
- mListening = false;
- }
+ }
+ }
+
+ private void stopListenForPhoneState() {
+ if (mListening) {
+
+ mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+ mListening = false;
}
}
@@ -177,107 +227,123 @@ class HeadsetPhoneState {
}
}
- private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onServiceStateChanged(ServiceState serviceState) {
- mServiceState = serviceState;
- 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();
- }
+ private PhoneStateListener getPhoneStateListener(int subId) {
+ PhoneStateListener mPhoneStateListener = new PhoneStateListener(subId) {
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+
+ mServiceState = serviceState;
+ 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);
- @Override
- public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- int prevSignal = mSignal;
- if (mService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE)
- mSignal = 0;
- else if (signalStrength.isGsm()) {
- mSignal = gsmAsuToSignal(signalStrength);
- } else {
- mSignal = cdmaDbmEcioToSignal(signalStrength);
- }
- // network signal strength is scaled to BT 1-5 levels.
- // This results in a lot of duplicate messages, hence this check
- if (prevSignal != mSignal)
sendDeviceStateChanged();
- }
+ }
- /* convert [0,31] ASU signal strength to the [0,5] expected by
- * bluetooth devices. Scale is similar to status bar policy
- */
- private int gsmAsuToSignal(SignalStrength signalStrength) {
- int asu = signalStrength.getGsmSignalStrength();
- if (asu >= 16) return 5;
- else if (asu >= 8) return 4;
- else if (asu >= 4) return 3;
- else if (asu >= 2) return 2;
- else if (asu >= 1) return 1;
- else return 0;
- }
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+
+ int prevSignal = mSignal;
+ if (mService == HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
+ mSignal = 0;
+ } else if (signalStrength.isGsm()) {
+ mSignal = signalStrength.getLteLevel();
+ if (mSignal == SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ mSignal = gsmAsuToSignal(signalStrength);
+ } else {
+ // SignalStrength#getLteLevel returns the scale from 0-4
+ // Bluetooth signal scales at 0-5
+ // Let's match up the larger side
+ mSignal++;
+ }
+ } else {
+ mSignal = cdmaDbmEcioToSignal(signalStrength);
+ }
+
+ // network signal strength is scaled to BT 1-5 levels.
+ // This results in a lot of duplicate messages, hence this check
+ if (prevSignal != mSignal) {
+ sendDeviceStateChanged();
+ }
+ }
- /**
- * Convert the cdma / evdo db levels to appropriate icon level.
- * The scale is similar to the one used in status bar policy.
- *
- * @param signalStrength
- * @return the icon level
- */
- private int cdmaDbmEcioToSignal(SignalStrength signalStrength) {
- int levelDbm = 0;
- int levelEcio = 0;
- int cdmaIconLevel = 0;
- int evdoIconLevel = 0;
- int cdmaDbm = signalStrength.getCdmaDbm();
- int cdmaEcio = signalStrength.getCdmaEcio();
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- cdmaIconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;
-
- // STOPSHIP: Change back to getRilVoiceRadioTechnology
- if (mServiceState != null &&
- (mServiceState.getRadioTechnology() ==
- ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
- mServiceState.getRadioTechnology() ==
- ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)) {
- int evdoEcio = signalStrength.getEvdoEcio();
- int evdoSnr = signalStrength.getEvdoSnr();
- int levelEvdoEcio = 0;
- int levelEvdoSnr = 0;
-
- // Ec/Io are in dB*10
- if (evdoEcio >= -650) levelEvdoEcio = 4;
- else if (evdoEcio >= -750) levelEvdoEcio = 3;
- else if (evdoEcio >= -900) levelEvdoEcio = 2;
- else if (evdoEcio >= -1050) levelEvdoEcio = 1;
- else levelEvdoEcio = 0;
-
- if (evdoSnr > 7) levelEvdoSnr = 4;
- else if (evdoSnr > 5) levelEvdoSnr = 3;
- else if (evdoSnr > 3) levelEvdoSnr = 2;
- else if (evdoSnr > 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- evdoIconLevel = (levelEvdoEcio < levelEvdoSnr) ? levelEvdoEcio : levelEvdoSnr;
+ /* convert [0,31] ASU signal strength to the [0,5] expected by
+ * bluetooth devices. Scale is similar to status bar policy
+ */
+ private int gsmAsuToSignal(SignalStrength signalStrength) {
+ int asu = signalStrength.getGsmSignalStrength();
+ if (asu >= 16) return 5;
+ else if (asu >= 8) return 4;
+ else if (asu >= 4) return 3;
+ else if (asu >= 2) return 2;
+ else if (asu >= 1) return 1;
+ else return 0;
}
- // TODO(): There is a bug open regarding what should be sent.
- return (cdmaIconLevel > evdoIconLevel) ? cdmaIconLevel : evdoIconLevel;
- }
- };
+
+ /**
+ * Convert the cdma / evdo db levels to appropriate icon level.
+ * The scale is similar to the one used in status bar policy.
+ *
+ * @param signalStrength
+ * @return the icon level
+ */
+ private int cdmaDbmEcioToSignal(SignalStrength signalStrength) {
+ int levelDbm = 0;
+ int levelEcio = 0;
+ int cdmaIconLevel = 0;
+ int evdoIconLevel = 0;
+ int cdmaDbm = signalStrength.getCdmaDbm();
+ int cdmaEcio = signalStrength.getCdmaEcio();
+
+ if (cdmaDbm >= -75) levelDbm = 4;
+ else if (cdmaDbm >= -85) levelDbm = 3;
+ else if (cdmaDbm >= -95) levelDbm = 2;
+ else if (cdmaDbm >= -100) levelDbm = 1;
+ else levelDbm = 0;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) levelEcio = 4;
+ else if (cdmaEcio >= -110) levelEcio = 3;
+ else if (cdmaEcio >= -130) levelEcio = 2;
+ else if (cdmaEcio >= -150) levelEcio = 1;
+ else levelEcio = 0;
+
+ cdmaIconLevel = (levelDbm < levelEcio) ? levelDbm : levelEcio;
+
+ // STOPSHIP: Change back to getRilVoiceRadioTechnology
+ if (mServiceState != null &&
+ (mServiceState.getRadioTechnology() ==
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
+ mServiceState.getRadioTechnology() ==
+ ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A)) {
+ int evdoEcio = signalStrength.getEvdoEcio();
+ int evdoSnr = signalStrength.getEvdoSnr();
+ int levelEvdoEcio = 0;
+ int levelEvdoSnr = 0;
+
+ // Ec/Io are in dB*10
+ if (evdoEcio >= -650) levelEvdoEcio = 4;
+ else if (evdoEcio >= -750) levelEvdoEcio = 3;
+ else if (evdoEcio >= -900) levelEvdoEcio = 2;
+ else if (evdoEcio >= -1050) levelEvdoEcio = 1;
+ else levelEvdoEcio = 0;
+
+ if (evdoSnr > 7) levelEvdoSnr = 4;
+ else if (evdoSnr > 5) levelEvdoSnr = 3;
+ else if (evdoSnr > 3) levelEvdoSnr = 2;
+ else if (evdoSnr > 1) levelEvdoSnr = 1;
+ else levelEvdoSnr = 0;
+
+ evdoIconLevel = (levelEvdoEcio < levelEvdoSnr) ? levelEvdoEcio : levelEvdoSnr;
+ }
+ // TODO(): There is a bug open regarding what should be sent.
+ return (cdmaIconLevel > evdoIconLevel) ? cdmaIconLevel : evdoIconLevel;
+ }
+ };
+ return mPhoneStateListener;
+ }
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index ae2954e..1e8dc7f 100755
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -129,7 +129,7 @@ public class HeadsetService extends ProfileService {
}
private HeadsetService getService() {
- if (!Utils.checkCaller()) {
+ if (!Utils.checkCallerAllowManagedProfiles(mService)) {
Log.w(TAG,"Headset call not allowed for non-active user");
return null;
}
@@ -557,4 +557,11 @@ public class HeadsetService extends ProfileService {
return true;
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ if (mStateMachine != null) {
+ mStateMachine.dump(sb);
+ }
+ }
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index 6752b45..3bbaa35 100755..100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -53,11 +53,13 @@ import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.PowerManager;
+import android.os.UserHandle;
import android.os.PowerManager.WakeLock;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
+import com.android.bluetooth.btservice.ProfileService;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -297,6 +299,20 @@ final class HeadsetStateMachine extends StateMachine {
}
}
+ public void dump(StringBuilder sb) {
+ ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
+ ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
+ ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);
+ ProfileService.println(sb, "mActiveScoDevice: " + mActiveScoDevice);
+ ProfileService.println(sb, "mMultiDisconnectDevice: " + mMultiDisconnectDevice);
+ ProfileService.println(sb, "mVirtualCallStarted: " + mVirtualCallStarted);
+ ProfileService.println(sb, "mVoiceRecognitionStarted: " + mVoiceRecognitionStarted);
+ ProfileService.println(sb, "mWaitingForVoiceRecognition: " + mWaitingForVoiceRecognition);
+ ProfileService.println(sb, "StateMachine: " + this.toString());
+ ProfileService.println(sb, "mPhoneState: " + mPhoneState);
+ ProfileService.println(sb, "mAudioState: " + mAudioState);
+ }
+
private class Disconnected extends State {
@Override
public void enter() {
@@ -2295,7 +2311,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
}
private void broadcastAudioState(BluetoothDevice device, int newState, int prevState) {
@@ -2308,7 +2325,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
log("Audio state " + device + ": " + prevState + "->" + newState);
}
@@ -2333,7 +2351,8 @@ final class HeadsetStateMachine extends StateMachine {
intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY
+ "." + Integer.toString(companyId));
- mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL,
+ HeadsetService.BLUETOOTH_PERM);
}
private void configAudioParameters(BluetoothDevice device)
@@ -2697,10 +2716,14 @@ final class HeadsetStateMachine extends StateMachine {
String number = mPhoneProxy.getSubscriberNumber();
if (number != null) {
atResponseStringNative("+CNUM: ,\"" + number + "\"," +
- PhoneNumberUtils.toaFromString(number) +
- ",,4", getByteAddress(device));
+ PhoneNumberUtils.toaFromString(number) +
+ ",,4", getByteAddress(device));
atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK,
- 0, getByteAddress(device));
+ 0, getByteAddress(device));
+ } else {
+ Log.e(TAG, "getSubscriberNumber returns null");
+ atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR,
+ 0, getByteAddress(device));
}
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
index aaf7156..d7eb12d 100644
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientService.java
@@ -734,4 +734,12 @@ public class HeadsetClientService extends ProfileService {
}
return mStateMachine.getCurrentAgFeatures();
}
+
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ if (mStateMachine != null) {
+ mStateMachine.dump(sb);
+ }
+ }
}
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
index d50602a..b3e4b0a 100644
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -158,6 +158,35 @@ final class HeadsetClientStateMachine extends StateMachine {
classInitNative();
}
+ public void dump(StringBuilder sb) {
+ ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
+ ProfileService.println(sb, "mAudioOn: " + mAudioOn);
+ ProfileService.println(sb, "mAudioState: " + mAudioState);
+ ProfileService.println(sb, "mAudioWbs: " + mAudioWbs);
+ ProfileService.println(sb, "mIndicatorNetworkState: " + mIndicatorNetworkState);
+ ProfileService.println(sb, "mIndicatorNetworkType: " + mIndicatorNetworkType);
+ ProfileService.println(sb, "mIndicatorNetworkSignal: " + mIndicatorNetworkSignal);
+ ProfileService.println(sb, "mIndicatorBatteryLevel: " + mIndicatorBatteryLevel);
+ ProfileService.println(sb, "mIndicatorCall: " + mIndicatorCall);
+ ProfileService.println(sb, "mIndicatorCallSetup: " + mIndicatorCallSetup);
+ ProfileService.println(sb, "mIndicatorCallHeld: " + mIndicatorCallHeld);
+ ProfileService.println(sb, "mVgsFromStack: " + mVgsFromStack);
+ ProfileService.println(sb, "mVgmFromStack: " + mVgmFromStack);
+ ProfileService.println(sb, "mRingtone: " + mRingtone);
+ ProfileService.println(sb, "mOperatorName: " + mOperatorName);
+ ProfileService.println(sb, "mSubscriberInfo: " + mSubscriberInfo);
+ ProfileService.println(sb, "mVoiceRecognitionActive: " + mVoiceRecognitionActive);
+ ProfileService.println(sb, "mInBandRingtone: " + mInBandRingtone);
+ ProfileService.println(sb, "mCalls:");
+ for (BluetoothHeadsetClientCall call : mCalls.values()) {
+ ProfileService.println(sb, " " + call);
+ }
+ ProfileService.println(sb, "mCallsUpdate:");
+ for (BluetoothHeadsetClientCall call : mCallsUpdate.values()) {
+ ProfileService.println(sb, " " + call);
+ }
+ }
+
private void clearPendingAction() {
mPendingAction = new Pair<Integer, Object>(NO_ACTION, 0);
}
diff --git a/src/com/android/bluetooth/hid/HidService.java b/src/com/android/bluetooth/hid/HidService.java
index 219332e..418c13b 100755
--- a/src/com/android/bluetooth/hid/HidService.java
+++ b/src/com/android/bluetooth/hid/HidService.java
@@ -680,6 +680,16 @@ public class HidService extends ProfileService {
}
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ println(sb, "mTargetDevice: " + mTargetDevice);
+ println(sb, "mInputDevices:");
+ for (BluetoothDevice device : mInputDevices.keySet()) {
+ println(sb, " " + device + " : " + mInputDevices.get(device));
+ }
+ }
+
// Constants matching Hal header file bt_hh.h
// bthh_connection_state_t
private final static int CONN_STATE_CONNECTED = 0;
diff --git a/src/com/android/bluetooth/map/BluetoothMapContent.java b/src/com/android/bluetooth/map/BluetoothMapContent.java
index 41df206..540cbbb 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContent.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContent.java
@@ -44,6 +44,7 @@ import com.google.android.mms.pdu.PduHeaders;
import com.android.bluetooth.map.BluetoothMapAppParams;
import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -216,148 +217,13 @@ public class BluetoothMapContent {
mBaseEmailUri = emailBaseUri;
}
-
-
- private void printSms(Cursor c) {
- String body = c.getString(c.getColumnIndex(Sms.BODY));
- if (V) Log.v(TAG, "printSms " + BaseColumns._ID + ": " + c.getLong(c.getColumnIndex(BaseColumns._ID)) +
- "\n " + Sms.THREAD_ID + " : " + c.getLong(c.getColumnIndex(Sms.THREAD_ID)) +
- "\n " + Sms.ADDRESS + " : " + c.getString(c.getColumnIndex(Sms.ADDRESS)) +
- "\n " + Sms.BODY + " : " + body.substring(0, Math.min(body.length(), 8)) +
- "\n " + Sms.DATE + " : " + c.getLong(c.getColumnIndex(Sms.DATE)) +
- "\n " + Sms.READ + " : " + c.getLong(c.getColumnIndex(Sms.READ)) +
- "\n " + Sms.TYPE + " : " + c.getInt(c.getColumnIndex(Sms.TYPE)) +
- "\n " + Sms.STATUS + " : " + c.getInt(c.getColumnIndex(Sms.STATUS)) +
- "\n " + Sms.LOCKED + " : " + c.getInt(c.getColumnIndex(Sms.LOCKED)) +
- "\n " + Sms.ERROR_CODE + " : " + c.getInt(c.getColumnIndex(Sms.ERROR_CODE)));
-
-
- }
-
- private void printMms(Cursor c) {
- if (V) Log.v(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)) +
- "\n " + Mms.PRIORITY + " : " + c.getInt(c.getColumnIndex(Mms.PRIORITY)) +
- "\n " + Mms.MESSAGE_SIZE + " : " + c.getInt(c.getColumnIndex(Mms.MESSAGE_SIZE)));
- }
-
- 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 (V) Log.v(TAG, "printEmail " + BaseColumns._ID + ": " + c.getLong(c.getColumnIndex(BaseColumns._ID)) +
- "\n " + BluetoothMapContract.MessageColumns.DATE + " : " + getDateTimeString(c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns.DATE))) +
- "\n " + BluetoothMapContract.MessageColumns.SUBJECT + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.SUBJECT)) +
- "\n " + BluetoothMapContract.MessageColumns.FLAG_READ + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_READ)) +
- "\n " + BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY)) +
- "\n " + BluetoothMapContract.MessageColumns.RECEPTION_STATE + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.RECEPTION_STATE)) +
- "\n " + BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_ATTACHMENT)) +
- "\n " + BluetoothMapContract.MessageColumns.MESSAGE_SIZE + " : " + c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns.MESSAGE_SIZE)) +
- "\n " + BluetoothMapContract.MessageColumns.FLAG_PROTECTED + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FLAG_PROTECTED)) +
- "\n " + BluetoothMapContract.MessageColumns.FROM_LIST + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.FROM_LIST)) +
- "\n " + BluetoothMapContract.MessageColumns.TO_LIST + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.TO_LIST)) +
- "\n " + BluetoothMapContract.MessageColumns.CC_LIST + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.CC_LIST)) +
- "\n " + BluetoothMapContract.MessageColumns.BCC_LIST + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.BCC_LIST)) +
- "\n " + BluetoothMapContract.MessageColumns.REPLY_TO_LIST + " : " + c.getString(c.getColumnIndex(BluetoothMapContract.MessageColumns.REPLY_TO_LIST)) +
- "\n " + BluetoothMapContract.MessageColumns.FOLDER_ID + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID)) +
- "\n " + BluetoothMapContract.MessageColumns.ACCOUNT_ID + " : " + c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.ACCOUNT_ID)) );
- }
-
- private void printMmsAddr(long id) {
- final String[] projection = null;
- String selection = new String("msg_id=" + id);
- String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/addr");
- 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 = new String(Mms.CONTENT_URI + "/part/" + partid);
- Uri uriAddress = Uri.parse(uriStr);
- int ch;
- StringBuffer sb = new StringBuffer("");
- InputStream is = null;
-
+ private static void close(Closeable c) {
try {
- is = mResolver.openInputStream(uriAddress);
-
- while ((ch = is.read()) != -1) {
- sb.append((char)ch);
- }
- if (D) Log.d(TAG, sb.toString());
-
+ if (c != null) c.close();
} 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 = new String(Mms.CONTENT_URI + "/" + id + "/part");
- 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());
- }
- }
-
-
private void setProtected(BluetoothMapMessageListingElement e, Cursor c,
FilterInfo fi, BluetoothMapAppParams ap) {
if ((ap.getParameterMask() & MASK_PROTECTED) != 0) {
@@ -747,7 +613,6 @@ public class BluetoothMapContent {
date = c.getLong(fi.mEmailColDate);
}
e.setDateTime(date);
- if (V) Log.v(TAG, "setDateTime: " + e.getDateTimeString());
}
}
@@ -757,11 +622,10 @@ public class BluetoothMapContent {
String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/part");
Uri uriAddress = Uri.parse(uriStr);
// TODO: maybe use a projection with only "ct" and "text"
- Cursor c = mResolver.query(uriAddress, null, selection,
- null, null);
- if (c != null && c.moveToFirst()) {
- do {
+ Cursor c = mResolver.query(uriAddress, null, selection, null, null);
+ try {
+ while(c != null && c.moveToNext()) {
String ct = c.getString(c.getColumnIndex("ct"));
if (ct.equals("text/plain")) {
String part = c.getString(c.getColumnIndex("text"));
@@ -769,10 +633,9 @@ public class BluetoothMapContent {
text += part;
}
}
- } while(c.moveToNext());
- }
- if (c != null) {
- c.close();
+ }
+ } finally {
+ close(c);
}
return text;
}
@@ -844,13 +707,13 @@ public class BluetoothMapContent {
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));
+ try {
+ if (c != null && c.moveToFirst()) {
+ name = c.getString(c.getColumnIndex(Contacts.DISPLAY_NAME));
+ };
+ } finally {
+ close(c);
}
-
- c.close();
return name;
}
@@ -859,17 +722,17 @@ public class BluetoothMapContent {
String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/addr");
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(Mms.Addr.ADDRESS));
- if(addr.equals(INSERT_ADDRES_TOKEN))
- addr = "";
+ Cursor c = r.query(uriAddress, null, selection, null, null);
+ try {
+ if (c != null && c.moveToFirst()) {
+ addr = c.getString(c.getColumnIndex(Mms.Addr.ADDRESS));
+ if (addr.equals(INSERT_ADDRES_TOKEN)) addr = "";
+ }
+ } finally {
+ close(c);
}
- if (c != null) {
- c.close();
- }
return addr;
}
@@ -1173,29 +1036,32 @@ public class BluetoothMapContent {
new String[]{str},
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
- while (c != null && c.moveToNext()) {
- String contactId = c.getString(c.getColumnIndex(ContactsContract.Contacts._ID));
+ try {
+ 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);
+ 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));
+ try {
+ while (p != null && p.moveToNext()) {
+ String number = p.getString(
+ p.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
- where += " address = " + "'" + number + "'";
- if (!p.isLast()) {
- where += " OR ";
+ where += " address = " + "'" + number + "'";
+ if (!p.isLast()) where += " OR ";
+ }
+ } finally {
+ close(p);
}
+
+ if (!c.isLast()) where += " OR ";
}
- if (!c.isLast()) {
- where += " OR ";
- }
- p.close();
+ } finally {
+ close(c);
}
- c.close();
if (str != null && str.length() > 0) {
if (where.length() > 0) {
@@ -1382,153 +1248,155 @@ public class BluetoothMapContent {
Cursor smsCursor = null;
Cursor mmsCursor = null;
Cursor emailCursor = null;
- String limit = "";
- int countNum = ap.getMaxListCount();
- int offsetNum = ap.getStartOffset();
- if(ap.getMaxListCount()>0){
- limit=" LIMIT "+ (ap.getMaxListCount()+ap.getStartOffset());
- }
- if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
- if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
- BluetoothMapAppParams.FILTER_NO_MMS|
- BluetoothMapAppParams.FILTER_NO_SMS_GSM)||
- ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
- BluetoothMapAppParams.FILTER_NO_MMS|
- BluetoothMapAppParams.FILTER_NO_SMS_CDMA)){
- //set real limit and offset if only this type is used (only if offset/limit is used
- limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
- if(D) Log.d(TAG, "SMS Limit => "+limit);
- offsetNum = 0;
+ try {
+ String limit = "";
+ int countNum = ap.getMaxListCount();
+ int offsetNum = ap.getStartOffset();
+ if(ap.getMaxListCount()>0){
+ limit=" LIMIT "+ (ap.getMaxListCount()+ap.getStartOffset());
}
- fi.mMsgType = FilterInfo.TYPE_SMS;
- if(ap.getFilterPriority() != 1){ /*SMS cannot have high priority*/
+
+ if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
+ if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
+ BluetoothMapAppParams.FILTER_NO_MMS|
+ BluetoothMapAppParams.FILTER_NO_SMS_GSM)||
+ ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
+ BluetoothMapAppParams.FILTER_NO_MMS|
+ BluetoothMapAppParams.FILTER_NO_SMS_CDMA)){
+ //set real limit and offset if only this type is used (only if offset/limit is used
+ limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
+ if(D) Log.d(TAG, "SMS Limit => "+limit);
+ offsetNum = 0;
+ }
+ fi.mMsgType = FilterInfo.TYPE_SMS;
+ if(ap.getFilterPriority() != 1){ /*SMS cannot have high priority*/
+ String where = setWhereFilter(folderElement, fi, ap);
+ if(!where.isEmpty()) {
+ if (D) Log.d(TAG, "msgType: " + fi.mMsgType);
+ smsCursor = mResolver.query(Sms.CONTENT_URI,
+ SMS_PROJECTION, where, null, Sms.DATE + " DESC" + limit);
+ if (smsCursor != null) {
+ BluetoothMapMessageListingElement e = null;
+ // store column index so we dont have to look them up anymore (optimization)
+ if(D) Log.d(TAG, "Found " + smsCursor.getCount() + " sms messages.");
+ fi.setSmsColumns(smsCursor);
+ while (smsCursor.moveToNext()) {
+ if (matchAddresses(smsCursor, fi, ap)) {
+ e = element(smsCursor, fi, ap);
+ bmList.add(e);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (mmsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
+ if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
+ BluetoothMapAppParams.FILTER_NO_SMS_CDMA|
+ BluetoothMapAppParams.FILTER_NO_SMS_GSM)){
+ //set real limit and offset if only this type is used (only if offset/limit is used
+ limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
+ if(D) Log.d(TAG, "MMS Limit => "+limit);
+ offsetNum = 0;
+ }
+ fi.mMsgType = FilterInfo.TYPE_MMS;
String where = setWhereFilter(folderElement, fi, ap);
if(!where.isEmpty()) {
if (D) Log.d(TAG, "msgType: " + fi.mMsgType);
- smsCursor = mResolver.query(Sms.CONTENT_URI,
- SMS_PROJECTION, where, null, Sms.DATE + " DESC" + limit);
- if (smsCursor != null) {
+ mmsCursor = mResolver.query(Mms.CONTENT_URI,
+ MMS_PROJECTION, where, null, Mms.DATE + " DESC" + limit);
+ if (mmsCursor != null) {
BluetoothMapMessageListingElement e = null;
// store column index so we dont have to look them up anymore (optimization)
- if(D) Log.d(TAG, "Found " + smsCursor.getCount() + " sms messages.");
- fi.setSmsColumns(smsCursor);
- while (smsCursor.moveToNext()) {
- if (matchAddresses(smsCursor, fi, ap)) {
- if(V) printSms(smsCursor);
- e = element(smsCursor, fi, ap);
+ fi.setMmsColumns(mmsCursor);
+ int cnt = 0;
+ if(D) Log.d(TAG, "Found " + mmsCursor.getCount() + " mms messages.");
+ while (mmsCursor.moveToNext()) {
+ if (matchAddresses(mmsCursor, fi, ap)) {
+ e = element(mmsCursor, fi, ap);
bmList.add(e);
}
}
}
}
}
- }
- if (mmsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
- if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_EMAIL|
- BluetoothMapAppParams.FILTER_NO_SMS_CDMA|
- BluetoothMapAppParams.FILTER_NO_SMS_GSM)){
- //set real limit and offset if only this type is used (only if offset/limit is used
- limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
- if(D) Log.d(TAG, "MMS Limit => "+limit);
- offsetNum = 0;
- }
- fi.mMsgType = FilterInfo.TYPE_MMS;
- String where = setWhereFilter(folderElement, fi, ap);
- if(!where.isEmpty()) {
- if (D) Log.d(TAG, "msgType: " + fi.mMsgType);
- mmsCursor = mResolver.query(Mms.CONTENT_URI,
- MMS_PROJECTION, where, null, Mms.DATE + " DESC" + limit);
- if (mmsCursor != null) {
- BluetoothMapMessageListingElement e = null;
- // store column index so we dont have to look them up anymore (optimization)
- fi.setMmsColumns(mmsCursor);
- int cnt = 0;
- if(D) Log.d(TAG, "Found " + mmsCursor.getCount() + " mms messages.");
- while (mmsCursor.moveToNext()) {
- if (matchAddresses(mmsCursor, fi, ap)) {
- if(V) printMms(mmsCursor);
- e = element(mmsCursor, fi, ap);
+ if (emailSelected(fi, ap) && folderElement.getEmailFolderId() != -1) {
+ if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_MMS|
+ BluetoothMapAppParams.FILTER_NO_SMS_CDMA|
+ BluetoothMapAppParams.FILTER_NO_SMS_GSM)){
+ //set real limit and offset if only this type is used (only if offset/limit is used
+ limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
+ if(D) Log.d(TAG, "Email Limit => "+limit);
+ offsetNum = 0;
+ }
+ fi.mMsgType = FilterInfo.TYPE_EMAIL;
+ String where = setWhereFilter(folderElement, fi, ap);
+
+ if(!where.isEmpty()) {
+ if (D) Log.d(TAG, "msgType: " + fi.mMsgType);
+ Uri contentUri = Uri.parse(mBaseEmailUri + BluetoothMapContract.TABLE_MESSAGE);
+ emailCursor = mResolver.query(contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION,
+ where, null, BluetoothMapContract.MessageColumns.DATE + " DESC" + limit);
+ if (emailCursor != null) {
+ BluetoothMapMessageListingElement e = null;
+ // store column index so we dont have to look them up anymore (optimization)
+ fi.setEmailColumns(emailCursor);
+ int cnt = 0;
+ while (emailCursor.moveToNext()) {
+ if(D) Log.d(TAG, "Found " + emailCursor.getCount() + " email messages.");
+ e = element(emailCursor, fi, ap);
bmList.add(e);
}
+ // emailCursor.close();
}
}
}
- }
- if (emailSelected(fi, ap) && folderElement.getEmailFolderId() != -1) {
- if(ap.getFilterMessageType() == (BluetoothMapAppParams.FILTER_NO_MMS|
- BluetoothMapAppParams.FILTER_NO_SMS_CDMA|
- BluetoothMapAppParams.FILTER_NO_SMS_GSM)){
- //set real limit and offset if only this type is used (only if offset/limit is used
- limit = " LIMIT " + ap.getMaxListCount()+" OFFSET "+ ap.getStartOffset();
- if(D) Log.d(TAG, "Email Limit => "+limit);
- offsetNum = 0;
- }
- fi.mMsgType = FilterInfo.TYPE_EMAIL;
- String where = setWhereFilter(folderElement, fi, ap);
+ /* Enable this if post sorting and segmenting needed */
+ bmList.sort();
+ bmList.segment(ap.getMaxListCount(), offsetNum);
+ List<BluetoothMapMessageListingElement> list = bmList.getList();
+ int listSize = list.size();
+ Cursor tmpCursor = null;
+ for (int x=0; x<listSize; x++){
+ BluetoothMapMessageListingElement ele = list.get(x);
+ if ((ele.getType().equals(TYPE.SMS_GSM)||ele.getType().equals(TYPE.SMS_CDMA)) && smsCursor != null){
+ tmpCursor = smsCursor;
+ fi.mMsgType = FilterInfo.TYPE_SMS;
+ } else if (ele.getType().equals(TYPE.MMS) && mmsCursor != null){
+ tmpCursor = mmsCursor;
+ fi.mMsgType = FilterInfo.TYPE_MMS;
+ } else if (ele.getType().equals(TYPE.EMAIL) && emailCursor != null){
+ tmpCursor = emailCursor;
+ fi.mMsgType = FilterInfo.TYPE_EMAIL;
+ }
- if(!where.isEmpty()) {
- if (D) Log.d(TAG, "msgType: " + fi.mMsgType);
- Uri contentUri = Uri.parse(mBaseEmailUri + BluetoothMapContract.TABLE_MESSAGE);
- emailCursor = mResolver.query(contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION,
- where, null, BluetoothMapContract.MessageColumns.DATE + " DESC" + limit);
- if (emailCursor != null) {
- BluetoothMapMessageListingElement e = null;
- // store column index so we dont have to look them up anymore (optimization)
- fi.setEmailColumns(emailCursor);
- int cnt = 0;
- while (emailCursor.moveToNext()) {
- if(V) printEmail(emailCursor);
- if(D) Log.d(TAG, "Found " + emailCursor.getCount() + " email messages.");
- e = element(emailCursor, fi, ap);
- bmList.add(e);
- }
- // emailCursor.close();
+ if (tmpCursor != null && tmpCursor.moveToPosition(ele.getCursorIndex())) {
+ setSenderAddressing(ele, tmpCursor, fi, ap);
+ setSenderName(ele, tmpCursor, fi, ap);
+ setRecipientAddressing(ele, tmpCursor, fi, ap);
+ setRecipientName(ele, tmpCursor, fi, ap);
+ setSubject(ele, tmpCursor, fi, ap);
+ setSize(ele, tmpCursor, fi, ap);
+ setReceptionStatus(ele, tmpCursor, fi, ap);
+ setText(ele, tmpCursor, fi, ap);
+ setAttachmentSize(ele, tmpCursor, fi, ap);
+ setPriority(ele, tmpCursor, fi, ap);
+ setSent(ele, tmpCursor, fi, ap);
+ setProtected(ele, tmpCursor, fi, ap);
+ setThreadId(ele, tmpCursor, fi, ap);
}
}
+ } finally {
+ close(emailCursor);
+ close(smsCursor);
+ close(mmsCursor);
}
- /* Enable this if post sorting and segmenting needed */
- bmList.sort();
- bmList.segment(ap.getMaxListCount(), offsetNum);
- List<BluetoothMapMessageListingElement> list = bmList.getList();
- int listSize = list.size();
- Cursor tmpCursor = null;
- for(int x=0;x<listSize;x++){
- BluetoothMapMessageListingElement ele = list.get(x);
- if((ele.getType().equals(TYPE.SMS_GSM)||ele.getType().equals(TYPE.SMS_CDMA)) && smsCursor != null){
- tmpCursor = smsCursor;
- fi.mMsgType = FilterInfo.TYPE_SMS;
- }else if(ele.getType().equals(TYPE.MMS) && mmsCursor != null){
- tmpCursor = mmsCursor;
- fi.mMsgType = FilterInfo.TYPE_MMS;
- }else if(ele.getType().equals(TYPE.EMAIL) && emailCursor != null){
- tmpCursor = emailCursor;
- fi.mMsgType = FilterInfo.TYPE_EMAIL;
- }
- if(tmpCursor != null){
- tmpCursor.moveToPosition(ele.getCursorIndex());
- setSenderAddressing(ele, tmpCursor, fi, ap);
- setSenderName(ele, tmpCursor, fi, ap);
- setRecipientAddressing(ele, tmpCursor, fi, ap);
- setRecipientName(ele, tmpCursor, fi, ap);
- setSubject(ele, tmpCursor, fi, ap);
- setSize(ele, tmpCursor, fi, ap);
- setReceptionStatus(ele, tmpCursor, fi, ap);
- setText(ele, tmpCursor, fi, ap);
- setAttachmentSize(ele, tmpCursor, fi, ap);
- setPriority(ele, tmpCursor, fi, ap);
- setSent(ele, tmpCursor, fi, ap);
- setProtected(ele, tmpCursor, fi, ap);
- setThreadId(ele, tmpCursor, fi, ap);
- }
- }
- if(emailCursor != null)emailCursor.close();
- if(smsCursor != null)smsCursor.close();
- if(mmsCursor != null)mmsCursor.close();
- if(D)Log.d(TAG, "messagelisting end");
+ if (D) Log.d(TAG, "messagelisting end");
return bmList;
}
@@ -1547,40 +1415,34 @@ public class BluetoothMapContent {
FilterInfo fi = new FilterInfo();
setFilterInfo(fi);
- if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
+ if (smsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
fi.mMsgType = FilterInfo.TYPE_SMS;
String where = setWhereFilter(folderElement, fi, ap);
Cursor c = mResolver.query(Sms.CONTENT_URI,
SMS_PROJECTION, where, null, Sms.DATE + " DESC");
- if (c != null) {
- cnt = c.getCount();
- c.close();
- }
+ if (c != null) cnt = c.getCount();
+ close(c);
}
- if (mmsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
+ if (mmsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
fi.mMsgType = FilterInfo.TYPE_MMS;
String where = setWhereFilter(folderElement, fi, ap);
Cursor c = mResolver.query(Mms.CONTENT_URI,
MMS_PROJECTION, where, null, Mms.DATE + " DESC");
- if (c != null) {
- cnt += c.getCount();
- c.close();
- }
+ if (c != null) cnt += c.getCount();
+ close(c);
}
if (emailSelected(fi, ap) && folderElement.getEmailFolderId() != -1) {
fi.mMsgType = FilterInfo.TYPE_EMAIL;
String where = setWhereFilter(folderElement, fi, ap);
- if(!where.isEmpty()) {
+ if (!where.isEmpty()) {
Uri contentUri = Uri.parse(mBaseEmailUri + BluetoothMapContract.TABLE_MESSAGE);
Cursor c = mResolver.query(contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION,
where, null, BluetoothMapContract.MessageColumns.DATE + " DESC");
- if (c != null) {
- cnt += c.getCount();
- c.close();
- }
+ if (c != null) cnt += c.getCount();
+ close(c);
}
}
@@ -1611,10 +1473,8 @@ public class BluetoothMapContent {
Cursor c = mResolver.query(Sms.CONTENT_URI,
SMS_PROJECTION, where, null, Sms.DATE + " DESC");
- if (c != null) {
- cnt = c.getCount();
- c.close();
- }
+ if (c != null) cnt += c.getCount();
+ close(c);
}
if (mmsSelected(fi, ap) && folderElement.hasSmsMmsContent()) {
@@ -1625,10 +1485,8 @@ public class BluetoothMapContent {
Cursor c = mResolver.query(Mms.CONTENT_URI,
MMS_PROJECTION, where, null, Sms.DATE + " DESC");
- if (c != null) {
- cnt += c.getCount();
- c.close();
- }
+ if (c != null) cnt += c.getCount();
+ close(c);
}
@@ -1641,10 +1499,8 @@ public class BluetoothMapContent {
Uri contentUri = Uri.parse(mBaseEmailUri + BluetoothMapContract.TABLE_MESSAGE);
Cursor c = mResolver.query(contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION,
where, null, BluetoothMapContract.MessageColumns.DATE + " DESC");
- if (c != null) {
- cnt += c.getCount();
- c.close();
- }
+ if (c != null) cnt += c.getCount();
+ close(c);
}
}
@@ -1701,7 +1557,6 @@ public class BluetoothMapContent {
String contactId = null, contactName = null;
String[] phoneNumbers = null;
String[] emailAddresses = null;
- Cursor p;
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phone));
@@ -1711,40 +1566,44 @@ public class BluetoothMapContent {
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 {
- // use only actual phone number
- phoneNumbers = new String[1];
- phoneNumbers[0] = phone;
+ Cursor p = mResolver.query(uri, projection, selection, null, orderBy);
- // 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;
+ try {
+ if (p != null && p.moveToFirst()) {
+ contactId = p.getString(p.getColumnIndex(Contacts._ID));
+ contactName = p.getString(p.getColumnIndex(Contacts.DISPLAY_NAME));
+ }
+
+ // 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 {
+ // use only actual phone number
+ phoneNumbers = new String[1];
+ phoneNumbers[0] = phone;
+
+ // Fetch contact e-mail addresses
+ close (p);
+ 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();
}
+ } finally {
+ close(p);
}
- if(incoming == true) {
+
+ if (incoming == true) {
if(V) Log.d(TAG, "Adding originator for phone:" + phone);
message.addOriginator(contactName, contactName, phoneNumbers, emailAddresses); // Use version 3.0 as we only have a formatted name
} else {
@@ -1763,10 +1622,13 @@ public class BluetoothMapContent {
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()) {
+ throw new IllegalArgumentException("SMS handle not found");
+ }
- if(c != null && c.moveToFirst())
- {
+ try {
if(V) Log.v(TAG,"c.count: " + c.getCount());
if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
@@ -1803,12 +1665,11 @@ public class BluetoothMapContent {
} else /*if (charset == MAP_MESSAGE_CHARSET_UTF8)*/ {
message.setSmsBody(msgBody);
}
-
- c.close();
-
- return message.encode();
+ } finally {
+ close(c);
}
- throw new IllegalArgumentException("SMS handle not found");
+
+ return message.encode();
}
private void extractMmsAddresses(long id, BluetoothMapbMessageMms message) {
@@ -1817,9 +1678,10 @@ public class BluetoothMapContent {
String uriStr = new String(Mms.CONTENT_URI + "/" + id + "/addr");
Uri uriAddress = Uri.parse(uriStr);
String contactName = null;
+
Cursor c = mResolver.query( uriAddress, projection, selection, null, null);
- if (c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
String address = c.getString(c.getColumnIndex(Mms.Addr.ADDRESS));
if(address.equals(INSERT_ADDRES_TOKEN))
continue;
@@ -1844,7 +1706,9 @@ public class BluetoothMapContent {
default:
break;
}
- } while(c.moveToNext());
+ }
+ } finally {
+ close (c);
}
}
@@ -1873,11 +1737,8 @@ public class BluetoothMapContent {
// do nothing for now
Log.w(TAG,"Error reading part data",e);
} finally {
- try {
- os.close();
- is.close();
- } catch (IOException e) {
- }
+ close(os);
+ close(is);
}
return retVal;
}
@@ -1896,14 +1757,10 @@ public class BluetoothMapContent {
String uriStr = new String(Mms.CONTENT_URI + "/"+ id + "/part");
Uri uriAddress = Uri.parse(uriStr);
BluetoothMapbMessageMms.MimePart part;
- Cursor c = mResolver.query(
- uriAddress,
- projection,
- selection,
- null, null);
-
- if (c.moveToFirst()) {
- do {
+ Cursor c = mResolver.query(uriAddress, projection, selection, null, null);
+
+ try {
+ while(c != null && c.moveToNext()) {
Long partId = c.getLong(c.getColumnIndex(BaseColumns._ID));
String contentType = c.getString(c.getColumnIndex(Mms.Part.CONTENT_TYPE));
String name = c.getString(c.getColumnIndex(Mms.Part.NAME));
@@ -1950,11 +1807,13 @@ public class BluetoothMapContent {
Log.d(TAG,"extractMmsParts",e);
part.mData = null;
part.mCharsetName = null;
- } finally {
}
part.mFileName = filename;
- } while(c.moveToNext());
+ }
+ } finally {
+ close(c);
}
+
message.updateCharset();
}
@@ -1973,8 +1832,11 @@ public class BluetoothMapContent {
BluetoothMapbMessageMms message = new BluetoothMapbMessageMms();
Cursor c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION, "_ID = " + id, null, null);
- if(c != null && c.moveToFirst())
- {
+ if (c == null || !c.moveToFirst()) {
+ throw new IllegalArgumentException("MMS handle not found");
+ }
+
+ try {
message.setType(TYPE.MMS);
// The MMS info:
@@ -1993,23 +1855,14 @@ public class BluetoothMapContent {
message.setDate(c.getLong(c.getColumnIndex(Mms.DATE)) * 1000L);
message.setTextOnly(c.getInt(c.getColumnIndex(Mms.TEXT_ONLY)) == 0 ? false : true);
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();
+ } finally {
+ close(c);
}
- throw new IllegalArgumentException("MMS handle not found");
+ return message.encode();
}
/**
@@ -2037,11 +1890,12 @@ public class BluetoothMapContent {
BluetoothMapbMessageEmail message = new BluetoothMapbMessageEmail();
Uri contentUri = Uri.parse(mBaseEmailUri + BluetoothMapContract.TABLE_MESSAGE);
Cursor c = mResolver.query(contentUri, BluetoothMapContract.BT_MESSAGE_PROJECTION, "_ID = " + id, null, null);
- if(c != null && c.moveToFirst())
- {
+ if (c != null && c.moveToFirst()) {
+ throw new IllegalArgumentException("EMAIL handle not found");
+ }
+
+ try {
BluetoothMapFolderElement folderElement;
- FileInputStream is = null;
- ParcelFileDescriptor fd = null;
// Handle fraction requests
int fractionRequest = appParams.getFractionRequest();
@@ -2106,7 +1960,6 @@ public class BluetoothMapContent {
i++;
}
}
- c.close();
// Find out if we get attachments
String attStr = (appParams.getAttachment() == 0) ? "/" + BluetoothMapContract.FILE_MSG_NO_ATTACHMENTS : "";
@@ -2114,6 +1967,9 @@ public class BluetoothMapContent {
// Get email message body content
int count = 0;
+ FileInputStream is = null;
+ ParcelFileDescriptor fd = null;
+
try {
fd = mResolver.openFileDescriptor(uri, "r");
is = new FileInputStream(fd.getFileDescriptor());
@@ -2132,21 +1988,14 @@ public class BluetoothMapContent {
Log.w(TAG, e);
} catch (IOException e) {
Log.w(TAG, e);
+ } finally {
+ close(is);
+ close(fd);
}
- finally {
- try {
- if(is != null)
- is.close();
- } catch (IOException e) {}
- try {
- if(fd != null)
- fd.close();
- } catch (IOException e) {}
- }
- return message.encode();
- } else if(c != null) {
- c.close();
+ } finally {
+ close(c);
}
- throw new IllegalArgumentException("EMAIL handle not found");
+
+ return message.encode();
}
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index 7101f22..dd14c82 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -14,6 +14,7 @@
*/
package com.android.bluetooth.map;
+import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -116,6 +117,13 @@ public class BluetoothMapContentObserver {
private TYPE mSmsType;
+ private static void close(Closeable c) {
+ try {
+ if (c != null) c.close();
+ } catch (IOException e) {
+ }
+ }
+
static final String[] SMS_PROJECTION = new String[] {
Sms._ID,
Sms.THREAD_ID,
@@ -452,17 +460,19 @@ public class BluetoothMapContentObserver {
Cursor c = mResolver.query(Sms.CONTENT_URI,
SMS_PROJECTION_SHORT, null, null, null);
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Sms._ID));
int type = c.getInt(c.getColumnIndex(Sms.TYPE));
int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
Msg msg = new Msg(id, type, threadId);
msgListSms.put(id, msg);
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
+
synchronized(mMsgListSms) {
mMsgListSms.clear();
mMsgListSms = msgListSms;
@@ -472,17 +482,19 @@ public class BluetoothMapContentObserver {
c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null);
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Mms._ID));
int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
Msg msg = new Msg(id, type, threadId);
msgListMms.put(id, msg);
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
+
synchronized(mMsgListMms) {
mMsgListMms.clear();
mMsgListMms = msgListMms;
@@ -494,16 +506,18 @@ public class BluetoothMapContentObserver {
Uri uri = mMessageUri;
Cursor c = mProviderClient.query(uri, EMAIL_PROJECTION_SHORT, null, null, null);
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(MessageColumns._ID));
long folderId = c.getInt(c.getColumnIndex(BluetoothMapContract.MessageColumns.FOLDER_ID));
Msg msg = new Msg(id, folderId);
msgListEmail.put(id, msg);
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
+
synchronized(mMsgListEmail) {
mMsgListEmail.clear();
mMsgListEmail = msgListEmail;
@@ -520,8 +534,8 @@ public class BluetoothMapContentObserver {
SMS_PROJECTION_SHORT, null, null, null);
synchronized(mMsgListSms) {
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Sms._ID));
int type = c.getInt(c.getColumnIndex(Sms.TYPE));
int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
@@ -570,8 +584,9 @@ public class BluetoothMapContentObserver {
}
msgListSms.put(id, msg);
}
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
for (Msg msg : mMsgListSms.values()) {
@@ -594,8 +609,8 @@ public class BluetoothMapContentObserver {
MMS_PROJECTION_SHORT, null, null, null);
synchronized(mMsgListMms) {
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Mms._ID));
int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE));
@@ -657,8 +672,9 @@ public class BluetoothMapContentObserver {
}
msgListMms.put(id, msg);
}
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
for (Msg msg : mMsgListMms.values()) {
@@ -681,8 +697,8 @@ public class BluetoothMapContentObserver {
Cursor c = mProviderClient.query(mMessageUri, EMAIL_PROJECTION_SHORT, null, null, null);
synchronized(mMsgListEmail) {
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c != null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(BluetoothMapContract.MessageColumns._ID));
int folderId = c.getInt(c.getColumnIndex(
BluetoothMapContract.MessageColumns.FOLDER_ID));
@@ -750,8 +766,9 @@ public class BluetoothMapContentObserver {
}
msgListEmail.put(id, msg);
}
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
// For all messages no longer in the database send a delete notification
@@ -893,31 +910,34 @@ public class BluetoothMapContentObserver {
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 */
- synchronized(mMsgListMms) {
- Msg msg = mMsgListMms.get(handle);
- if(msg != null) { // This will always be the case
- msg.threadId = DELETED_THREAD_ID;
+
+ try {
+ 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 */
+ synchronized(mMsgListMms) {
+ Msg msg = mMsgListMms.get(handle);
+ if(msg != null) { // This will always be the case
+ msg.threadId = DELETED_THREAD_ID;
+ }
}
+ updateThreadId(uri, Mms.THREAD_ID, DELETED_THREAD_ID);
+ } else {
+ /* Delete from observer message list to avoid delete notifications */
+ synchronized(mMsgListMms) {
+ mMsgListMms.remove(handle);
+ }
+ /* Delete message */
+ mResolver.delete(uri, null, null);
}
- updateThreadId(uri, Mms.THREAD_ID, DELETED_THREAD_ID);
- } else {
- /* Delete from observer message list to avoid delete notifications */
- synchronized(mMsgListMms) {
- mMsgListMms.remove(handle);
- }
- /* Delete message */
- mResolver.delete(uri, null, null);
+ res = true;
}
- res = true;
- }
- if (c != null) {
- c.close();
+ } finally {
+ close(c);
}
+
return res;
}
@@ -926,40 +946,42 @@ public class BluetoothMapContentObserver {
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(Mms._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));
- Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
- synchronized(mMsgListMms) {
- Msg msg = mMsgListMms.get(handle);
- if(msg != null) { // This will always be the case
- msg.threadId = oldThreadId.intValue();
+ try {
+ 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(Mms._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));
+ Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
+ synchronized(mMsgListMms) {
+ Msg msg = mMsgListMms.get(handle);
+ if(msg != null) { // This will always be the case
+ msg.threadId = oldThreadId.intValue();
+ }
}
+ updateThreadId(uri, Mms.THREAD_ID, oldThreadId);
+ } else {
+ Log.d(TAG, "Message not in deleted folder: handle " + handle
+ + " threadId " + threadId);
}
- updateThreadId(uri, Mms.THREAD_ID, oldThreadId);
- } else {
- Log.d(TAG, "Message not in deleted folder: handle " + handle
- + " threadId " + threadId);
+ res = true;
}
- res = true;
- }
- if (c != null) {
- c.close();
+ } finally {
+ close(c);
}
+
return res;
}
@@ -968,31 +990,33 @@ public class BluetoothMapContentObserver {
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) {
- synchronized(mMsgListSms) {
- Msg msg = mMsgListSms.get(handle);
- if(msg != null) { // This will always be the case
- msg.threadId = DELETED_THREAD_ID;
+ try {
+ 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) {
+ synchronized(mMsgListSms) {
+ Msg msg = mMsgListSms.get(handle);
+ if(msg != null) { // This will always be the case
+ msg.threadId = DELETED_THREAD_ID;
+ }
}
+ /* Set deleted thread id */
+ updateThreadId(uri, Sms.THREAD_ID, DELETED_THREAD_ID);
+ } else {
+ /* Delete from observer message list to avoid delete notifications */
+ synchronized(mMsgListSms) {
+ mMsgListSms.remove(handle);
+ }
+ /* Delete message */
+ mResolver.delete(uri, null, null);
}
- /* Set deleted thread id */
- updateThreadId(uri, Sms.THREAD_ID, DELETED_THREAD_ID);
- } else {
- /* Delete from observer message list to avoid delete notifications */
- synchronized(mMsgListSms) {
- mMsgListSms.remove(handle);
- }
- /* Delete message */
- mResolver.delete(uri, null, null);
+ res = true;
}
- res = true;
- }
- if (c != null) {
- c.close();
+ } finally {
+ close(c);
}
+
return res;
}
@@ -1001,29 +1025,31 @@ public class BluetoothMapContentObserver {
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));
- Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
- synchronized(mMsgListSms) {
- Msg msg = mMsgListSms.get(handle);
- if(msg != null) { // This will always be the case
- msg.threadId = oldThreadId.intValue(); // The threadId is specified as an int, so it is safe to truncate
+ try {
+ 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));
+ Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients);
+ synchronized(mMsgListSms) {
+ Msg msg = mMsgListSms.get(handle);
+ if(msg != null) { // This will always be the case
+ msg.threadId = oldThreadId.intValue(); // The threadId is specified as an int, so it is safe to truncate
+ }
}
+ updateThreadId(uri, Sms.THREAD_ID, oldThreadId);
+ } else {
+ Log.d(TAG, "Message not in deleted folder: handle " + handle
+ + " threadId " + threadId);
}
- updateThreadId(uri, Sms.THREAD_ID, oldThreadId);
- } else {
- Log.d(TAG, "Message not in deleted folder: handle " + handle
- + " threadId " + threadId);
+ res = true;
}
- res = true;
- }
- if (c != null) {
- c.close();
+ } finally {
+ close(c);
}
+
return res;
}
@@ -1073,7 +1099,6 @@ public class BluetoothMapContentObserver {
if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
Uri uri = Sms.Inbox.CONTENT_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);
contentValues.put(Sms.SEEN, statusValue);
@@ -1082,15 +1107,15 @@ public class BluetoothMapContentObserver {
if (D) Log.d(TAG, " -> SMS Uri: " + uri.toString() + " Where " + where + " values " + values);
count = mResolver.update(uri, contentValues, where, null);
if (D) Log.d(TAG, " -> "+count +" rows updated!");
+
} else if (type == TYPE.MMS) {
Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle);
- Cursor c = mResolver.query(uri, null, null, null, null);
if (D) Log.d(TAG, " -> MMS Uri: " + uri.toString());
ContentValues contentValues = new ContentValues();
contentValues.put(Mms.READ, statusValue);
count = mResolver.update(uri, contentValues, null, null);
-
if (D) Log.d(TAG, " -> "+count +" rows updated!");
+
} if (type == TYPE.EMAIL) {
Uri uri = mMessageUri;
ContentValues contentValues = new ContentValues();
@@ -1098,10 +1123,8 @@ public class BluetoothMapContentObserver {
contentValues.put(BluetoothMapContract.MessageColumns._ID, handle);
count = mProviderClient.update(uri, contentValues, null, null);
}
- if(count < 1) {
- return false;
- }
- return true;
+
+ return (count > 0);
}
private class PushMsgInfo {
@@ -1267,18 +1290,20 @@ public class BluetoothMapContentObserver {
return -1;
}
Cursor c = mResolver.query(uri, SMS_PROJECTION_SHORT, null, null, null);
-
- /* Extract the data for the inserted message, and store in local mirror, to
- * avoid sending a NewMessage Event. */
- if (c != null && c.moveToFirst()) {
- long id = c.getLong(c.getColumnIndex(Sms._ID));
- int type = c.getInt(c.getColumnIndex(Sms.TYPE));
- int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
- Msg newMsg = new Msg(id, type, threadId);
- mMsgListSms.put(id, newMsg);
- c.close();
- } else {
- return -1; // This can only happen, if the message is deleted just as it is added
+ try {
+ /* Extract the data for the inserted message, and store in local mirror, to
+ * avoid sending a NewMessage Event. */
+ if (c != null && c.moveToFirst()) {
+ long id = c.getLong(c.getColumnIndex(Sms._ID));
+ int type = c.getInt(c.getColumnIndex(Sms.TYPE));
+ int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID));
+ Msg newMsg = new Msg(id, type, threadId);
+ mMsgListSms.put(id, newMsg);
+ } else {
+ return -1; // This can only happen, if the message is deleted just as it is added
+ }
+ } finally {
+ close(c);
}
handle = Long.parseLong(uri.getLastPathSegment());
@@ -1335,28 +1360,28 @@ public class BluetoothMapContentObserver {
}
}
-
private void moveDraftToOutbox(long handle) {
/*Move message by changing the msg_box value in the content provider database */
- if (handle != -1) {
- String whereClause = " _id= " + handle;
- Uri uri = Mms.CONTENT_URI;
- Cursor queryResult = mResolver.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(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
- mResolver.update(uri, data, whereClause, null);
- if (D) Log.d(TAG, "moved draft MMS to outbox");
- }
- queryResult.close();
- }else {
+ if (handle != -1) return;
+
+ String whereClause = " _id= " + handle;
+ Uri uri = Mms.CONTENT_URI;
+ Cursor queryResult = mResolver.query(uri, null, whereClause, null, null);
+ try {
+ if (queryResult != null && queryResult.moveToFirst()) {
+ ContentValues data = new ContentValues();
+ /* set folder to be outbox */
+ data.put(Mms.MESSAGE_BOX, Mms.MESSAGE_BOX_OUTBOX);
+ mResolver.update(uri, data, whereClause, null);
+ if (D) Log.d(TAG, "Moved draft MMS to outbox");
+ } else {
if (D) Log.d(TAG, "Could not move draft to outbox ");
}
+ } finally {
+ queryResult.close();
}
}
+
private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMms msg) {
/**
* strategy:
@@ -1400,7 +1425,6 @@ public class BluetoothMapContentObserver {
Uri uri = Mms.CONTENT_URI;
synchronized (mMsgListMms) {
-
uri = mResolver.insert(uri, values);
if (uri == null) {
@@ -1412,19 +1436,21 @@ public class BluetoothMapContentObserver {
doing the query ensures we get any changes made by the content provider
at insert. */
Cursor c = mResolver.query(uri, MMS_PROJECTION_SHORT, null, null, null);
+ try {
+ if (c != null && c.moveToFirst()) {
+ long id = c.getLong(c.getColumnIndex(Mms._ID));
+ int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
+ int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
- if (c != null && c.moveToFirst()) {
- long id = c.getLong(c.getColumnIndex(Mms._ID));
- int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
- int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID));
-
- /* We must filter out any actions made by the MCE. Add the new message to
- * the list of known messages. */
+ /* We must filter out any actions made by the MCE. Add the new message to
+ * the list of known messages. */
- Msg newMsg = new Msg(id, type, threadId);
- newMsg.localInitiatedSend = true;
- mMsgListMms.put(id, newMsg);
- c.close();
+ Msg newMsg = new Msg(id, type, threadId);
+ newMsg.localInitiatedSend = true;
+ mMsgListMms.put(id, newMsg);
+ }
+ } finally {
+ close(c);
}
} // Done adding changes, unlock access to mMsgListMms to allow sending MMS events again
@@ -1437,9 +1463,9 @@ public class BluetoothMapContentObserver {
Log.w(TAG, "No MMS parts present...");
} else {
if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() + " parts to the data base.");
+ int count = 0;
for(MimePart part : msg.getMimeParts()) {
- int count = 0;
- count++;
+ ++count;
values.clear();
if(part.mContentType != null && part.mContentType.toUpperCase().contains("TEXT")) {
values.put(Mms.Part.CONTENT_TYPE, "text/plain");
@@ -1912,11 +1938,10 @@ public class BluetoothMapContentObserver {
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);
+ Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c!= null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Sms._ID));
String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
PushMsgInfo msgInfo = mPushMsgList.get(id);
@@ -1925,19 +1950,20 @@ public class BluetoothMapContentObserver {
}
msgInfo.sendInProgress = true;
sendMessage(msgInfo, msgBody);
- } while (c.moveToNext());
- c.close();
+ }
+ } finally {
+ close(c);
}
}
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);
+ Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, null);
+ if (c == null) return;
- if (c != null && c.moveToFirst()) {
- do {
+ try {
+ while (c!= null && c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Sms._ID));
String msgBody = c.getString(c.getColumnIndex(Sms.BODY));
PushMsgInfo msgInfo = mPushMsgList.get(id);
@@ -1946,9 +1972,10 @@ public class BluetoothMapContentObserver {
}
Sms.moveMessageToFolder(mContext, msgInfo.uri,
Sms.MESSAGE_TYPE_FAILED, 0);
- } while (c.moveToNext());
+ }
+ } finally {
+ close(c);
}
- if (c != null) c.close();
}
private void removeDeletedMessages() {
@@ -1989,5 +2016,4 @@ public class BluetoothMapContentObserver {
}
return false;
}
-
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapEmailSettingsLoader.java b/src/com/android/bluetooth/map/BluetoothMapEmailSettingsLoader.java
index d42a808..c6a6ca7 100644
--- a/src/com/android/bluetooth/map/BluetoothMapEmailSettingsLoader.java
+++ b/src/com/android/bluetooth/map/BluetoothMapEmailSettingsLoader.java
@@ -151,28 +151,16 @@ public class BluetoothMapEmailSettingsLoader {
}
mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT);
-
- Uri uri = Uri.parse(app.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_ACCOUNT);
-
- c = mProviderClient.query(uri, BluetoothMapContract.BT_ACCOUNT_PROJECTION, null, null, BluetoothMapContract.AccountColumns._ID+" DESC");
- } catch (RemoteException e){
- if(D)Log.d(TAG,"Could not establish ContentProviderClient for "+app.getPackageName()+
- " - returning empty account list" );
- return children;
- }
-
- if (c != null) {
- c.moveToPosition(-1);
- while (c.moveToNext()) {
- if(D)Log.d(TAG,"Adding account " +c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME))+
- " with ID "+String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))));
-
+ Uri uri = Uri.parse(app.mBase_uri_no_account + "/" + BluetoothMapContract.TABLE_ACCOUNT);
+ c = mProviderClient.query(uri, BluetoothMapContract.BT_ACCOUNT_PROJECTION, null, null,
+ BluetoothMapContract.AccountColumns._ID+" DESC");
+ while (c != null && c.moveToNext()) {
BluetoothMapEmailSettingsItem child = new BluetoothMapEmailSettingsItem(
- /*id*/ String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))),
- /*name*/ c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME)) ,
- /*package name*/ app.getPackageName(),
- /*providerMeta*/ app.getProviderAuthority(),
- /*icon*/ null);
+ String.valueOf((c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns._ID)))),
+ c.getString(c.getColumnIndex(BluetoothMapContract.AccountColumns.ACCOUNT_DISPLAY_NAME)) ,
+ app.getPackageName(),
+ app.getProviderAuthority(),
+ null);
child.mIsChecked = (c.getInt(c.getColumnIndex(BluetoothMapContract.AccountColumns.FLAG_EXPOSE))!=0);
/*update the account counter so we can make sure that not to many accounts are checked. */
@@ -182,9 +170,11 @@ public class BluetoothMapEmailSettingsLoader {
}
children.add(child);
}
- c.close();
- } else {
- if(D)Log.d(TAG, "query failed");
+ } catch (RemoteException e){
+ if(D)Log.d(TAG,"Could not establish ContentProviderClient for "+app.getPackageName()+
+ " - returning empty account list" );
+ } finally {
+ if (c != null) c.close();
}
return children;
}
@@ -198,5 +188,4 @@ public class BluetoothMapEmailSettingsLoader {
if(D)Log.d(TAG,"Enabled Accounts count:"+ mAccountsEnabledCount);
return mAccountsEnabledCount;
}
-
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
index fe2207e..7b321d1 100644
--- a/src/com/android/bluetooth/map/BluetoothMapObexServer.java
+++ b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -212,17 +212,15 @@ public class BluetoothMapObexServer extends ServerRequestHandler {
" = " + parentFolder.getEmailFolderId();
Cursor c = mProviderClient.query(mEmailFolderUri,
BluetoothMapContract.BT_FOLDER_PROJECTION, where, null, null);
- if (c != null) {
- c.moveToPosition(-1);
- while (c.moveToNext()) {
+ try {
+ while (c != null && c.moveToNext()) {
String name = c.getString(c.getColumnIndex(BluetoothMapContract.FolderColumns.NAME));
long id = c.getLong(c.getColumnIndex(BluetoothMapContract.FolderColumns._ID));
newFolder = parentFolder.addEmailFolder(name, id);
addEmailFolders(newFolder); // Use recursion to add any sub folders
}
- c.close();
- } else {
- if (D) Log.d(TAG, "addEmailFolders(): no elements found");
+ } finally {
+ if (c != null) c.close();
}
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java
index f016fb1..12c294b 100755
--- a/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -74,9 +74,9 @@ public class BluetoothMapService extends ProfileService {
* DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE"
*/
- public static final boolean DEBUG = true; //TODO: set to false
+ public static final boolean DEBUG = true;
- public static final boolean VERBOSE = true; //TODO: set to false
+ public static final boolean VERBOSE = false;
/**
* Intent indicating timeout for user confirmation, which is sent to
@@ -1084,4 +1084,26 @@ public class BluetoothMapService extends ProfileService {
return service.getPriority(device);
}
}
+
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ println(sb, "mRemoteDevice: " + mRemoteDevice);
+ println(sb, "sRemoteDeviceName: " + sRemoteDeviceName);
+ println(sb, "mState: " + mState);
+ println(sb, "mAppObserver: " + mAppObserver);
+ println(sb, "mIsWaitingAuthorization: " + mIsWaitingAuthorization);
+ println(sb, "mRemoveTimeoutMsg: " + mRemoveTimeoutMsg);
+ println(sb, "mPermission: " + mPermission);
+ println(sb, "mAccountChanged: " + mAccountChanged);
+ println(sb, "mBluetoothMnsObexClient: " + mBluetoothMnsObexClient);
+ println(sb, "mMasInstanceMap:");
+ for (BluetoothMapEmailSettingsItem key : mMasInstanceMap.keySet()) {
+ println(sb, " " + key + " : " + mMasInstanceMap.get(key));
+ }
+ println(sb, "mEnabledAccounts:");
+ for (BluetoothMapEmailSettingsItem account : mEnabledAccounts) {
+ println(sb, " " + account);
+ }
+ }
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java b/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
index 5b7b8db..4428874 100644
--- a/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
+++ b/src/com/android/bluetooth/map/BluetoothMapSmsPdu.java
@@ -482,7 +482,7 @@ public class BluetoothMapSmsPdu {
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.cdma.SmsMessage.calculateLength((CharSequence)messageText, false, true) :
com.android.internal.telephony.gsm.SmsMessage.calculateLength((CharSequence)messageText, false);
SmsPdu newPdu;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java b/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
index 1855bc9..3a39439 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
@@ -75,8 +75,6 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity imple
private ContentValues mUpdateValues;
- private TextView mContentView;
-
private boolean mTimeout = false;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -200,7 +198,7 @@ public class BluetoothOppIncomingFileConfirmActivity extends AlertActivity imple
private void onTimeout() {
mTimeout = true;
- mContentView.setText(getString(R.string.incoming_file_confirm_timeout_content,
+ mAlert.setTitle(getString(R.string.incoming_file_confirm_timeout_content,
mTransInfo.mDeviceName));
mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setText(
diff --git a/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java b/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
index 5bd54af..f0d4cda 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppObexServerSession.java
@@ -276,7 +276,8 @@ public class BluetoothOppObexServerSession extends ServerRequestHandler implemen
boolean needConfirm = true;
/** It's not first put if !serverBlocking, so we auto accept it */
- if (!mServerBlocking) {
+ if (!mServerBlocking && (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED ||
+ mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED)) {
values.put(BluetoothShare.USER_CONFIRMATION,
BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED);
needConfirm = false;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java
index 4d71584..f952bec 100755
--- a/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -704,7 +704,7 @@ public class BluetoothOppService extends Service {
info.mDestination = stringFromCursor(info.mDestination, cursor, BluetoothShare.DESTINATION);
int newVisibility = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY));
- boolean confirmed = false;
+ boolean confirmUpdated = false;
int newConfirm = cursor.getInt(cursor
.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION));
@@ -718,7 +718,7 @@ public class BluetoothOppService extends Service {
if (info.mConfirm == BluetoothShare.USER_CONFIRMATION_PENDING
&& newConfirm != BluetoothShare.USER_CONFIRMATION_PENDING) {
- confirmed = true;
+ confirmUpdated = true;
}
info.mConfirm = cursor.getInt(cursor
.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION));
@@ -736,14 +736,14 @@ public class BluetoothOppService extends Service {
info.mTimestamp = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP));
info.mMediaScanned = (cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) != Constants.MEDIA_SCANNED_NOT_SCANNED);
- if (confirmed) {
- if (V) Log.v(TAG, "Service handle info " + info.mId + " confirmed");
- /* Inbounds transfer get user confirmation, so we start it */
+ if (confirmUpdated) {
+ if (V) Log.v(TAG, "Service handle info " + info.mId + " confirmation updated");
+ /* Inbounds transfer user confirmation status changed, update the session server */
int i = findBatchWithTimeStamp(info.mTimestamp);
if (i != -1) {
BluetoothOppBatch batch = mBatchs.get(i);
if (mServerTransfer != null && batch.mId == mServerTransfer.getBatchId()) {
- mServerTransfer.setConfirmed();
+ mServerTransfer.confirmStatusChanged();
} //TODO need to think about else
}
}
@@ -870,7 +870,7 @@ public class BluetoothOppService extends Service {
mServerTransfer.start();
if (nextBatch.getPendingShare().mConfirm ==
BluetoothShare.USER_CONFIRMATION_CONFIRMED) {
- mServerTransfer.setConfirmed();
+ mServerTransfer.confirmStatusChanged();
}
return;
}
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransfer.java b/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
index 2dbed49..6c883d2 100755
--- a/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransfer.java
@@ -462,7 +462,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch
if (V) Log.v(TAG, "processCurrentShare" + mCurrentShare.mId);
mSession.addShare(mCurrentShare);
if (mCurrentShare.mConfirm == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) {
- setConfirmed();
+ confirmStatusChanged();
}
}
@@ -470,7 +470,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch
* Set transfer confirmed status. It should only be called for inbound
* transfer
*/
- public void setConfirmed() {
+ public void confirmStatusChanged() {
/* unblock server session */
final Thread notifyThread = new Thread("Server Unblock thread") {
public void run() {
@@ -480,7 +480,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch
}
}
};
- if (V) Log.v(TAG, "setConfirmed to unblock mSession" + mSession.toString());
+ if (V) Log.v(TAG, "confirmStatusChanged to unblock mSession" + mSession.toString());
notifyThread.start();
}
@@ -711,7 +711,7 @@ public class BluetoothOppTransfer implements BluetoothOppBatch.BluetoothOppBatch
if (V) Log.v(TAG, "Transfer continue session for info " + mCurrentShare.mId +
" from batch " + mBatch.mId);
processCurrentShare();
- setConfirmed();
+ confirmStatusChanged();
}
}
}
diff --git a/src/com/android/bluetooth/pan/PanService.java b/src/com/android/bluetooth/pan/PanService.java
index 5d1bc30..23753ed 100755
--- a/src/com/android/bluetooth/pan/PanService.java
+++ b/src/com/android/bluetooth/pan/PanService.java
@@ -50,9 +50,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-
/**
* Provides Bluetooth Pan Device profile, as a service in
* the Bluetooth application.
@@ -76,8 +73,6 @@ public class PanService extends ProfileService {
private static final int MESSAGE_DISCONNECT = 2;
private static final int MESSAGE_CONNECT_STATE_CHANGED = 11;
private boolean mTetherOn = false;
- private static final String PAN_PREFERENCE_FILE = "PANMGR";
- private static final String PAN_TETHER_SETTING = "TETHERSTATE";
private BluetoothTetheringNetworkFactory mNetworkFactory;
@@ -109,10 +104,6 @@ public class PanService extends ProfileService {
mNetworkFactory = new BluetoothTetheringNetworkFactory(getBaseContext(), getMainLooper(),
this);
- // Set mTetherOn based on the last saved tethering preference while starting the Pan service
- SharedPreferences tetherSetting = getSharedPreferences(PAN_PREFERENCE_FILE, 0);
- mTetherOn = tetherSetting.getBoolean(PAN_TETHER_SETTING, false);
-
return true;
}
@@ -238,6 +229,7 @@ public class PanService extends ProfileService {
return service.isPanUOn();
}
public boolean isTetheringOn() {
+ // TODO(BT) have a variable marking the on/off state
PanService service = getService();
if (service == null) return false;
return service.isTetheringOn();
@@ -297,6 +289,7 @@ public class PanService extends ProfileService {
return (getPanLocalRoleNative() & BluetoothPan.LOCAL_PANU_ROLE) != 0;
}
boolean isTetheringOn() {
+ // TODO(BT) have a variable marking the on/off state
return mTetherOn;
}
@@ -309,14 +302,6 @@ public class PanService extends ProfileService {
throw new SecurityException("DISALLOW_CONFIG_TETHERING is enabled for this user.");
}
if(mTetherOn != value) {
-
- SharedPreferences tetherSetting = getSharedPreferences(PAN_PREFERENCE_FILE, 0);
- SharedPreferences.Editor editor = tetherSetting.edit();
-
- editor.putBoolean(PAN_TETHER_SETTING, value);
-
- // Commit the edit!
- editor.commit();
//drop any existing panu or pan-nap connection when changing the tethering state
mTetherOn = value;
List<BluetoothDevice> DevList = getConnectedDevices();
@@ -576,6 +561,22 @@ public class PanService extends ProfileService {
return panDevice.mState;
}
+ @Override
+ public void dump(StringBuilder sb) {
+ super.dump(sb);
+ println(sb, "mMaxPanDevices: " + mMaxPanDevices);
+ println(sb, "mPanIfName: " + mPanIfName);
+ println(sb, "mTetherOn: " + mTetherOn);
+ println(sb, "mPanDevices:");
+ for (BluetoothDevice device : mPanDevices.keySet()) {
+ println(sb, " " + device + " : " + mPanDevices.get(device));
+ }
+ println(sb, "mBluetoothIfaceAddresses:");
+ for (String address : mBluetoothIfaceAddresses) {
+ println(sb, " " + address);
+ }
+ }
+
private class BluetoothPanDevice {
private int mState;
private String mIfaceAddr;
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
index 2c0bb4a..d3e116e 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapVcardManager.java
@@ -520,10 +520,8 @@ public class BluetoothPbapVcardManager {
if (isContacts) {
VCardComposer composer = null;
- FilterVcard vcardfilter= new FilterVcard();
- if (!ignorefilter) {
- vcardfilter.setFilter(filter);
- }
+ VCardFilter vcardfilter= new VCardFilter(ignorefilter ? null : filter);
+
HandlerForStringBuffer buffer = null;
try {
// Currently only support Generic Vcard 2.1 and 3.0
@@ -575,15 +573,11 @@ public class BluetoothPbapVcardManager {
return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
}
if (V) Log.v (TAG , "vCard from composer: " + vcard);
- if (!ignorefilter) {
- vcard = vcardfilter.applyFilter(vcard, vcardType21);
- if (V) Log.v (TAG , "vCard on applying filter: " + vcard);
- }
+
+ vcard = vcardfilter.apply(vcard, vcardType21);
vcard = StripTelephoneNumber(vcard);
- if (V) {
- Log.v(TAG, "Vcard Entry:");
- Log.v(TAG,vcard);
- }
+
+ if (V) Log.v (TAG, "vCard after cleanup: " + vcard);
if (!buffer.onEntryCreated(vcard)) {
// onEntryCreate() already emits error.
@@ -724,288 +718,84 @@ public class BluetoothPbapVcardManager {
}
}
- public class FilterVcard{
-
- public FilterVcard(){
- };
-
- private final int FN_BIT = 1;
-
- private boolean fn = true;
-
- private final int PHOTO_BIT = 3;
-
- private boolean photo = true;
-
- //BDAY falls under events
- private final int BDAY_BIT = 4;
-
- private boolean bday = true;
-
- private final int ADR_BIT = 5;
-
- private boolean adr = true;
-
- private final int EMAIL_BIT = 8;
-
- private boolean email = true;
-
- private final int TITLE_BIT = 12;
-
- private boolean title = true;
-
- private final int ORG_BIT = 16;
-
- private boolean org = true;
-
- private final int NOTES_BIT = 17;
-
- private boolean notes = true;
-
- private final int URL_BIT = 20;
-
- private boolean url = true;
-
- private final int NICKNAME_BIT = 23;
-
- private boolean nickname = true;
-
- public void setFilter(byte[] filter){
-
- fn = checkbit(FN_BIT, filter);
- photo = checkbit(PHOTO_BIT, filter);
- bday = checkbit(BDAY_BIT, filter);
- adr = checkbit(ADR_BIT, filter);
- email = checkbit(EMAIL_BIT, filter);
- title = checkbit(TITLE_BIT, filter);
- org = checkbit(ORG_BIT, filter);
- notes = checkbit(NOTES_BIT, filter);
- url = checkbit(URL_BIT, filter);
- nickname = checkbit(NICKNAME_BIT, filter);
- }
-
- private boolean checkbit (int attr_bit, byte[] filter){
- int filterlen = filter.length;
- if( ((filter[filterlen -1 -((int)attr_bit/8)] >> (attr_bit%8)) & 0x01) == 0) {
- return false;
- }
- return true;
- }
-
- public boolean isPhotoEnabled(){
- return photo;
- }
-
- private boolean checkValidFilter (String attr) {
- if((attr.startsWith("N:")) || (attr.startsWith("TEL"))
- || (attr.startsWith("VERSION")) || (attr.startsWith("URL"))
- || (attr.startsWith("FN")) || (attr.startsWith("BDAY"))
- || (attr.startsWith("ADR")) || (attr.startsWith("EMAIL"))
- || (attr.startsWith("TITLE")) || (attr.startsWith("ORG"))
- || (attr.startsWith("NOTE")) || (attr.startsWith("NICKNAME"))) {
- return true;
- }
- return false;
- }
-
- public String applyFilter ( String vCard, boolean vCardType21){
- String attr [] = vCard.split(System.getProperty("line.separator"));
- String filteredVcard = "";
-
- //FN is not the mandatory field in 2.1 vCard
- if(((!fn) && (vCardType21)) && (vCard.contains("FN"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("FN")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- //NOTE: No need to check photo, we already refrained it if it is not set in the filter
- if((!bday) && (vCard.contains("BDAY"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("BDAY")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!adr) && (vCard.contains("ADR"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("ADR")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!email) && (vCard.contains("EMAIL"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("EMAIL")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!title) && (vCard.contains("TITLE"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("TITLE")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!org) && (vCard.contains("ORG"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("ORG")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!notes) && (vCard.contains("NOTE"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("NOTE")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
- /*Nickname is not supported in 2.1 version.
- *Android still ads it for 2.1 with nickname mentioned in lower case, and therefore
- *we need to check for both cases.
- */
- if(((!nickname) || (vCardType21)) && (vCard.contains("NICKNAME"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("NICKNAME")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
- }
- }
- }
- }
-
- if((!url) && (vCard.contains("URL"))) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].startsWith("URL")){
- attr[i] = "";
- /** Remove multiline Content, if any */
- /** End traversal before END:VCARD */
- for (int j = i+1; j < attr.length - 1; j++) {
- if (checkValidFilter(attr[j])) {
- break;
- } else {
- /** Continuation of above attribute, remove */
- attr[j] = "";
- }
+ public static class VCardFilter {
+ private static enum FilterBit {
+ // bit property onlyCheckV21 excludeForV21
+ FN ( 1, "FN", true, false),
+ PHOTO( 3, "PHOTO", false, false),
+ BDAY( 4, "BDAY", false, false),
+ ADR( 5, "ADR", false, false),
+ EMAIL( 8, "EMAIL", false, false),
+ TITLE( 12, "TITLE", false, false),
+ ORG( 16, "ORG", false, false),
+ NOTES( 17, "NOTES", false, false),
+ URL( 20, "URL", false, false),
+ NICKNAME( 23, "NICKNAME", false, true);
+
+ public final int pos;
+ public final String prop;
+ public final boolean onlyCheckV21;
+ public final boolean excludeForV21;
+
+ FilterBit(int pos, String prop, boolean onlyCheckV21, boolean excludeForV21) {
+ this.pos = pos;
+ this.prop = prop;
+ this.onlyCheckV21 = onlyCheckV21;
+ this.excludeForV21 = excludeForV21;
+ }
+ }
+
+ private static final String SEPARATOR = System.getProperty("line.separator");
+ private final byte[] filter;
+
+ private boolean isFilteredOut(FilterBit bit, boolean vCardType21) {
+ final int offset = (bit.pos / 8) + 1;
+ final int bit_pos = bit.pos % 8;
+ if (!vCardType21 && bit.onlyCheckV21) return false;
+ if (vCardType21 && bit.excludeForV21) return true;
+ if (filter == null || offset >= filter.length) return false;
+ return ((filter[filter.length - offset] >> bit_pos) & 0x01) != 0;
+ }
+
+ VCardFilter(byte[] filter) {
+ this.filter = filter;
+ }
+
+ public boolean isPhotoEnabled() {
+ return !isFilteredOut(FilterBit.PHOTO, false);
+ }
+
+ public String apply(String vCard, boolean vCardType21){
+ if (filter == null) return vCard;
+ String lines[] = vCard.split(SEPARATOR);
+ StringBuilder filteredVCard = new StringBuilder();
+ boolean filteredOut = false;
+
+ for (String line : lines) {
+ // Check whether the current property is changing (ignoring multi-line properties)
+ // and determine if the current property is filtered in.
+ if (!Character.isWhitespace(line.charAt(0)) && !line.startsWith("=")) {
+ String currentProp = line.split("[;:]")[0];
+ filteredOut = false;
+
+ for (FilterBit bit : FilterBit.values()) {
+ if (bit.prop.equals(currentProp)) {
+ filteredOut = isFilteredOut(bit, vCardType21);
+ break;
}
}
- }
- }
- /*Since PBAP does not have filter bit for IM and SIP,
- *removing them by default.
- */
- if(vCard.toUpperCase().contains("IM")) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].toUpperCase().contains("IM")){
- vCard = vCard.replace(attr[i] + "\n", "");
- }
- }
- }
- if(vCard.toUpperCase().contains("SIP")) {
- for (int i=0; i < attr.length; i++) {
- if(attr[i].toUpperCase().contains("SIP")){
- vCard = vCard.replace(attr[i] + "\n", "");
- }
+ // Since PBAP does not have filter bits for IM and SIP,
+ // exclude them by default. Easiest way is to exclude all
+ // X- fields....
+ if (currentProp.startsWith("X-")) filteredOut = true;
}
- }
-
- Log.v(TAG, "Tokens after applying filter: ");
- for (int i=0; i < attr.length; i++) {
- if(!attr[i].equals("")){
- filteredVcard = filteredVcard.concat(attr[i] + "\n");
- }
+ // Build filtered vCard
+ if (!filteredOut) filteredVCard.append(line + SEPARATOR);
}
- return filteredVcard;
+ return filteredVCard.toString();
}
}
}
diff --git a/src/com/android/bluetooth/util/NumberUtils.java b/src/com/android/bluetooth/util/NumberUtils.java
new file mode 100644
index 0000000..1d27456
--- /dev/null
+++ b/src/com/android/bluetooth/util/NumberUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.util;
+
+/**
+ * Utility for parsing numbers in Bluetooth.
+ */
+public class NumberUtils {
+
+ /**
+ * Convert a byte to unsigned int.
+ */
+ public static int unsignedByteToInt(byte b) {
+ return b & 0xFF;
+ }
+
+ /**
+ * Convert a little endian byte array to integer.
+ */
+ public static int littleEndianByteArrayToInt(byte[] bytes) {
+ int length = bytes.length;
+ if (length == 0) {
+ return 0;
+ }
+ int result = 0;
+ for (int i = length - 1; i >= 0; i--) {
+ int value = unsignedByteToInt(bytes[i]);
+ result += (value << (i * 8));
+ }
+ return result;
+ }
+}
diff --git a/tests/src/com/android/bluetooth/gatt/GattServiceTest.java b/tests/src/com/android/bluetooth/gatt/GattServiceTest.java
new file mode 100644
index 0000000..28c5a10
--- /dev/null
+++ b/tests/src/com/android/bluetooth/gatt/GattServiceTest.java
@@ -0,0 +1,22 @@
+
+package com.android.bluetooth.gatt;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.bluetooth.gatt.GattService;
+
+/**
+ * Test cases for {@link GattService}.
+ */
+public class GattServiceTest extends AndroidTestCase {
+
+ @SmallTest
+ public void testParseBatchTimestamp() {
+ GattService service = new GattService();
+ long timestampNanos = service.parseTimestampNanos(new byte[] {
+ -54, 7 });
+ assertEquals(99700000000L, timestampNanos);
+ }
+
+}
diff --git a/tests/src/com/android/bluetooth/util/NumberUtilsTest.java b/tests/src/com/android/bluetooth/util/NumberUtilsTest.java
new file mode 100644
index 0000000..a2fa1aa
--- /dev/null
+++ b/tests/src/com/android/bluetooth/util/NumberUtilsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.util;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Tests for {@link NumberUtils}.
+ */
+public class NumberUtilsTest extends AndroidTestCase {
+
+ @SmallTest
+ public static void testUnsignedByteToInt() {
+ assertEquals(0, NumberUtils.unsignedByteToInt((byte) 0));
+ assertEquals(19, NumberUtils.unsignedByteToInt((byte) 19));
+ assertEquals(154, NumberUtils.unsignedByteToInt((byte) 154));
+ }
+
+ @SmallTest
+ public void testLittleEndianByteArrayToInt() {
+ assertEquals(1, NumberUtils.littleEndianByteArrayToInt(new byte[] {
+ 1 }));
+ assertEquals(513, NumberUtils.littleEndianByteArrayToInt(new byte[] {
+ 1, 2 }));
+ assertEquals(197121, NumberUtils.littleEndianByteArrayToInt(new byte[] {
+ 1, 2, 3 }));
+ }
+}