Merge tag 'android-7.1.0_r4' of https://android.googlesource.com/platform/packages/apps/Bluetooth into aosp-7.1
Android 7.1.0 release 4
Change-Id: I44595dac56b16a9b3c24a9d0c3afdc69abae5f92
diff --git a/jni/com_android_bluetooth_hfp.cpp b/jni/com_android_bluetooth_hfp.cpp
index 963949f..983ab2f 100644
--- a/jni/com_android_bluetooth_hfp.cpp
+++ b/jni/com_android_bluetooth_hfp.cpp
@@ -50,6 +50,8 @@
static jmethodID method_onAtClcc;
static jmethodID method_onUnknownAt;
static jmethodID method_onKeyPressed;
+static jmethodID method_onAtBind;
+static jmethodID method_onAtBiev;
static const bthf_interface_t *sBluetoothHfpInterface = NULL;
static jobject mCallbacksObj = NULL;
@@ -377,6 +379,34 @@
sCallbackEnv->DeleteLocalRef(addr);
}
+static void at_bind_callback(char *at_string, bt_bdaddr_t *bd_addr) {
+ CHECK_CALLBACK_ENV
+
+ jbyteArray addr = marshall_bda(bd_addr);
+ if (addr == NULL)
+ return;
+
+ jstring js_at_string = sCallbackEnv->NewStringUTF(at_string);
+
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind, js_at_string, addr);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+
+ sCallbackEnv->DeleteLocalRef(js_at_string);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
+
+static void at_biev_callback(bthf_hf_ind_type_t ind_id, int ind_value, bt_bdaddr_t *bd_addr) {
+ CHECK_CALLBACK_ENV
+
+ jbyteArray addr = marshall_bda(bd_addr);
+ if (addr == NULL)
+ return;
+
+ sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id, (jint)ind_value, addr);
+ checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
+ sCallbackEnv->DeleteLocalRef(addr);
+}
+
static bthf_callbacks_t sBluetoothHfpCallbacks = {
sizeof(sBluetoothHfpCallbacks),
connection_state_callback,
@@ -395,6 +425,8 @@
at_cops_callback,
at_clcc_callback,
unknown_at_callback,
+ at_bind_callback,
+ at_biev_callback,
key_pressed_callback
};
@@ -417,6 +449,8 @@
method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
method_onUnknownAt = env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
+ method_onAtBind = env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V");
+ method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V");
ALOGI("%s: succeeds", __FUNCTION__);
}
@@ -678,6 +712,30 @@
return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
+static jboolean bindResponseNative(JNIEnv *env,jobject object,
+ jint ind_id, jboolean ind_status,
+ jbyteArray address) {
+ ALOGI("%s: sBluetoothHfpInterface: %p", __FUNCTION__, sBluetoothHfpInterface);
+
+ if (!sBluetoothHfpInterface)
+ return JNI_FALSE;
+
+ jbyte *addr = env->GetByteArrayElements(address, NULL);
+ if (!addr) {
+ jniThrowIOException(env, EINVAL);
+ return JNI_FALSE;
+ }
+
+ bt_status_t status = sBluetoothHfpInterface->bind_response((bthf_hf_ind_type_t) ind_id,
+ ind_status ? BTHF_HF_IND_ENABLED : BTHF_HF_IND_DISABLED,
+ (bt_bdaddr_t *)addr);
+
+ if (status != BT_STATUS_SUCCESS)
+ ALOGE("%s: Failed bind_response, status: %d", __FUNCTION__, status);
+
+ env->ReleaseByteArrayElements(address, addr, 0);
+ return (status == BT_STATUS_SUCCESS ? JNI_TRUE : JNI_FALSE);
+}
static jboolean atResponseStringNative(JNIEnv *env, jobject object, jstring response_str,
jbyteArray address) {
@@ -820,6 +878,7 @@
{"notifyDeviceStatusNative", "(IIII)Z", (void *) notifyDeviceStatusNative},
{"copsResponseNative", "(Ljava/lang/String;[B)Z", (void *) copsResponseNative},
{"cindResponseNative", "(IIIIIII[B)Z", (void *) cindResponseNative},
+ {"bindResponseNative", "(IZ[B)Z", (void *)bindResponseNative},
{"atResponseStringNative", "(Ljava/lang/String;[B)Z", (void *) atResponseStringNative},
{"atResponseCodeNative", "(II[B)Z", (void *)atResponseCodeNative},
{"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z", (void *) clccResponseNative},
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 53ce817..ed31bb1 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -27,7 +27,7 @@
<string name="airplane_error_msg" msgid="8698965595254137230">"No pots utilitzar Bluetooth en mode d\'avió."</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
<string name="bt_enable_line1" msgid="7203551583048149">"Per utilitzar serveis Bluetooth, primer cal que activeu el Bluetooth."</string>
- <string name="bt_enable_line2" msgid="4341936569415937994">"Voleu activar el Bluetooth ara?"</string>
+ <string name="bt_enable_line2" msgid="4341936569415937994">"Vols activar el Bluetooth ara?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"Cancel·la"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Activa"</string>
<string name="incoming_file_confirm_title" msgid="8139874248612182627">"Transferència del fitxer"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 9e390dd..bdffe86 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -99,7 +99,7 @@
<string name="status_no_sd_card" product="default" msgid="5760944071743325592">"هیچ کارت SD موجود نیست. برای ذخیره فایلهای منتقل شده، یک کارت SD در گوشی قرار دهید."</string>
<string name="status_connection_error" msgid="947681831523219891">"اتصال ناموفق بود."</string>
<string name="status_protocol_error" msgid="3245444473429269539">"درخواست به درستی انجام نمیشود."</string>
- <string name="status_unknown_error" msgid="8156660554237824912">"خطای ناشناخته."</string>
+ <string name="status_unknown_error" msgid="8156660554237824912">"خطای ناشناس."</string>
<string name="btopp_live_folder" msgid="7967791481444474554">"بلوتوث دریافت شد"</string>
<string name="download_success" msgid="7036160438766730871">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> دریافت کامل شد."</string>
<string name="upload_success" msgid="4014469387779648949">"<xliff:g id="FILE_SIZE">%1$s</xliff:g> ارسال کامل شد."</string>
diff --git a/res/values-fa/strings_pbap.xml b/res/values-fa/strings_pbap.xml
index 945d442..0667ebb 100644
--- a/res/values-fa/strings_pbap.xml
+++ b/res/values-fa/strings_pbap.xml
@@ -5,7 +5,7 @@
<string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"به کلید جلسه بلوتوث نیاز است"</string>
<string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"هنگام پذیرش اتصال به %1$s وقفه زمانی ایجاد شده است"</string>
<string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"هنگام ورود کلید جلسه با %1$s وقفه زمانی ایجاد شده است"</string>
- <string name="auth_notif_ticker" msgid="1575825798053163744">"درخواست راستیآزمایی Obex"</string>
+ <string name="auth_notif_ticker" msgid="1575825798053163744">"درخواست احراز هویت Obex"</string>
<string name="auth_notif_title" msgid="7599854855681573258">"کلید جلسه"</string>
<string name="auth_notif_message" msgid="6667218116427605038">"تایپ کلید جلسه برای %1$s"</string>
<string name="defaultname" msgid="4821590500649090078">"کیت خودرو"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index ed242a9..efef63b 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -23,8 +23,8 @@
<string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
<string name="unknown_device" msgid="9221903979877041009">"Անհայտ սարք"</string>
<string name="unknownNumber" msgid="4994750948072751566">"Անհայտ"</string>
- <string name="airplane_error_title" msgid="2683839635115739939">"Ինքնաթիռային ռեժիմ"</string>
- <string name="airplane_error_msg" msgid="8698965595254137230">"Դուք չեք կարող օգտվել Bluetooth-ից ինքնաթիռային ռեժիմում:"</string>
+ <string name="airplane_error_title" msgid="2683839635115739939">"Ինքնաթիռի ռեժիմ"</string>
+ <string name="airplane_error_msg" msgid="8698965595254137230">"Դուք չեք կարող օգտվել Bluetooth-ից Ինքնաթիռի ռեժիմում:"</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
<string name="bt_enable_line1" msgid="7203551583048149">"Bluetooth ծառայություններից օգտվելու համար նախ պետք է միացնեք Bluetooth-ը:"</string>
<string name="bt_enable_line2" msgid="4341936569415937994">"Միացնե՞լ Bluetooth-ը հիմա:"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index a7ae86f..69cf285 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Pasiekti atsisiuntimo tvarkyklę."</string>
+ <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Pasiekti atsisiuntimo tvarkytuvę."</string>
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Leidžiama programai pasiekti „BluetoothShare“ tvarkyklę ir naudoti ją failams perkelti."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Į baltąjį sąrašą įtraukto „Bluetooth“ įrenginio prieiga."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Leidžiama programai laikinai į baltąjį sąrašą įtraukti „Bluetooth“ įrenginį, suteikiant jam galimybę siųsti failus į šį įrenginį be naudotojo patvirtinimo."</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index a71b298..2bbb010 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -19,7 +19,7 @@
<string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ဒေါင်းလုပ်မန်နေဂျာကို အသုံးပြုနိုင်မည်"</string>
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"အပလီကေးရှင်းအား ဘလူးတုသ်မျှဝေမှု မန်နေဂျာကို အသုံးပြုခွင့်ပေးပြီး ဖိုင်လွှဲရန် အသုံးပြုပါ"</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"ဘလူးတုသ်ယာယီခွင့်ပြုစာရင်းကို အသုံးပြုခွင့်"</string>
- <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"အပလီကေးရှင်းအား ဘလူးတုသ်စက်ကို ယာယီခွင့်ပြုစာရင်းထဲ ထည့်ရန်ခွင့်ပြုကာ အသုံးပြုသူ၏ အတည်ပြုချက်မရယူပဲ ဖိုင်များကို စက်ထဲသို့ ပို့ခွင့်ပြုမည်"</string>
+ <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"အက်ပ်အား ဘလူးတုသ်စက်ကို ယာယီခွင့်ပြုစာရင်းထဲ ထည့်ရန်ခွင့်ပြုကာ အသုံးပြုသူ၏ အတည်ပြုချက်မရယူပဲ ဖိုင်များကို စက်ထဲသို့ ပို့ခွင့်ပြုမည်"</string>
<string name="bt_share_picker_label" msgid="6268100924487046932">"ဘလူးတုသ်"</string>
<string name="unknown_device" msgid="9221903979877041009">"မသိသော စက်"</string>
<string name="unknownNumber" msgid="4994750948072751566">"အကြောင်းအရာ မသိရှိ"</string>
@@ -28,7 +28,7 @@
<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>
@@ -120,12 +120,12 @@
<string name="transfer_menu_clear_all" msgid="790017462957873132">"စာရင်းကို ဖယ်ရှားရန်"</string>
<string name="transfer_menu_open" msgid="3368984869083107200">"ဖွင့်ရန်"</string>
<string name="transfer_menu_clear" msgid="5854038118831427492">"စာရင်းမှ ရှင်းပစ်မည်"</string>
- <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"ဖယ်ရှားရန်"</string>
- <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"သိမ်းဆည်းရန်"</string>
- <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"မလုပ်တော့ပါ"</string>
+ <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"ရှင်းရန်"</string>
+ <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"သိမ်းရန်"</string>
+ <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"မလုပ်တော့"</string>
<string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"ဘလူးတုသ်မှ မျှဝေလိုသော အကောင့်များကို ရွေးပါ။ ချိတ်ဆက်သည့်အခါ အကောင့်များအား ဝင်ခွင့်ပြုဖို့ လက်ခံပေးရပါလိမ့်ဦးမည်။"</string>
<string name="bluetooth_map_settings_count" msgid="4557473074937024833">"ကျန်နေသည့် အပေါက်များ:"</string>
- <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"အက်ပ် အိုင်ကွန်"</string>
+ <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"အပလီကေးရှင်း သင်္ကေတ"</string>
<string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ဘလူးတုသ် စာ မျှဝေရေး ဆက်တင်များ"</string>
<string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"ရွေးထားသည့် အကောင့်ကို မရွေးနိုင်ပါ။ သုည အပေါက်များ ကျန်နေ"</string>
<string name="bluetooth_connected" msgid="6718623220072656906">"ဘလူးတုသ်အသံ ချိတ်ဆက်ပြီးပါပြီ"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 9a4a536..85423d7 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -82,7 +82,7 @@
<string name="bt_toast_2" msgid="8602553334099066582">"Fișierul nu poate fi primit."</string>
<string name="bt_toast_3" msgid="6707884165086862518">"Primirea fișierului de la „<xliff:g id="SENDER">%1$s</xliff:g>” a fost anulată"</string>
<string name="bt_toast_4" msgid="4678812947604395649">"Se trimite fișierul către „<xliff:g id="RECIPIENT">%1$s</xliff:g>”"</string>
- <string name="bt_toast_5" msgid="2846870992823019494">"Se trimit <xliff:g id="NUMBER">%1$s</xliff:g> (de) fișiere către „<xliff:g id="RECIPIENT">%2$s</xliff:g>”"</string>
+ <string name="bt_toast_5" msgid="2846870992823019494">"Se trimit <xliff:g id="NUMBER">%1$s</xliff:g> fișiere către „<xliff:g id="RECIPIENT">%2$s</xliff:g>”"</string>
<string name="bt_toast_6" msgid="1855266596936622458">"Trimiterea fișierului către „<xliff:g id="RECIPIENT">%1$s</xliff:g>” a fost anulată"</string>
<string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"Nu există spațiu suficient pe stocarea USB pentru a salva fișierul de la „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
<string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"Nu există suficient spațiu pe cardul SD pentru a salva fișierul de la „<xliff:g id="SENDER">%1$s</xliff:g>”"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index dcbe208..90e513d 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -35,14 +35,25 @@
of the location permissions. -->
<bool name="strict_location_check">true</bool>
- <!-- Specifies the min/max connection interval parameters for high priority
- and low power GATT configurations. These values are in multiples of
- 1.25ms. -->
+ <!-- Specifies the min/max connection interval parameters for high priority,
+ balanced and low power GATT configurations. These values are in
+ multiples of 1.25ms. -->
<integer name="gatt_high_priority_min_interval">9</integer>
<integer name="gatt_high_priority_max_interval">12</integer>
+ <!-- Default specs recommended interval is 30 (24 * 1.25) -> 50 (40 * 1.25)
+ ms. -->
+ <integer name="gatt_balanced_priority_min_interval">24</integer>
+ <integer name="gatt_balanced_priority_max_interval">40</integer>
<integer name="gatt_low_power_min_interval">80</integer>
<integer name="gatt_low_power_max_interval">100</integer>
+ <!-- Specifies latency parameters for high priority, balanced and low power
+ GATT configurations. These values represents the number of packets a
+ slave device is allowed to skip. -->
+ <integer name="gatt_high_priority_latency">0</integer>
+ <integer name="gatt_balanced_priority_latency">0</integer>
+ <integer name="gatt_low_power_latency">2</integer>
+
<bool name="headset_client_initial_audio_route_allowed">true</bool>
<!-- For AVRCP absolute volume feature. If the threshold is non-zero,
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java
index 297bae3..82ecf73 100644
--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -5435,6 +5435,7 @@
ProfileService.println(sb, "mVolCmdAdjustInProgress: " + deviceFeatures[i].mVolCmdAdjustInProgress);
ProfileService.println(sb, "mAbsVolRetryTimes: " + deviceFeatures[i].mAbsVolRetryTimes);
ProfileService.println(sb, "mSkipAmount: " + mSkipAmount);
+ ProfileService.println(sb, "mVolumeMapping: " + deviceFeatures[i].mVolumeMapping.toString());
if (mMediaController != null)
ProfileService.println(sb, "mMediaSession pkg: " +
mMediaController.getPackageName());
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index fb40cbb..6f0d47f 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -538,7 +538,10 @@
registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP));
mProfileObserver = new ProfileObserver(getApplicationContext(), this, new Handler());
mProfileObserver.start();
+
mVendor.init();
+
+ setAdapterService(this);
}
@Override
@@ -597,9 +600,6 @@
// Ignore.
}
- //FIXME: Set static instance here???
- setAdapterService(this);
-
//Start Gatt service
setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
}
diff --git a/src/com/android/bluetooth/btservice/RemoteDevices.java b/src/com/android/bluetooth/btservice/RemoteDevices.java
index 19089a7..2545bd4 100644
--- a/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -45,13 +45,13 @@
private static final int UUID_INTENT_DELAY = 6000;
private static final int MESSAGE_UUID_INTENT = 1;
- private HashMap<BluetoothDevice, DeviceProperties> mDevices;
+ private HashMap<String, DeviceProperties> mDevices;
RemoteDevices(AdapterService service) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mAdapterService = service;
mSdpTracker = new ArrayList<BluetoothDevice>();
- mDevices = new HashMap<BluetoothDevice, DeviceProperties>();
+ mDevices = new HashMap<String, DeviceProperties>();
}
@@ -70,16 +70,15 @@
DeviceProperties getDeviceProperties(BluetoothDevice device) {
synchronized (mDevices) {
- return mDevices.get(device);
+ return mDevices.get(device.getAddress());
}
}
BluetoothDevice getDevice(byte[] address) {
synchronized (mDevices) {
- for (BluetoothDevice dev : mDevices.keySet()) {
- if (dev.getAddress().equals(Utils.getAddressStringFromByte(address))) {
- return dev;
- }
+ DeviceProperties p = mDevices.get(Utils.getAddressStringFromByte(address));
+ if (p != null) {
+ return p.getDevice();
}
}
return null;
@@ -88,10 +87,9 @@
DeviceProperties addDeviceProperties(byte[] address) {
synchronized (mDevices) {
DeviceProperties prop = new DeviceProperties();
- BluetoothDevice device =
- mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
+ prop.mDevice = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
prop.mAddress = address;
- mDevices.put(device, prop);
+ mDevices.put(Utils.getAddressStringFromByte(address), prop);
return prop;
}
}
@@ -105,6 +103,7 @@
private int mDeviceType;
private String mAlias;
private int mBondState;
+ private BluetoothDevice mDevice;
DeviceProperties() {
mBondState = BluetoothDevice.BOND_NONE;
@@ -147,6 +146,15 @@
}
/**
+ * @return the mDevice
+ */
+ BluetoothDevice getDevice() {
+ synchronized (mObject) {
+ return mDevice;
+ }
+ }
+
+ /**
* @return mRssi
*/
short getRssi() {
diff --git a/src/com/android/bluetooth/gatt/AdvertiseManager.java b/src/com/android/bluetooth/gatt/AdvertiseManager.java
index 058bf4b..3fb4aa9 100644
--- a/src/com/android/bluetooth/gatt/AdvertiseManager.java
+++ b/src/com/android/bluetooth/gatt/AdvertiseManager.java
@@ -194,7 +194,7 @@
private void handleStartAdvertising(AdvertiseClient client) {
Utils.enforceAdminPermission(mService);
int clientIf = client.clientIf;
- if (mAdvertiseClients.contains(clientIf)) {
+ if (mAdvertiseClients.contains(client)) {
postCallback(clientIf, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
return;
}
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index e1e5e57..0316b42 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -1627,12 +1627,11 @@
void connectionParameterUpdate(int clientIf, String address, int connectionPriority) {
enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- // Default spec recommended interval is 30->50 ms
- int minInterval = 24; // 24 * 1.25ms = 30ms
- int maxInterval = 40; // 40 * 1.25ms = 50ms
+ int minInterval;
+ int maxInterval;
// Slave latency
- int latency = 0;
+ int latency;
// Link supervision timeout is measured in N * 10ms
int timeout = 2000; // 20s
@@ -1642,12 +1641,22 @@
case BluetoothGatt.CONNECTION_PRIORITY_HIGH:
minInterval = getResources().getInteger(R.integer.gatt_high_priority_min_interval);
maxInterval = getResources().getInteger(R.integer.gatt_high_priority_max_interval);
+ latency = getResources().getInteger(R.integer.gatt_high_priority_latency);
break;
case BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER:
minInterval = getResources().getInteger(R.integer.gatt_low_power_min_interval);
maxInterval = getResources().getInteger(R.integer.gatt_low_power_max_interval);
- latency = 2;
+ latency = getResources().getInteger(R.integer.gatt_low_power_latency);
+ break;
+
+ default:
+ // Using the values for CONNECTION_PRIORITY_BALANCED.
+ minInterval =
+ getResources().getInteger(R.integer.gatt_balanced_priority_min_interval);
+ maxInterval =
+ getResources().getInteger(R.integer.gatt_balanced_priority_max_interval);
+ latency = getResources().getInteger(R.integer.gatt_balanced_priority_latency);
break;
}
diff --git a/src/com/android/bluetooth/gatt/HandleMap.java b/src/com/android/bluetooth/gatt/HandleMap.java
index 4a20639..27a7a71 100644
--- a/src/com/android/bluetooth/gatt/HandleMap.java
+++ b/src/com/android/bluetooth/gatt/HandleMap.java
@@ -69,7 +69,6 @@
this.type = type;
this.handle = handle;
this.uuid = uuid;
- this.instance = instance;
this.serviceHandle = serviceHandle;
}
@@ -78,7 +77,6 @@
this.type = type;
this.handle = handle;
this.uuid = uuid;
- this.instance = instance;
this.serviceHandle = serviceHandle;
this.charHandle = charHandle;
}
diff --git a/src/com/android/bluetooth/gatt/ScanManager.java b/src/com/android/bluetooth/gatt/ScanManager.java
index b20a54f..bb45bf7 100644
--- a/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/src/com/android/bluetooth/gatt/ScanManager.java
@@ -242,7 +242,7 @@
Message msg = mHandler.obtainMessage(MSG_SCAN_TIMEOUT);
msg.obj = client;
// Only one timeout message should exist at any time
- mHandler.removeMessages(SCAN_TIMEOUT_MS);
+ mHandler.removeMessages(MSG_SCAN_TIMEOUT);
mHandler.sendMessageDelayed(msg, SCAN_TIMEOUT_MS);
}
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetHalConstants.java b/src/com/android/bluetooth/hfp/HeadsetHalConstants.java
index 0742917..dee633f 100644
--- a/src/com/android/bluetooth/hfp/HeadsetHalConstants.java
+++ b/src/com/android/bluetooth/hfp/HeadsetHalConstants.java
@@ -64,4 +64,8 @@
final static int CALL_STATE_INCOMING = 4;
final static int CALL_STATE_WAITING = 5;
final static int CALL_STATE_IDLE = 6;
+
+ // Match up with bthf_hf_ind_type_t of bt_hf.h
+ final static int HF_INDICATOR_ENHANCED_DRIVER_SAFETY = 1;
+ final static int HF_INDICATOR_BATTERY_LEVEL_STATUS = 2;
}
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index c61cb3c..09d2e32 100644
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -331,6 +331,12 @@
if (service == null) return false;
return service.disableWBS();
}
+
+ public void bindResponse(int ind_id, boolean ind_status) {
+ HeadsetService service = getService();
+ if (service == null) return;
+ service.bindResponse(ind_id, ind_status);
+ }
};
//API methods
@@ -639,6 +645,24 @@
return true;
}
+ private boolean bindResponse(int ind_id, boolean ind_status) {
+ for (BluetoothDevice device: getConnectedDevices()) {
+ int connectionState = mStateMachine.getConnectionState(device);
+ if (connectionState != BluetoothProfile.STATE_CONNECTED &&
+ connectionState != BluetoothProfile.STATE_CONNECTING) {
+ continue;
+ }
+ if (DBG) Log.d("Bind Response sent for", device.getAddress());
+ Message msg = mStateMachine.obtainMessage(HeadsetStateMachine.BIND_RESPONSE);
+ msg.obj = device;
+ msg.arg1 = ind_id;
+ msg.arg2 = (ind_status == true) ? 1 : 0;
+ mStateMachine.sendMessage(msg);
+ return true;
+ }
+ return false;
+ }
+
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index bcc560d..d8f3e47 100755
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -70,6 +70,7 @@
import com.android.internal.util.StateMachine;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -110,10 +111,12 @@
static final int ENABLE_WBS = 16;
static final int DISABLE_WBS = 17;
- static final int UPDATE_A2DP_PLAY_STATE = 18;
- static final int UPDATE_A2DP_CONN_STATE = 19;
- static final int QUERY_PHONE_STATE_AT_SLC = 20;
- static final int UPDATE_CALL_TYPE = 21;
+ static final int BIND_RESPONSE = 18;
+
+ static final int UPDATE_A2DP_PLAY_STATE = 28;
+ static final int UPDATE_A2DP_CONN_STATE = 29;
+ static final int QUERY_PHONE_STATE_AT_SLC = 30;
+ static final int UPDATE_CALL_TYPE = 31;
private static final int STACK_EVENT = 101;
private static final int DIALING_OUT_TIMEOUT = 102;
@@ -627,6 +630,15 @@
}
processConnectionEvent(event.valueInt, event.device);
break;
+
+ case EVENT_TYPE_BIND:
+ processAtBind(event.valueString, event.device);
+ break;
+
+ case EVENT_TYPE_BIEV:
+ processAtBiev(event.valueInt, event.valueInt2, event.device);
+ break;
+
default:
Log.e(TAG, "Unexpected event: " + event.type);
break;
@@ -1069,6 +1081,13 @@
case UPDATE_CALL_TYPE:
processIntentUpdateCallType((Intent) message.obj);
break;
+ case BIND_RESPONSE:
+ {
+ BluetoothDevice device = (BluetoothDevice) message.obj;
+ bindResponseNative((int)message.arg1, ((message.arg2 == 1) ? true : false),
+ getByteAddress(device));
+ }
+ break;
case START_VR_TIMEOUT:
{
BluetoothDevice device = (BluetoothDevice) message.obj;
@@ -1149,6 +1168,12 @@
case EVENT_TYPE_KEY_PRESSED:
processKeyPressed(event.device);
break;
+ case EVENT_TYPE_BIND:
+ processAtBind(event.valueString, event.device);
+ break;
+ case EVENT_TYPE_BIEV:
+ processAtBiev(event.valueInt, event.valueInt2, event.device);
+ break;
default:
Log.e(TAG, "Unknown stack event: " + event.type);
break;
@@ -1649,6 +1674,12 @@
case EVENT_TYPE_KEY_PRESSED:
processKeyPressed(event.device);
break;
+ case EVENT_TYPE_BIND:
+ processAtBind(event.valueString, event.device);
+ break;
+ case EVENT_TYPE_BIEV:
+ processAtBiev(event.valueInt, event.valueInt2, event.device);
+ break;
default:
Log.e(TAG, "Unknown stack event: " + event.type);
break;
@@ -2067,6 +2098,12 @@
case EVENT_TYPE_KEY_PRESSED:
processKeyPressed(event.device);
break;
+ case EVENT_TYPE_BIND:
+ processAtBind(event.valueString, event.device);
+ break;
+ case EVENT_TYPE_BIEV:
+ processAtBiev(event.valueInt, event.valueInt2, event.device);
+ break;
default:
Log.e(TAG, "Unexpected event: " + event.type);
break;
@@ -3740,6 +3777,65 @@
if (DBG) Log.d(TAG, "Exit processKeyPressed()");
}
+ private void sendIndicatorIntent(BluetoothDevice device, int ind_id, String ind_value)
+ {
+ Intent intent = new Intent(BluetoothHeadset.ACTION_HF_INDICATORS_VALUE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, ind_id);
+ if (ind_value != null)
+ intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, ind_value);
+
+ mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
+ }
+
+ private void processAtBind( String at_string, BluetoothDevice device) {
+ log("processAtBind processAtBind: " + at_string);
+
+ // Parse the AT String to find the Indicator Ids that are supported
+ int ind_id = 0;
+ int iter = 0;
+ int iter1 = 0;
+
+ while (iter < at_string.length()) {
+ iter1 = findChar(',', at_string, iter);
+ String id = at_string.substring(iter, iter1);
+
+ try {
+ ind_id = new Integer(id);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+
+ switch (ind_id) {
+ case HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY :
+ log("Send Broadcast intent for the" +
+ "Enhanced Driver Safety indicator.");
+ sendIndicatorIntent(device, ind_id, null);
+ break;
+ case HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS :
+ log("Send Broadcast intent for the" +
+ "Battery Level indicator.");
+ sendIndicatorIntent(device, ind_id, null);
+ break;
+ default:
+ log("Invalid HF Indicator Received");
+ break;
+ }
+
+ iter = iter1 + 1; // move past comma
+ }
+ }
+
+ private void processAtBiev( int ind_id, int ind_value, BluetoothDevice device) {
+ log(" Process AT + BIEV Command : " + ind_id + ", " + ind_value);
+
+ String ind_value_str = Integer.toString(ind_value);
+
+ Intent intent = new Intent(BluetoothHeadset.ACTION_HF_INDICATORS_VALUE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ sendIndicatorIntent(device, ind_id, ind_value_str);
+ }
+
private void onConnectionStateChanged(int state, byte[] address) {
if (DBG) Log.d(TAG, "Enter onConnectionStateChanged()");
StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
@@ -3887,6 +3983,21 @@
if (DBG) Log.d(TAG, "Exit onKeyPressed()");
}
+ private void onATBind(String atString, byte[] address) {
+ StackEvent event = new StackEvent(EVENT_TYPE_BIND);
+ event.valueString = atString;
+ event.device = getDevice(address);
+ sendMessage(STACK_EVENT, event);
+ }
+
+ private void onATBiev(int ind_id, int ind_value, byte[] address) {
+ StackEvent event = new StackEvent(EVENT_TYPE_BIEV);
+ event.valueInt = ind_id;
+ event.valueInt2 = ind_value;
+ event.device = getDevice(address);
+ sendMessage(STACK_EVENT, event);
+ }
+
private void processIntentBatteryChanged(Intent intent) {
if (DBG) Log.d(TAG, "Enter processIntentBatteryChanged()");
int batteryLevel = intent.getIntExtra("level", -1);
@@ -4095,6 +4206,8 @@
final private static int EVENT_TYPE_UNKNOWN_AT = 15;
final private static int EVENT_TYPE_KEY_PRESSED = 16;
final private static int EVENT_TYPE_WBS = 17;
+ final private static int EVENT_TYPE_BIND = 18;
+ final private static int EVENT_TYPE_BIEV = 19;
private class StackEvent {
int type = EVENT_TYPE_NONE;
@@ -4125,6 +4238,7 @@
private native boolean cindResponseNative(int service, int numActive, int numHeld,
int callState, int signal, int roam,
int batteryCharge, byte[] address);
+ private native boolean bindResponseNative(int ind_id, boolean ind_status, byte[] address);
private native boolean notifyDeviceStatusNative(int networkState, int serviceType, int signal,
int batteryCharge);
diff --git a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
old mode 100644
new mode 100755
index 05806fa..76ef463
--- a/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
+++ b/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java
@@ -339,6 +339,7 @@
Log.d(TAG, "Enter sendCallChangedIntent()");
Log.d(TAG, "sendCallChangedIntent " + c);
Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CALL_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(BluetoothHeadsetClient.EXTRA_CALL, c);
mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
Log.d(TAG, "Exit sendCallChangedIntent()");
diff --git a/src/com/android/bluetooth/map/BluetoothMapContent.java b/src/com/android/bluetooth/map/BluetoothMapContent.java
index 2370a4d..4f42bfb 100755
--- a/src/com/android/bluetooth/map/BluetoothMapContent.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContent.java
@@ -950,10 +950,14 @@
address = c.getString(c.getColumnIndex(Sms.ADDRESS));
}
if ((address == null) && msgType == Sms.MESSAGE_TYPE_DRAFT) {
- //Fetch address for Drafts folder from "canonical_address" table
+ // Fetch address for Drafts folder from "canonical_address" table
int threadIdInd = c.getColumnIndex(Sms.THREAD_ID);
String threadIdStr = c.getString(threadIdInd);
- address = getCanonicalAddressSms(mResolver, Integer.valueOf(threadIdStr));
+ // If a draft message has no recipient, it has no thread ID
+ // hence threadIdStr could possibly be null
+ if (threadIdStr != null) {
+ address = getCanonicalAddressSms(mResolver, Integer.valueOf(threadIdStr));
+ }
if(V) Log.v(TAG, "threadId = " + threadIdStr + " adress:" + address +"\n");
}
} else if (fi.mMsgType == FilterInfo.TYPE_MMS) {
@@ -961,7 +965,7 @@
address = getAddressMms(mResolver, id, MMS_TO);
} else if (fi.mMsgType == FilterInfo.TYPE_EMAIL) {
/* Might be another way to handle addresses */
- address = getRecipientAddressingEmail(e, c,fi);
+ address = getRecipientAddressingEmail(e, c, fi);
}
if (V) Log.v(TAG, "setRecipientAddressing: " + address);
if(address == null)
@@ -1603,7 +1607,8 @@
} else if (BluetoothMapContract.FOLDER_NAME_SENT.equalsIgnoreCase(folder)) {
where = Sms.TYPE + " = 2 AND " + Sms.THREAD_ID + " <> -1";
} else if (BluetoothMapContract.FOLDER_NAME_DRAFT.equalsIgnoreCase(folder)) {
- where = Sms.TYPE + " = 3 AND " + Sms.THREAD_ID + " <> -1";
+ where = Sms.TYPE + " = 3 AND " +
+ "(" + Sms.THREAD_ID + " IS NULL OR " + Sms.THREAD_ID + " <> -1 )";
} else if (BluetoothMapContract.FOLDER_NAME_DELETED.equalsIgnoreCase(folder)) {
where = Sms.THREAD_ID + " = -1";
}
@@ -1620,7 +1625,8 @@
} else if (BluetoothMapContract.FOLDER_NAME_SENT.equalsIgnoreCase(folder)) {
where = Mms.MESSAGE_BOX + " = 2 AND " + Mms.THREAD_ID + " <> -1";
} else if (BluetoothMapContract.FOLDER_NAME_DRAFT.equalsIgnoreCase(folder)) {
- where = Mms.MESSAGE_BOX + " = 3 AND " + Mms.THREAD_ID + " <> -1";
+ where = Mms.MESSAGE_BOX + " = 3 AND " +
+ "(" + Mms.THREAD_ID + " IS NULL OR " + Mms.THREAD_ID + " <> -1 )";
} else if (BluetoothMapContract.FOLDER_NAME_DELETED.equalsIgnoreCase(folder)) {
where = Mms.THREAD_ID + " = -1";
}
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index 878f5be..6edc556 100755
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -37,6 +37,7 @@
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
+import android.os.UserManager;
import android.provider.Telephony;
import android.provider.Telephony.Mms;
import android.provider.Telephony.MmsSms;
@@ -1184,9 +1185,10 @@
private void initMsgList() throws RemoteException {
if (V) Log.d(TAG, "initMsgList");
+ UserManager manager = UserManager.get(mContext);
+ if (manager == null || manager.isUserUnlocked()) return;
- if(mEnableSmsMms) {
-
+ if (mEnableSmsMms) {
HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>();
Cursor c = mResolver.query(Sms.CONTENT_URI,
@@ -2361,21 +2363,19 @@
/* Approved MAP spec errata 3445 states that read status initiated
* by the MCE shall change the MSE read status. */
if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) {
- Uri uri = Sms.Inbox.CONTENT_URI;
+ Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle);
ContentValues contentValues = new ContentValues();
contentValues.put(Sms.READ, statusValue);
contentValues.put(Sms.SEEN, statusValue);
- String where = Sms._ID+"="+handle;
String values = contentValues.toString();
- if (D) Log.d(TAG, " -> SMS Uri: " + uri.toString() +
- " Where " + where + " values " + values);
+ if (D) Log.d(TAG, " -> SMS Uri: " + uri.toString() + " values " + values);
synchronized(getMsgListSms()) {
Msg msg = getMsgListSms().get(handle);
if(msg != null) { // This will always be the case
msg.flagRead = statusValue;
}
}
- count = mResolver.update(uri, contentValues, where, null);
+ count = mResolver.update(uri, contentValues, null, null);
if (D) Log.d(TAG, " -> "+count +" rows updated!");
} else if (type == TYPE.MMS) {
@@ -2455,8 +2455,16 @@
long folderId = -1;
if (recipientList == null) {
- if (D) Log.d(TAG, "empty recipient list");
- return -1;
+ if (folderElement.getName().equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) {
+ BluetoothMapbMessage.vCard empty =
+ new BluetoothMapbMessage.vCard("", "", null, null, 0);
+ recipientList = new ArrayList<BluetoothMapbMessage.vCard>();
+ recipientList.add(empty);
+ Log.w(TAG, "Added empty recipient to draft message");
+ } else {
+ Log.e(TAG, "Trying to send a message with no recipients");
+ return -1;
+ }
}
if ( msg.getType().equals(TYPE.EMAIL) ) {
@@ -3331,6 +3339,8 @@
private void resendPendingMessages() {
/* Send pending messages in outbox */
String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX;
+ UserManager manager = UserManager.get(mContext);
+ if (manager == null || !manager.isUserUnlocked()) return;
Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null,
null);
try {
diff --git a/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
index 88e5605..832060e 100644
--- a/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
+++ b/src/com/android/bluetooth/map/BluetoothMapMessageListingElement.java
@@ -27,6 +27,7 @@
import android.util.Xml;
import com.android.bluetooth.map.BluetoothMapUtils.TYPE;
+import com.android.bluetooth.util.Interop;
public class BluetoothMapMessageListingElement
implements Comparable<BluetoothMapMessageListingElement> {
@@ -276,9 +277,17 @@
BluetoothMapUtils.getMapHandle(mCpHandle, mType));
if(mSubject != null){
String stripped = BluetoothMapUtils.stripInvalidChars(mSubject);
+
+ if (Interop.matchByAddress(Interop.INTEROP_MAP_ASCIIONLY,
+ BluetoothMapService.getRemoteDevice().getAddress())) {
+ stripped = stripped.replaceAll("[\\P{ASCII}&\"><]", "");
+ if (stripped.isEmpty()) stripped = "---";
+ }
+
xmlMsgElement.attribute(null, "subject",
stripped.substring(0, stripped.length() < 256 ? stripped.length() : 256));
}
+
if(mDateTime != 0)
xmlMsgElement.attribute(null, "datetime", this.getDateTimeString());
if(mSenderName != null)
diff --git a/src/com/android/bluetooth/map/BluetoothMapObexServer.java b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
index f0c26b0..00b2902 100644
--- a/src/com/android/bluetooth/map/BluetoothMapObexServer.java
+++ b/src/com/android/bluetooth/map/BluetoothMapObexServer.java
@@ -24,6 +24,7 @@
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
+import android.os.UserManager;
import android.text.format.DateUtils;
import android.util.Log;
@@ -402,6 +403,11 @@
return ResponseCodes.OBEX_HTTP_OK;
}
+ private boolean isUserUnlocked() {
+ UserManager manager = UserManager.get(mContext);
+ return (manager == null || manager.isUserUnlocked());
+ }
+
@Override
public int onPut(final Operation op) {
if (D) Log.d(TAG, "onPut(): enter");
@@ -431,26 +437,34 @@
return ResponseCodes.OBEX_HTTP_OK;
}
return updateInbox();
- }else if(type.equals(TYPE_SET_NOTIFICATION_REGISTRATION)) {
+ } else if (type.equals(TYPE_SET_NOTIFICATION_REGISTRATION)) {
if(V) {
Log.d(TAG,"TYPE_SET_NOTIFICATION_REGISTRATION: NotificationStatus: "
+ appParams.getNotificationStatus());
}
return mObserver.setNotificationRegistration(appParams.getNotificationStatus());
- }else if(type.equals(TYPE_SET_NOTIFICATION_FILTER)) {
+ } else if (type.equals(TYPE_SET_NOTIFICATION_FILTER)) {
if(V) {
Log.d(TAG,"TYPE_SET_NOTIFICATION_FILTER: NotificationFilter: "
+ appParams.getNotificationFilter());
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
mObserver.setNotificationFilter(appParams.getNotificationFilter());
return ResponseCodes.OBEX_HTTP_OK;
- } else if(type.equals(TYPE_SET_MESSAGE_STATUS)) {
+ } else if (type.equals(TYPE_SET_MESSAGE_STATUS)) {
if(V) {
Log.d(TAG,"TYPE_SET_MESSAGE_STATUS: " +
"StatusIndicator: " + appParams.getStatusIndicator()
+ ", StatusValue: " + appParams.getStatusValue()
+ ", ExtentedData: " + "" ); // TODO: appParams.getExtendedImData());
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
return setMessageStatus(name, appParams);
} else if (type.equals(TYPE_MESSAGE)) {
if(V) {
@@ -458,6 +472,10 @@
+ ", retry: " + appParams.getRetry()
+ ", charset: " + appParams.getCharset());
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
return pushMessage(op, name, appParams, mMessageVersion);
} else if (type.equals(TYPE_SET_OWNER_STATUS)) {
if(V) {
@@ -916,6 +934,10 @@
Log.d(TAG,"FilterConvoId = " + ((tmpLongLong == null) ? "" :
Long.toHexString(tmpLongLong.getLeastSignificantBits()) ) );
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
// Block until all packets have been send.
return sendMessageListingRsp(op, appParams, name);
@@ -930,6 +952,10 @@
Log.d(TAG,"FilterReadStatus = " + appParams.getFilterReadStatus());
Log.d(TAG,"FilterRecipient = " + appParams.getFilterRecipient());
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
// Block until all packets have been send.
return sendConvoListingRsp(op, appParams,name);
} else if (type.equals(TYPE_GET_MAS_INSTANCE_INFORMATION)) {
@@ -947,6 +973,10 @@
", Charset = " + appParams.getCharset() +
", FractionRequest = " + appParams.getFractionRequest());
}
+ if (!isUserUnlocked()) {
+ Log.e(TAG, "Storage locked, " + type + " failed");
+ return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
+ }
// Block until all packets have been send.
return sendGetMessageRsp(op, name, appParams, mMessageVersion);
} else {
@@ -1028,8 +1058,8 @@
return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
Log.v(TAG,"sendMessageListingRsp: has sms " + folderToList.hasSmsMmsContent() +
- "has email " + folderToList.hasEmailContent() +
- "has IM " + folderToList.hasImContent() );
+ ", has email " + folderToList.hasEmailContent() +
+ ", has IM " + folderToList.hasImContent() );
}
try {
diff --git a/src/com/android/bluetooth/map/BluetoothMapService.java b/src/com/android/bluetooth/map/BluetoothMapService.java
index 552bb09..cce506c 100755
--- a/src/com/android/bluetooth/map/BluetoothMapService.java
+++ b/src/com/android/bluetooth/map/BluetoothMapService.java
@@ -135,7 +135,7 @@
private HashMap<BluetoothMapAccountItem, BluetoothMapMasInstance> mMasInstanceMap =
new HashMap<BluetoothMapAccountItem, BluetoothMapMasInstance>(1);
- private static BluetoothDevice mRemoteDevice = null;
+ private static BluetoothDevice mRemoteDevice = null; // The remote connected device - protect access
private ArrayList<BluetoothMapAccountItem> mEnabledAccounts = null;
private static String sRemoteDeviceName = null;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java b/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java
index 2a51aa0..38873da 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java
@@ -42,31 +42,31 @@
if (D) Log.d(TAG, "No device attached to handover intent.");
return;
}
+
+ String mimeType = intent.getType();
+ ArrayList<Uri> uris = new ArrayList<Uri>();
if (action.equals(Constants.ACTION_HANDOVER_SEND)) {
- String type = intent.getType();
Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM);
- if (stream != null && type != null) {
- // Save type/stream, will be used when adding transfer
- // session to DB.
- BluetoothOppManager.getInstance(context).saveSendingFileInfo(type,
- stream.toString(), true);
- } else {
- if (D) Log.d(TAG, "No mimeType or stream attached to handover request");
- }
+ if (stream != null) uris.add(stream);
} else if (action.equals(Constants.ACTION_HANDOVER_SEND_MULTIPLE)) {
- ArrayList<Uri> uris = new ArrayList<Uri>();
- String mimeType = intent.getType();
uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
- if (mimeType != null && uris != null) {
- BluetoothOppManager.getInstance(context).saveSendingFileInfo(mimeType,
- uris, true);
- } else {
- if (D) Log.d(TAG, "No mimeType or stream attached to handover request");
- return;
- }
}
- // we already know where to send to
- BluetoothOppManager.getInstance(context).startTransfer(device);
+
+ if (mimeType != null && uris != null && !uris.isEmpty()) {
+ final String finalType = mimeType;
+ final ArrayList<Uri> finalUris = uris;
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ BluetoothOppManager.getInstance(context).saveSendingFileInfo(finalType,
+ finalUris, true);
+ BluetoothOppManager.getInstance(context).startTransfer(device);
+ }
+ });
+ t.start();
+ } else {
+ if (D) Log.d(TAG, "No mimeType or stream attached to handover request");
+ return;
+ }
} else if (action.equals(Constants.ACTION_WHITELIST_DEVICE)) {
BluetoothDevice device =
(BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
diff --git a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
index 0f23bd3..59e7848 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
@@ -476,13 +476,13 @@
outputStream.write(buffer, 0, readLength);
position += readLength;
+ /* check remote accept or reject */
+ responseCode = putOperation.getResponseCode();
mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
synchronized (this) {
mWaitingForRemote = false;
}
- /* check remote accept or reject */
- responseCode = putOperation.getResponseCode();
if (responseCode == ResponseCodes.OBEX_HTTP_CONTINUE
|| responseCode == ResponseCodes.OBEX_HTTP_OK) {
@@ -595,7 +595,7 @@
} finally {
try {
if (outputStream != null) {
- outputStream.close();
+ outputStream.close();
}
// Close InputStream and remove SendFileInfo from map
diff --git a/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
index 2a9cadb..f60f06c 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
@@ -123,6 +123,7 @@
Log.e(TAG, "generateFileInfo: " + e);
return new BluetoothOppSendFileInfo(fileName, contentType, length, null, 0);
}
+
if (metadataCursor != null) {
try {
if (metadataCursor.moveToFirst()) {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppUtility.java b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
index 65588f1..15f4a89 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppUtility.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppUtility.java
@@ -374,6 +374,9 @@
static void putSendFileInfo(Uri uri, BluetoothOppSendFileInfo sendFileInfo) {
if (D) Log.d(TAG, "putSendFileInfo: uri=" + uri + " sendFileInfo=" + sendFileInfo);
+ if (sendFileInfo == BluetoothOppSendFileInfo.SEND_FILE_INFO_ERROR) {
+ Log.e(TAG, "putSendFileInfo: bad sendFileInfo, URI: " + uri);
+ }
sSendFileMap.put(uri, sendFileInfo);
}
diff --git a/src/com/android/bluetooth/pan/PanService.java b/src/com/android/bluetooth/pan/PanService.java
index 05f92ff..6a43b93 100755
--- a/src/com/android/bluetooth/pan/PanService.java
+++ b/src/com/android/bluetooth/pan/PanService.java
@@ -440,8 +440,8 @@
if (prevState == state) return;
if (remote_role == BluetoothPan.LOCAL_PANU_ROLE) {
if (state == BluetoothProfile.STATE_CONNECTED) {
- if((!mTetherOn)||(local_role == BluetoothPan.LOCAL_PANU_ROLE)){
- if(DBG) Log.d(TAG, "handlePanDeviceStateChange BT tethering is off/Local role"
+ if ((!mTetherOn) || (local_role == BluetoothPan.LOCAL_PANU_ROLE)) {
+ if (DBG) Log.d(TAG, "handlePanDeviceStateChange BT tethering is off/Local role"
+ " is PANU drop the connection");
mPanDevices.remove(device);
disconnectPanNative(Utils.getByteAddress(device));
diff --git a/src/com/android/bluetooth/util/Interop.java b/src/com/android/bluetooth/util/Interop.java
new file mode 100644
index 0000000..4861c15
--- /dev/null
+++ b/src/com/android/bluetooth/util/Interop.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bluetooth.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Centralized Bluetooth Interoperability workaround utilities and database.
+ * This is the Java version. An analagous native version can be found
+ * in /system/bt/devices/include/interop_database.h.
+ */
+public class Interop {
+
+ /**
+ * Simple interop entry consisting of a workarond id (see below)
+ * and a (partial or complete) Bluetooth device address string
+ * to match against.
+ */
+ private static class Entry {
+ String address;
+ int workaround_id;
+
+ public Entry(int workaround_id, String address) {
+ this.workaround_id = workaround_id;
+ this.address = address;
+ }
+ }
+
+ /**
+ * The actual "database" of interop entries.
+ */
+ private static List<Entry> entries = null;
+
+ /**
+ * Workaround ID for deivces which do not accept non-ASCII
+ * characters in SMS messages.
+ */
+ public static final int INTEROP_MAP_ASCIIONLY = 1;
+
+ /**
+ * Initializes the interop datbase with the relevant workaround
+ * entries.
+ * When adding entries, please provide a description for each
+ * device as to what problem the workaround addresses.
+ */
+ private static void lazyInitInteropDatabase() {
+ if (entries != null) return;
+ entries = new ArrayList<Entry>();
+
+ /** Mercedes Benz NTG 4.5 does not handle non-ASCII characters in SMS */
+ entries.add(new Entry(INTEROP_MAP_ASCIIONLY, "00:26:e8"));
+ }
+
+ /**
+ * Checks wheter a given device identified by |address| is a match
+ * for a given workaround identified by |workaround_id|.
+ * Return true if the address matches, false otherwise.
+ */
+ public static boolean matchByAddress(int workaround_id, String address) {
+ if (address == null || address.isEmpty()) return false;
+
+ lazyInitInteropDatabase();
+ for (Entry entry : entries) {
+ if (entry.workaround_id == workaround_id &&
+ entry.address.startsWith(address.toLowerCase())) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}