diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6de6114759a..99272a426b9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -58,7 +58,6 @@
-
@@ -227,9 +226,6 @@
android:excludeFromRecents="true"
android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
android:enabled="@bool/profile_supported_pbap">
-
-
-
prepareCodecPreferences(
static void initNative(JNIEnv* env, jobject object,
jint maxConnectedAudioDevices,
- jobjectArray codecConfigArray) {
+ jobjectArray codecConfigArray,
+ jobjectArray codecConfigOffload) {
std::unique_lock interface_lock(interface_mutex);
std::unique_lock callbacks_lock(callbacks_mutex);
@@ -306,8 +307,10 @@ static void initNative(JNIEnv* env, jobject object,
std::vector codec_priorities =
prepareCodecPreferences(env, object, codecConfigArray);
+ std::vector offload_codec_supported =
+ prepareCodecPreferences(env, object, codecConfigOffload);
bt_status_t status = sBluetoothA2dpInterface->init(
- &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities);
+ &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities, offload_codec_supported);
if (status != BT_STATUS_SUCCESS) {
ALOGE("%s: Failed to initialize Bluetooth A2DP, status: %d", __func__,
status);
@@ -475,7 +478,7 @@ static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object,
static JNINativeMethod sMethods[] = {
{"classInitNative", "()V", (void*)classInitNative},
- {"initNative", "(I[Landroid/bluetooth/BluetoothCodecConfig;)V",
+ {"initNative", "(I[Landroid/bluetooth/BluetoothCodecConfig;[Landroid/bluetooth/BluetoothCodecConfig;)V",
(void*)initNative},
{"cleanupNative", "()V", (void*)cleanupNative},
{"connectA2dpNative", "([B)Z", (void*)connectA2dpNative},
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index 452151547fd..6e16cc113bc 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -1166,11 +1166,24 @@ void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
}
static void gattSetScanParametersNative(JNIEnv* env, jobject object,
- jint client_if, jint scan_interval_unit,
- jint scan_window_unit) {
+ jint client_if, jint scan_phy,
+ jintArray scan_interval_unit,
+ jintArray scan_window_unit) {
+ std::vector scan_interval = {0,0};
+ std::vector scan_window = {0,0};
if (!sGattIf) return;
+
+ int scan_int_cnt = env->GetArrayLength(scan_interval_unit);
+ if(scan_int_cnt > 0) {
+ env->GetIntArrayRegion(scan_interval_unit, 0, scan_int_cnt, (jint *)&scan_interval[0]);
+ }
+
+ int scan_window_cnt = env->GetArrayLength(scan_window_unit);
+ if(scan_window_cnt > 0) {
+ env->GetIntArrayRegion(scan_window_unit, 0, scan_window_cnt, (jint *)&scan_window[0]);
+ }
sGattIf->scanner->SetScanParameters(
- scan_interval_unit, scan_window_unit,
+ scan_phy, scan_interval, scan_window,
base::Bind(&set_scan_params_cmpl_cb, client_if));
}
@@ -2129,7 +2142,7 @@ static JNINativeMethod sScanMethods[] = {
(void*)gattClientScanFilterClearNative},
{"gattClientScanFilterEnableNative", "(IZ)V",
(void*)gattClientScanFilterEnableNative},
- {"gattSetScanParametersNative", "(III)V",
+ {"gattSetScanParametersNative", "(II[I[I)V",
(void*)gattSetScanParametersNative},
};
diff --git a/res/values-az/strings_map.xml b/res/values-az/strings_map.xml
deleted file mode 100644
index 0b8584e1207..00000000000
--- a/res/values-az/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "%1$s üçün seans açarı daxil edin"
- "Bluetooth seans açarı tələb olunur"
- "%1$s ilə bağlantı qəbul edərkən fasilə yarandı"
- "%1$s ilə seans açarını daxil edərkən fasilə yarandı"
- "Obex təsdiqləmə sorğusu"
- "Seans Açarı"
- "%1$s üçün seans açarı daxil edin"
- "Maşın dəsti"
- "Naməlum ad"
- "Mənim adım"
- "000000"
-
diff --git a/res/values-et/strings_map.xml b/res/values-et/strings_map.xml
deleted file mode 100644
index 8fe16424b2b..00000000000
--- a/res/values-et/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "Sisestage seansivõti seadmele %1$s"
- "Vajalik Bluetoothi seansivõti"
- "Esines ajalõpp ühenduse aktsepteerimiseks seadmega %1$s"
- "Esines ajalõpp seansivõtme sisestamiseks seadmele %1$s"
- "Obexi autentimise taotlus"
- "Seansivõti"
- "Sisestage seansivõti seadmele %1$s"
- "Autokomplekt"
- "Tundmatu nimi"
- "Minu nimi"
- "000000"
-
diff --git a/res/values-hy/strings_map.xml b/res/values-hy/strings_map.xml
deleted file mode 100644
index 91f2078be59..00000000000
--- a/res/values-hy/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"
- "Պահանջվում է Bluetooth-ի աշխատաշրջանի բանալի"
- "%1$s-ի հետ կապի ընդունման ժամանակը սպառվեց"
- "%1$s-ով աշխատաշրջանի բանալու մուտքագրման ժամանակը սպառվեց"
- "Կասեցնել նույնականացման հարցումը"
- "Աշխատաշրջանի բանալի"
- "Մուտքագրեք աշխատաշրջանի բանալին %1$s-ի համար"
- "Carkit"
- "Անհայտ անուն"
- "Իմ անունը"
- "000000"
-
diff --git a/res/values-ka/strings_map.xml b/res/values-ka/strings_map.xml
deleted file mode 100644
index 8e645c4f64a..00000000000
--- a/res/values-ka/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "სესიის გასაღები %1$s-ისთვის"
- "აუცილებელია Bluetooth სესიის გასაღები"
- "%1$s-თან კავშირის მიღების დრო ამოიწურა"
- "%1$s-თან სესიის გასაღების შეყვანის დრო ამოიწურა"
- "Obex ავთენტიფიკაციის მოთხოვნა"
- "სესიის გასაღები"
- "სესიის გასაღები %1$s-ისთვის"
- "მანქანის ნაკრები"
- "უცნობი სახელი"
- "ჩემი სახელი"
- "000000"
-
diff --git a/res/values-km/strings_map.xml b/res/values-km/strings_map.xml
deleted file mode 100644
index 8118669863b..00000000000
--- a/res/values-km/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "បញ្ចូលសោសម័យសម្រាប់ %1$s"
- "បានទាមទារសោសម័យប៊្លូធូស"
- "អស់ពេលវេលាក្នុងការទទួលយកការតភ្ជាប់ជាមួយ %1$s"
- "អស់ពេលដើម្បីបញ្ចូលសោសម័យជាមួយ %1$s"
- "សំណើការផ្ទៀងផ្ទាត់ Obex"
- "សោសម័យ"
- "បញ្ចូលសោសម័យសម្រាប់ %1$s"
- "Carkit"
- "មិនស្គាល់ឈ្មោះ"
- "ឈ្មោះរបស់ខ្ញុំ"
- "000000"
-
diff --git a/res/values-lo/strings_map.xml b/res/values-lo/strings_map.xml
deleted file mode 100644
index dd3a2889ebf..00000000000
--- a/res/values-lo/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"
- "ຕ້ອງມີ Bluetooth ລະຫັດເຊສຊັນ"
- "ໝົດເວລາທີ່ຈະຮັບການເຊື່ອມຕໍ່ກັບ %1$s"
- "ເກີດໝົດເວລາກ່ອນທີ່ຈະໃສ່ລະຫັດເຊສຊັນກັບ %1$s"
- "ການຮ້ອງຂໍພິສູດຢືນຢັນໂຕ Obex"
- "ກະແຈເຊສຊັສ"
- "ພິມລະຫັດເຊສຊັນສຳລັບ %1$s"
- "Carkit"
- "ບໍ່ຮູ້ຊື່"
- "ຊື່ຂອງຂ້ອຍ"
- "000000"
-
diff --git a/res/values-mn/strings_map.xml b/res/values-mn/strings_map.xml
deleted file mode 100644
index 45fc07dd457..00000000000
--- a/res/values-mn/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "%1$s-н горимын түлхүүрийг оруулна уу"
- "Блютүүт горимын түлхүүр шаардлагатай"
- "%1$s-тай холболт хийхийг зөвшөөрөх явцад хугацаа хэтэрсэн байна"
- "%1$s-д горимын түлхүүр оруулах явцад хугацаа хэтэрсэн байна"
- "Obex гэрчлэлтийн хүсэлт"
- "Горимын Түлхүүр"
- "%1$s-н горимын түлхүүрийг оруулна уу"
- "Carkit"
- "Тодорхойгүй нэр"
- "Миний нэр"
- "000000"
-
diff --git a/res/values-ms/strings_map.xml b/res/values-ms/strings_map.xml
deleted file mode 100644
index afc98d73cfe..00000000000
--- a/res/values-ms/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "Taipkan kunci sesi untuk %1$s"
- "Kunci sesi Bluetooth diperlukan"
- "Berlaku tamat masa semasa menerima sambungan dengan %1$s"
- "Tamat masa berlaku semasa memasukkan kunci sesi dengan %1$s"
- "Permintaan pengesahan Obex"
- "Kunci Sesi"
- "Taipkan kunci sesi untuk %1$s"
- "Kit kereta"
- "Nama tidak diketahui"
- "Nama saya"
- "000000"
-
diff --git a/res/values-ne/strings_map.xml b/res/values-ne/strings_map.xml
deleted file mode 100644
index 7584c1ec350..00000000000
--- a/res/values-ne/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"
- "ब्लूटूथ सत्र कुञ्जी आवश्यक"
- "%1$s सँग जडान स्वीकार गर्न समय सकियो"
- "%1$s का साथ सत्र कुञ्जी इनपुट गर्ने समय सकियो"
- "Obex प्रमाणिकरण अनुरोध"
- "सत्र कुञ्जी"
- "%1$s का लागि सत्र कुञ्जी टाइप गर्नुहोस्"
- "Carkit"
- "अज्ञात नाम"
- "मेरो नाम"
- "००००००"
-
diff --git a/res/values-si/strings_map.xml b/res/values-si/strings_map.xml
deleted file mode 100644
index 31c2febc809..00000000000
--- a/res/values-si/strings_map.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- "%1$s සඳහා සැසි යතුර ටයිප් කරන්න"
- "බ්ලූටූත් සැසි යතුර අවශ්යයි"
- "%1$s හා සම්බන්ධය පිළිගැනීමට කාල නිමාවක් විය"
- "%1$s හා සැසි යතුර ආදානය කිරීමට කාල නිමාවක් විය"
- "Obex සත්යාපන ඉල්ලීම"
- "සැසි යතුර"
- "%1$s සඳහා සැසි යතුර ටයිප් කරන්න"
- "Carkit"
- "නොදන්නා නමකි"
- "මගේ නම"
- "000000"
-
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 0204f983064..b7dcaf2a99c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -178,9 +178,9 @@
Stopped sending file to \u0022%1$s\u0022
- There isn\'t enough space in USB storage to save the file from \u0022%1$s\u0022
+ There isn\'t enough space in USB storage to save the file.
- There isn\'t enough space on the SD card to save the file from \u0022%1$s\u0022
+ There isn\'t enough space on the SD card to save the file.
Space needed: %1$s
Too many requests are being processed. Try again later.
@@ -228,13 +228,13 @@
Clear
- bluetooth_content_share
+ bluetooth_content_share
-
+
-
+
Now Playing
diff --git a/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java b/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
index 8127e766b95..5db50f3845a 100644
--- a/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
+++ b/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
+import android.provider.Settings;
import android.util.Log;
import com.android.bluetooth.R;
@@ -104,11 +105,22 @@ void enableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentCo
return;
}
+ boolean sbc_priority = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SBC_HD_PRIORITY, 0) != 0;
+
// Set the mandatory codec's priority to default, and remove the rest
for (int i = 0; i < codecConfigArray.length; i++) {
BluetoothCodecConfig codecConfig = codecConfigArray[i];
- if (!codecConfig.isMandatoryCodec()) {
+ if (codecConfig != null && !codecConfig.isMandatoryCodec()) {
codecConfigArray[i] = null;
+ } else if (sbc_priority) {
+ // Rebuild SBC selectable codec with Dual Channel (SBC HD audio)
+ codecConfigArray[i] = new BluetoothCodecConfig(
+ BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, mA2dpSourceCodecPrioritySbc,
+ BluetoothCodecConfig.SAMPLE_RATE_NONE,
+ BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
+ BluetoothCodecConfig.CHANNEL_MODE_DUAL_CHANNEL, 0 /* codecSpecific1 */,
+ 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */);
}
}
@@ -128,7 +140,7 @@ void disableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentC
// Set the mandatory codec's priority to highest, and remove the rest
for (int i = 0; i < codecConfigArray.length; i++) {
BluetoothCodecConfig codecConfig = codecConfigArray[i];
- if (codecConfig.isMandatoryCodec()) {
+ if (codecConfig != null && codecConfig.isMandatoryCodec()) {
codecConfig.setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST);
} else {
codecConfigArray[i] = null;
@@ -210,6 +222,31 @@ private BluetoothCodecConfig[] assignCodecConfigPriorities() {
mA2dpSourceCodecPriorityLdac = value;
}
+ // Set highest codec priority in the end, so that it can override xml values
+ int codec_priority = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.A2DP_SOURCE_CODEC_PRIORITY, 0);
+
+ switch (codec_priority) {
+ case 0:
+ default:
+ break;
+ case 1:
+ mA2dpSourceCodecPrioritySbc = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
+ break;
+ case 2:
+ mA2dpSourceCodecPriorityAac = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
+ break;
+ case 3:
+ mA2dpSourceCodecPriorityAptx = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
+ break;
+ case 4:
+ mA2dpSourceCodecPriorityAptxHd = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
+ break;
+ case 5:
+ mA2dpSourceCodecPriorityLdac = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
+ break;
+ }
+
BluetoothCodecConfig codecConfig;
BluetoothCodecConfig[] codecConfigArray =
new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX];
diff --git a/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
index cbdc28a6061..fc08032bbd8 100644
--- a/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
+++ b/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
@@ -75,8 +75,9 @@ public static A2dpNativeInterface getInstance() {
* @param codecConfigPriorities an array with the codec configuration
* priorities to configure.
*/
- public void init(int maxConnectedAudioDevices, BluetoothCodecConfig[] codecConfigPriorities) {
- initNative(maxConnectedAudioDevices, codecConfigPriorities);
+ public void init(int maxConnectedAudioDevices, BluetoothCodecConfig[] codecConfigPriorities,
+ BluetoothCodecConfig[] codecConfigOffload) {
+ initNative(maxConnectedAudioDevices, codecConfigPriorities, codecConfigOffload);
}
/**
@@ -205,7 +206,8 @@ private void onCodecConfigChanged(byte[] address,
// Native methods that call into the JNI interface
private static native void classInitNative();
private native void initNative(int maxConnectedAudioDevices,
- BluetoothCodecConfig[] codecConfigPriorities);
+ BluetoothCodecConfig[] codecConfigPriorities,
+ BluetoothCodecConfig[] codecConfigOffload);
private native void cleanupNative();
private native boolean connectA2dpNative(byte[] address);
private native boolean disconnectA2dpNative(byte[] address);
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index cebf7676be1..e18656a21aa 100644
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -122,8 +122,12 @@ protected boolean start() {
mA2dpCodecConfig = new A2dpCodecConfig(this, mA2dpNativeInterface);
// Step 5: Initialize native interface
+ List codecConfigOffload = mAudioManager.getHwOffloadEncodingFormatsSupportedForA2DP();
+ BluetoothCodecConfig[] offloadCodecConfig = new BluetoothCodecConfig[codecConfigOffload.size()];
+ offloadCodecConfig = codecConfigOffload.toArray(offloadCodecConfig);
mA2dpNativeInterface.init(mMaxConnectedAudioDevices,
- mA2dpCodecConfig.codecConfigPriorities());
+ mA2dpCodecConfig.codecConfigPriorities(),
+ offloadCodecConfig);
// Step 6: Check if A2DP is in offload mode
mA2dpOffloadEnabled = mAdapterService.isA2dpOffloadEnabled();
@@ -1035,7 +1039,13 @@ public void updateOptionalCodecsSupport(BluetoothDevice device) {
BluetoothCodecStatus codecStatus = sm.getCodecStatus();
if (codecStatus != null) {
for (BluetoothCodecConfig config : codecStatus.getCodecsSelectableCapabilities()) {
- if (config.isMandatoryCodec()) {
+ boolean isMandatoryCodecWithDualChannel = (config.isMandatoryCodec()
+ && (config.getChannelMode() & config.CHANNEL_MODE_DUAL_CHANNEL)
+ == config.CHANNEL_MODE_DUAL_CHANNEL);
+ if (isMandatoryCodecWithDualChannel) {
+ hasMandatoryCodec = true;
+ supportsOptional = true;
+ } else if (config.isMandatoryCodec()) {
hasMandatoryCodec = true;
} else {
supportsOptional = true;
@@ -1052,11 +1062,11 @@ public void updateOptionalCodecsSupport(BluetoothDevice device) {
}
if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN
- || supportsOptional != (previousSupport
- == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) {
+ || previousSupport == BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED) {
setSupportsOptionalCodecs(device, supportsOptional);
}
- if (supportsOptional) {
+ if (supportsOptional
+ || previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED) {
int enabled = getOptionalCodecsEnabled(device);
switch (enabled) {
case BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN:
diff --git a/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
index e2ae494a62a..91d577c7547 100644
--- a/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
+++ b/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
@@ -68,6 +68,8 @@ class ListCallback implements MediaPlayerList.MediaUpdateCallback,
MediaPlayerList.FolderUpdateCallback {
@Override
public void run(MediaData data) {
+ if (mNativeInterface == null) return;
+
boolean metadata = !Objects.equals(mCurrentData.metadata, data.metadata);
boolean state = !MediaPlayerWrapper.playstateEquals(mCurrentData.state, data.state);
boolean queue = !Objects.equals(mCurrentData.queue, data.queue);
@@ -84,6 +86,8 @@ public void run(MediaData data) {
@Override
public void run(boolean availablePlayers, boolean addressedPlayers,
boolean uids) {
+ if (mNativeInterface == null) return;
+
mNativeInterface.sendFolderUpdate(availablePlayers, addressedPlayers, uids);
}
}
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index a65bcfdf97f..418f79f0206 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -1215,6 +1215,17 @@ public boolean isBondingInitiatedLocally(BluetoothDevice device) {
return service.isBondingInitiatedLocally(device);
}
+ @Override
+ public void setBondingInitiatedLocally(BluetoothDevice device, boolean localInitiated) {
+ // don't check caller, may be called from system UI
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.setBondingInitiatedLocally(device,localInitiated);
+ return;
+ }
+
@Override
public long getSupportedProfiles() {
AdapterService service = getService();
@@ -1519,6 +1530,14 @@ public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) {
return service.sdpSearch(device, uuid);
}
+ public boolean isTwsPlusDevice(BluetoothDevice device) {
+ return false;
+ }
+
+ public String getTwsPlusPeerAddress(BluetoothDevice device) {
+ return null;
+ }
+
@Override
public int getBatteryLevel(BluetoothDevice device) {
if (!Utils.checkCaller()) {
@@ -1726,6 +1745,16 @@ public void onLeServiceUp() {
service.onLeServiceUp();
}
+ @Override
+ public void updateQuietModeStatus(boolean quietMode) {
+ AdapterService service = getService();
+ if (service == null) {
+ return;
+ }
+ service.updateQuietModeStatus(quietMode);
+ }
+
+
@Override
public void onBrEdrDown() {
AdapterService service = getService();
@@ -1735,6 +1764,15 @@ public void onBrEdrDown() {
service.onBrEdrDown();
}
+ public int setSocketOpt(int type, int channel, int optionName, byte [] optionVal,
+ int optionLen) {
+ return -1;
+ }
+
+ public int getSocketOpt(int type, int channel, int optionName, byte [] optionVal) {
+ return -1;
+ }
+
@Override
public void dump(FileDescriptor fd, String[] args) {
PrintWriter writer = new PrintWriter(new FileOutputStream(fd));
@@ -2126,6 +2164,17 @@ boolean isBondingInitiatedLocally(BluetoothDevice device) {
return deviceProp.isBondingInitiatedLocally();
}
+ void setBondingInitiatedLocally(BluetoothDevice device, boolean localInitiated) {
+ enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
+ if (deviceProp == null) {
+ return;
+ }
+ Log.w(TAG," localInitiated " + localInitiated);
+ deviceProp.setBondingInitiatedLocally(localInitiated);
+ return;
+ }
+
long getSupportedProfiles() {
return Config.getSupportedProfilesBitMask();
}
@@ -2548,6 +2597,12 @@ public int getTotalNumOfTrackableAdvertisements() {
return mAdapterProperties.getTotalNumOfTrackableAdvertisements();
}
+ void updateQuietModeStatus(boolean quietMode) {
+ debugLog("updateQuietModeStatus()-updateQuietModeStatus called with quiet mode status:"
+ + quietMode);
+ mQuietmode = quietMode;
+ }
+
void onLeServiceUp() {
mAdapterStateMachine.sendMessage(AdapterState.USER_TURN_ON);
}
diff --git a/src/com/android/bluetooth/gatt/ScanManager.java b/src/com/android/bluetooth/gatt/ScanManager.java
index 073697821c2..5adb8945ec2 100644
--- a/src/com/android/bluetooth/gatt/ScanManager.java
+++ b/src/com/android/bluetooth/gatt/ScanManager.java
@@ -20,6 +20,7 @@
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanSettings;
@@ -83,7 +84,8 @@ public class ScanManager {
// Timeout for each controller operation.
private static final int OPERATION_TIME_OUT_MILLIS = 500;
- private int mLastConfiguredScanSetting = Integer.MIN_VALUE;
+ private int mLastConfiguredScanSettingLE1M = Integer.MIN_VALUE;
+ private int mLastConfiguredScanSettingLECoded = Integer.MIN_VALUE;
// Scan parameters for batch scan.
private BatchScanParams mBatchScanParms;
@@ -117,6 +119,18 @@ private class UidImportance {
}
}
+ private class PhyInfo {
+ public int scanPhy;
+ public int scanModeLE1M;
+ public int scanModeLECoded;
+
+ PhyInfo(int scanPhy, int scanModeLE1M, int scanModeLECoded) {
+ this.scanPhy = scanPhy;
+ this.scanModeLE1M = scanModeLE1M;
+ this.scanModeLECoded = scanModeLECoded;
+ }
+ };
+
ScanManager(GattService service) {
mRegularScanClients =
Collections.newSetFromMap(new ConcurrentHashMap());
@@ -576,40 +590,85 @@ void configureRegularScanParams() {
if (DBG) {
Log.d(TAG, "configureRegularScanParams() - queue=" + mRegularScanClients.size());
}
- int curScanSetting = Integer.MIN_VALUE;
+ int curScanSettingLE1M = Integer.MIN_VALUE;
+ int curScanSettingLECoded = Integer.MIN_VALUE;
+ int scanPhy = BluetoothDevice.PHY_LE_1M;
ScanClient client = getAggressiveClient(mRegularScanClients);
+ PhyInfo phyInfoResult = getPhyInfo(mRegularScanClients);
+ boolean scanModeChanged = false;
+ int scanWindowLE1M = Integer.MIN_VALUE;
+ int scanIntervalLE1M = Integer.MIN_VALUE;
+ int scanWindowLECoded = Integer.MIN_VALUE;
+ int scanIntervalLECoded = Integer.MIN_VALUE;
+ int[] scanInterval = new int[2];
+ int[] scanWindow = new int[2];
+ int phyCnt = 0;
+
+
if (client != null) {
- curScanSetting = client.settings.getScanMode();
+ curScanSettingLE1M = phyInfoResult.scanModeLE1M;
+ curScanSettingLECoded = phyInfoResult.scanModeLECoded;
+ scanPhy = phyInfoResult.scanPhy;
}
if (DBG) {
- Log.d(TAG, "configureRegularScanParams() - ScanSetting Scan mode=" + curScanSetting
- + " mLastConfiguredScanSetting=" + mLastConfiguredScanSetting);
+ Log.d(TAG, "configureRegularScanParams() - ScanSetting LE 1M Scan mode=" + curScanSettingLE1M
+ + "ScanSetting LE Coded Scan mode=" + curScanSettingLECoded
+ + " mLastConfiguredScanSettingLE1M=" + mLastConfiguredScanSettingLE1M
+ + " mLastConfiguredScanSettingLECoded=" + mLastConfiguredScanSettingLECoded
+ + "scanPhy=" + scanPhy);
+ }
+
+ if ((curScanSettingLE1M != Integer.MIN_VALUE
+ && curScanSettingLE1M != ScanSettings.SCAN_MODE_OPPORTUNISTIC)) {
+ if (curScanSettingLE1M != mLastConfiguredScanSettingLE1M) {
+ scanModeChanged = true;
+ ScanSettings settings = new ScanSettings.Builder().setScanMode(curScanSettingLE1M).build();
+ scanWindowLE1M = getScanWindowMillis(settings);
+ scanIntervalLE1M = getScanIntervalMillis(settings);
+ // convert scanWindow and scanInterval from ms to LE scan units(0.625ms)
+ scanWindow[phyCnt] = Utils.millsToUnit(scanWindowLE1M);
+ scanInterval[phyCnt] = Utils.millsToUnit(scanIntervalLE1M);
+ phyCnt++;
+ }
}
-
- if (curScanSetting != Integer.MIN_VALUE
- && curScanSetting != ScanSettings.SCAN_MODE_OPPORTUNISTIC) {
- if (curScanSetting != mLastConfiguredScanSetting) {
- int scanWindow = getScanWindowMillis(client.settings);
- int scanInterval = getScanIntervalMillis(client.settings);
+ else {
+ mLastConfiguredScanSettingLE1M = curScanSettingLE1M;
+ if (DBG) {
+ Log.d(TAG, "configureRegularScanParams() - queue emtpy, scan stopped");
+ }
+ }
+ if((curScanSettingLECoded != Integer.MIN_VALUE
+ && curScanSettingLECoded != ScanSettings.SCAN_MODE_OPPORTUNISTIC)) {
+ if (curScanSettingLECoded != mLastConfiguredScanSettingLECoded) {
+ scanModeChanged = true;
+ ScanSettings settings = new ScanSettings.Builder().setScanMode(curScanSettingLECoded).build();
+ scanWindowLECoded = getScanWindowMillis(settings);
+ scanIntervalLECoded = getScanIntervalMillis(settings);
// convert scanWindow and scanInterval from ms to LE scan units(0.625ms)
- scanWindow = Utils.millsToUnit(scanWindow);
- scanInterval = Utils.millsToUnit(scanInterval);
- gattClientScanNative(false);
- if (DBG) {
- Log.d(TAG, "configureRegularScanParams - scanInterval = " + scanInterval
- + "configureRegularScanParams - scanWindow = " + scanWindow);
- }
- gattSetScanParametersNative(client.scannerId, scanInterval, scanWindow);
- gattClientScanNative(true);
- mLastConfiguredScanSetting = curScanSetting;
+ scanWindow[phyCnt] = Utils.millsToUnit(scanWindowLECoded);
+ scanInterval[phyCnt] = Utils.millsToUnit(scanIntervalLECoded);
}
- } else {
- mLastConfiguredScanSetting = curScanSetting;
+ }
+ else {
+ mLastConfiguredScanSettingLECoded = curScanSettingLECoded;
if (DBG) {
Log.d(TAG, "configureRegularScanParams() - queue emtpy, scan stopped");
}
}
+ if(scanModeChanged) {
+ gattClientScanNative(false);
+ if (DBG) {
+ Log.d(TAG, "configureRegularScanParams - scanInterval LE 1M = " + scanIntervalLE1M
+ + "configureRegularScanParams - scanWindow LE 1M= " + scanWindowLE1M
+ + "configureRegularScanParams - scanWindow LE Coded= " + scanWindowLECoded
+ + "configureRegularScanParams - scanWindow LE Coded= " + scanWindowLECoded);
+ }
+ gattSetScanParametersNative(client.scannerId, scanPhy, scanInterval, scanWindow);
+ gattClientScanNative(true);
+ mLastConfiguredScanSettingLE1M = curScanSettingLE1M;
+ mLastConfiguredScanSettingLECoded = curScanSettingLECoded;
+ }
}
ScanClient getAggressiveClient(Set cList) {
@@ -626,6 +685,29 @@ ScanClient getAggressiveClient(Set cList) {
return result;
}
+ PhyInfo getPhyInfo(Set cList) {
+ PhyInfo result = null;
+ int curScanSettingLE1M = Integer.MIN_VALUE;
+ int curScanSettingLECoded = Integer.MIN_VALUE;
+ int curScanPhy = BluetoothDevice.PHY_LE_1M;
+ int aggregateScanPhy = BluetoothDevice.PHY_LE_1M;
+ for (ScanClient client : cList) {
+ // Get the most aggresive scan mode for each PHY
+ curScanPhy = client.settings.getPhy();
+ if (((curScanPhy & BluetoothDevice.PHY_LE_1M)== BluetoothDevice.PHY_LE_1M) &&
+ (client.settings.getScanMode() > curScanSettingLE1M)) {
+ curScanSettingLE1M = client.settings.getScanMode();
+ }
+ if (((curScanPhy & BluetoothDevice.PHY_LE_CODED)== BluetoothDevice.PHY_LE_CODED) &&
+ (client.settings.getScanMode() > curScanSettingLECoded)) {
+ curScanSettingLECoded = client.settings.getScanMode();
+ }
+ aggregateScanPhy |= client.settings.getPhy();
+ }
+ result = new PhyInfo(aggregateScanPhy, curScanSettingLE1M, curScanSettingLECoded);
+ return result;
+ }
+
void startRegularScan(ScanClient client) {
if (isFilteringSupported() && mFilterIndexStack.isEmpty()
&& mClientFilterIndexMap.isEmpty()) {
@@ -1266,8 +1348,8 @@ private boolean manageAllocationOfTrackingAdvertisement(int numOfTrackableAdvert
private native void gattClientScanNative(boolean start);
- private native void gattSetScanParametersNative(int clientIf, int scanInterval,
- int scanWindow);
+ private native void gattSetScanParametersNative(int clientIf, int scan_phy, int[] scanInterval,
+ int[] scanWindow);
/************************** Filter related native methods ********************************/
private native void gattClientScanFilterAddNative(int clientId,
diff --git a/tests/unit/Android.mk b/tests/unit/Android.mk
index 98c88d403f0..df666874e2c 100644
--- a/tests/unit/Android.mk
+++ b/tests/unit/Android.mk
@@ -14,7 +14,7 @@ LOCAL_JAVA_LIBRARIES := \
android.test.mock
LOCAL_STATIC_JAVA_LIBRARIES := \
- com.android.emailcommon \
+ #com.android.emailcommon \
androidx.test.rules \
mockito-target \
androidx.test.espresso.intents