Merge "Revert "BluetoothInCallService: Wait for disconnect tone at onCallRemoved"" into sc-v2-dev
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index ead3f68..3ba6481 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -210,7 +210,7 @@
                             uint8_t secondary_phy, uint8_t advertising_sid,
                             int8_t tx_power, int8_t rssi,
                             uint16_t periodic_adv_int,
-                            std::vector<uint8_t> adv_data) {
+                            std::vector<uint8_t> adv_data, RawAddress* original_bda) {
   CallbackEnv sCallbackEnv(__func__);
   if (!sCallbackEnv.valid()) return;
 
@@ -221,10 +221,13 @@
   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(),
                                    (jbyte*)adv_data.data());
 
+  ScopedLocalRef<jstring> original_address(sCallbackEnv.get(),
+                                  bdaddr2newjstr(sCallbackEnv.get(), original_bda));
+
   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult, event_type,
                                addr_type, address.get(), primary_phy,
                                secondary_phy, advertising_sid, tx_power, rssi,
-                               periodic_adv_int, jb.get());
+                               periodic_adv_int, jb.get(), original_address.get());
 }
 
 void btgattc_open_cb(int conn_id, int status, int clientIf,
@@ -892,10 +895,11 @@
     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(),
                                      (jbyte*)adv_data.data());
 
+    // TODO(optedoblivion): Figure out original address for here, use same address for now
     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult, event_type,
                                  addr_type, address.get(), primary_phy,
                                  secondary_phy, advertising_sid, tx_power, rssi,
-                                 periodic_adv_int, jb.get());
+                                 periodic_adv_int, jb.get(), address.get());
   }
 
   void OnTrackAdvFoundLost(AdvertisingTrackInfo track_info) {
@@ -971,7 +975,7 @@
   method_onScannerRegistered =
       env->GetMethodID(clazz, "onScannerRegistered", "(IIJJ)V");
   method_onScanResult = env->GetMethodID(clazz, "onScanResult",
-                                         "(IILjava/lang/String;IIIIII[B)V");
+                                         "(IILjava/lang/String;IIIIII[BLjava/lang/String;)V");
   method_onConnected =
       env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
   method_onDisconnected =
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 6b01c92..04b6206 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -93,8 +93,8 @@
     <string name="status_not_accept" msgid="1695082417193780738">"সমল সমৰ্থিত নহয়।"</string>
     <string name="status_forbidden" msgid="613956401054050725">"নিৰ্দিষ্ট কৰা ডিভাইচটোৱে স্থানান্তৰণ নিষিদ্ধ কৰিছে।"</string>
     <string name="status_canceled" msgid="6664490318773098285">"ব্যৱহাৰকাৰীয়ে স্থানান্তৰণ বাতিল কৰিছে।"</string>
-    <string name="status_file_error" msgid="3671917770630165299">"সঞ্চয়াগাৰৰ সমস্যা।"</string>
-    <string name="status_no_sd_card_nosdcard" msgid="573631036356922221">"কোনো USB সঞ্চয়াগাৰ নাই।"</string>
+    <string name="status_file_error" msgid="3671917770630165299">"ষ্ট’ৰেজৰ সমস্যা।"</string>
+    <string name="status_no_sd_card_nosdcard" msgid="573631036356922221">"কোনো ইউএছবি ষ্ট’ৰেজ নাই।"</string>
     <string name="status_no_sd_card_default" msgid="396564893716701954">"কোনো SD কাৰ্ড নাই। স্থানান্তৰ কৰা ফাইলসমূহ ছেভ কৰিবলৈ SD কাৰ্ড ভৰাওক।"</string>
     <string name="status_connection_error" msgid="947681831523219891">"সংযোগ কৰিব পৰা নগ\'ল।"</string>
     <string name="status_protocol_error" msgid="3245444473429269539">"অনুৰোধ সঠিকভাৱে পৰিচালনা কৰিব নোৱাৰি।"</string>
@@ -106,7 +106,7 @@
     <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="transfer_clear_dlg_msg" msgid="1712376797268438075">"আটাইবোৰ সমল সূচীৰ পৰা মচা হ\'ব।"</string>
     <string name="outbound_noti_title" msgid="8051906709452260849">"ব্লুটুথ শ্বেয়াৰ: প্ৰেৰণ কৰা ফাইলসমূহ"</string>
     <string name="inbound_noti_title" msgid="4143352641953027595">"ব্লুটুথ শ্বেয়াৰ: লাভ কৰা ফাইলসমূহ"</string>
     <plurals name="noti_caption_unsuccessful" formatted="false" msgid="2020750076679526122">
diff --git a/res/values-as/test_strings.xml b/res/values-as/test_strings.xml
index a2efd87..861f5a8 100644
--- a/res/values-as/test_strings.xml
+++ b/res/values-as/test_strings.xml
@@ -5,7 +5,7 @@
     <string name="insert_record" msgid="1450997173838378132">"ৰেকৰ্ড ভৰাওক"</string>
     <string name="update_record" msgid="2480425402384910635">"ৰেকৰ্ড নিশ্চিত কৰক"</string>
     <string name="ack_record" msgid="6716152390978472184">"স্বীকৃত কৰা ৰেকৰ্ড"</string>
-    <string name="deleteAll_record" msgid="4383349788485210582">"সকলো ৰেকৰ্ড মচক"</string>
+    <string name="deleteAll_record" msgid="4383349788485210582">"আটাইবোৰ ৰেকৰ্ড মচক"</string>
     <string name="ok_button" msgid="6519033415223065454">"ঠিক"</string>
     <string name="delete_record" msgid="4645040331967533724">"ৰেকৰ্ড মচক"</string>
     <string name="start_server" msgid="9034821924409165795">"TCP ছাৰ্ভাৰ আৰম্ভ কৰক"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 31f37f4..ed97c52 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -26,7 +26,7 @@
     <string name="airplane_error_title" msgid="2683839635115739939">"Način rada u avionu"</string>
     <string name="airplane_error_msg" msgid="8698965595254137230">"Ne možete koristiti Bluetooth u načinu rada u avionu."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
-    <string name="bt_enable_line1" msgid="7203551583048149">"Da biste koristili Bluetooth usluge, prvo morate uključiti Bluetooth."</string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Da biste koristili usluge Bluetootha, prvo morate uključiti Bluetooth."</string>
     <string name="bt_enable_line2" msgid="4341936569415937994">"Želite uključiti Bluetooth sada?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Otkaži"</string>
     <string name="bt_enable_ok" msgid="3432462749994538265">"Uključi"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 1099df0..586176a 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -110,12 +110,12 @@
     <string name="outbound_noti_title" msgid="8051906709452260849">"Bluetooth: file inviati"</string>
     <string name="inbound_noti_title" msgid="4143352641953027595">"Bluetooth: file ricevuti"</string>
     <plurals name="noti_caption_unsuccessful" formatted="false" msgid="2020750076679526122">
+      <item quantity="one"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> unsuccessful.</item>
       <item quantity="other">Operazioni non riuscite: <xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g>.</item>
-      <item quantity="one">Operazione non riuscita: <xliff:g id="UNSUCCESSFUL_NUMBER_0">%1$d</xliff:g>.</item>
     </plurals>
     <plurals name="noti_caption_success" formatted="false" msgid="1572472450257645181">
+      <item quantity="one"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> successful, %2$s</item>
       <item quantity="other">Operazioni riuscite: <xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g>, %2$s</item>
-      <item quantity="one">Operazione riuscita: <xliff:g id="SUCCESSFUL_NUMBER_0">%1$d</xliff:g>, %2$s</item>
     </plurals>
     <string name="transfer_menu_clear_all" msgid="790017462957873132">"Cancella elenco"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"Apri"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 8302a2e..c698250 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/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">"Downloadbeheer weergeven."</string>
+    <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Downloadbeheer tonen."</string>
     <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Hiermee krijgt de app toegang tot de beheerfunctie voor delen via bluetooth om deze functie te gebruiken voor het overdragen van bestanden."</string>
     <string name="permlab_bluetoothAcceptlist" msgid="2647575807648622053">"Toegang voor bluetooth-apparaat op toelatingslijst zetten."</string>
     <string name="permdesc_bluetoothAcceptlist" msgid="2406423665674766442">"Hiermee kan de app een bluetooth-apparaat tijdelijk op de toelatingslijst zetten, waardoor dat apparaat bestanden naar dit apparaat kan sturen zonder bevestiging van de gebruiker."</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 7aac78b..eb99087 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -110,12 +110,12 @@
     <string name="outbound_noti_title" msgid="8051906709452260849">"Partilha por Bluetooth: ficheiros enviados"</string>
     <string name="inbound_noti_title" msgid="4143352641953027595">"Partilha por Bluetooth: ficheiros recebidos"</string>
     <plurals name="noti_caption_unsuccessful" formatted="false" msgid="2020750076679526122">
-      <item quantity="other"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> sem êxito.</item>
       <item quantity="one"><xliff:g id="UNSUCCESSFUL_NUMBER_0">%1$d</xliff:g> sem êxito.</item>
+      <item quantity="other"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> sem êxito.</item>
     </plurals>
     <plurals name="noti_caption_success" formatted="false" msgid="1572472450257645181">
-      <item quantity="other"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> com êxito, %2$s</item>
       <item quantity="one"><xliff:g id="SUCCESSFUL_NUMBER_0">%1$d</xliff:g> com êxito, %2$s</item>
+      <item quantity="other"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> com êxito, %2$s</item>
     </plurals>
     <string name="transfer_menu_clear_all" msgid="790017462957873132">"Limpar lista"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"Abrir"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 6dffe83..ab946a6 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -72,7 +72,7 @@
     <string name="upload_fail_cancel" msgid="9118496285835687125">"மூடு"</string>
     <string name="bt_error_btn_ok" msgid="5965151173011534240">"சரி"</string>
     <string name="unknown_file" msgid="6092727753965095366">"அறியப்படாத ஃபைல்"</string>
-    <string name="unknown_file_desc" msgid="480434281415453287">"இந்த வகையான கோப்பைக் கையாள எந்தப் பயன்பாடும் இல்லை. \n"</string>
+    <string name="unknown_file_desc" msgid="480434281415453287">"இந்த வகையான ஃபைலைக் கையாள எந்தப் பயன்பாடும் இல்லை. \n"</string>
     <string name="not_exist_file" msgid="3489434189599716133">"ஃபைல் இல்லை"</string>
     <string name="not_exist_file_desc" msgid="4059531573790529229">"ஃபைல் இல்லை. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"காத்திருக்கவும்…"</string>
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 7797b38..ce0ea4d 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -125,10 +125,10 @@
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.util.ArrayUtils;
 
-import libcore.util.SneakyThrow;
-
 import com.google.protobuf.InvalidProtocolBufferException;
 
+import libcore.util.SneakyThrow;
+
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -3668,6 +3668,7 @@
         if (DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
                 LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, false)) {
             initFlags.add(String.format("%s=%s", LOGGING_DEBUG_ENABLED_FOR_ALL_FLAG, "true"));
+            mIsVerboseLoggingEnabledForAll = true;
         }
         String debugLoggingEnabledTags = DeviceConfig.getString(DeviceConfig.NAMESPACE_BLUETOOTH,
                 LOGGING_DEBUG_ENABLED_FOR_TAGS_FLAG, "");
@@ -3687,6 +3688,12 @@
         return initFlags.toArray(new String[0]);
     }
 
+    private boolean mIsVerboseLoggingEnabledForAll = false;
+
+    public boolean getIsVerboseLoggingEnabledForAll() {
+        return mIsVerboseLoggingEnabledForAll;
+    }
+
     private final Object mDeviceConfigLock = new Object();
 
     /**
diff --git a/src/com/android/bluetooth/btservice/AdapterState.java b/src/com/android/bluetooth/btservice/AdapterState.java
index 3f153bd..8fdc61a 100644
--- a/src/com/android/bluetooth/btservice/AdapterState.java
+++ b/src/com/android/bluetooth/btservice/AdapterState.java
@@ -73,7 +73,7 @@
     static final int BLE_START_TIMEOUT = 12;
 
     static final int BLE_START_TIMEOUT_DELAY = 4000;
-    static final int BLE_STOP_TIMEOUT_DELAY = 1000;
+    static final int BLE_STOP_TIMEOUT_DELAY = 4000;
     static final int BREDR_START_TIMEOUT_DELAY = 4000;
     static final int BREDR_STOP_TIMEOUT_DELAY = 4000;
 
diff --git a/src/com/android/bluetooth/gatt/AppScanStats.java b/src/com/android/bluetooth/gatt/AppScanStats.java
index 975d7b6..b2324a0 100644
--- a/src/com/android/bluetooth/gatt/AppScanStats.java
+++ b/src/com/android/bluetooth/gatt/AppScanStats.java
@@ -15,6 +15,7 @@
  */
 package com.android.bluetooth.gatt;
 
+import android.bluetooth.BluetoothDevice;
 import android.bluetooth.le.ScanFilter;
 import android.bluetooth.le.ScanSettings;
 import android.os.Binder;
@@ -75,14 +76,21 @@
         public boolean isFilterScan;
         public boolean isCallbackScan;
         public boolean isBatchScan;
+        public boolean isLegacy;
         public int results;
         public int scannerId;
         public int scanMode;
         public int scanCallbackType;
+        public int phy;
+        public int scanResultType;
+        public long reportDelayMillis;
+        public int numOfMatchesPerFilter;
+        public int matchMode;
         public String filterString;
 
-        LastScan(long timestamp, boolean isFilterScan, boolean isCallbackScan, int scannerId,
-                int scanMode, int scanCallbackType) {
+        LastScan(long timestamp, boolean isFilterScan, boolean isCallbackScan, boolean isLegacy,
+                int scannerId, int scanMode, int scanCallbackType, int phy, int scanResultType,
+                long reportDelayMillis, int numOfMatchesPerFilter, int matchMode) {
             this.duration = 0;
             this.timestamp = timestamp;
             this.isOpportunisticScan = false;
@@ -90,9 +98,15 @@
             this.isBackgroundScan = false;
             this.isFilterScan = isFilterScan;
             this.isCallbackScan = isCallbackScan;
+            this.isLegacy = isLegacy;
             this.isBatchScan = false;
             this.scanMode = scanMode;
             this.scanCallbackType = scanCallbackType;
+            this.phy = phy;
+            this.scanResultType = scanResultType;
+            this.reportDelayMillis = reportDelayMillis;
+            this.numOfMatchesPerFilter = numOfMatchesPerFilter;
+            this.matchMode = matchMode;
             this.results = 0;
             this.scannerId = scannerId;
             this.suspendDuration = 0;
@@ -195,8 +209,10 @@
         this.mScansStarted++;
         startTime = SystemClock.elapsedRealtime();
 
-        LastScan scan = new LastScan(startTime, isFilterScan, isCallbackScan, scannerId,
-                settings.getScanMode(), settings.getCallbackType());
+        LastScan scan = new LastScan(startTime, isFilterScan, isCallbackScan, settings.getLegacy(),
+                scannerId, settings.getScanMode(), settings.getCallbackType(), settings.getPhy(),
+                settings.getScanResultType(), settings.getReportDelayMillis(),
+                settings.getNumOfMatches(), settings.getMatchMode());
         if (settings != null) {
             scan.isOpportunisticScan = scan.scanMode == ScanSettings.SCAN_MODE_OPPORTUNISTIC;
             scan.isBackgroundScan =
@@ -396,6 +412,16 @@
         }
         if (filter.getDeviceAddress() != null) {
             filterString += " DeviceAddress=" + filter.getDeviceAddress();
+            filterString += " AddressType="
+                    + addressTypeToString(filter.getDeviceAddress(), filter.getAddressType());
+            if (filter.getIrk() != null) {
+                if (filter.getIrk().length == 0) {
+                    filterString += "irkLength=0";
+                } else {
+                    filterString += "irkLength=" + filter.getIrk().length;
+                    filterString += "irkFirstByte=" + String.format("%02x", filter.getIrk()[0]);
+                }
+            }
         }
         if (filter.getServiceUuid() != null) {
             filterString += " ServiceUuid=" + filter.getServiceUuid();
@@ -433,6 +459,25 @@
         return filterString;
     }
 
+    private static String addressTypeToString(String address, int addressType) {
+        switch (addressType) {
+            case BluetoothDevice.ADDRESS_TYPE_PUBLIC:
+                return "PUBLIC";
+            case BluetoothDevice.ADDRESS_TYPE_RANDOM:
+                int msb = Integer.parseInt(address.split(":")[0], 16);
+                if ((msb & 0xC0) == 0xC0) {
+                    return "RANDOM_STATIC";
+                } else if ((msb & 0xC0) == 0x40) {
+                    return "RANDOM_RESOLVABLE";
+                } else if ((msb & 0xC0) == 0x00) {
+                    return "RANDOM_NON_RESOLVABLE";
+                } else {
+                    return "RANDOM_INVALID[msb=0x" + String.format("%02x", msb) + "]";
+                }
+            default:
+                return "INVALID[" + addressType + "]";
+        }
+    }
 
     private static String scanModeToString(int scanMode) {
         switch (scanMode) {
@@ -466,6 +511,43 @@
         }
     }
 
+    private static String phyToString(int phy) {
+        switch (phy) {
+            case BluetoothDevice.PHY_LE_1M:
+                return "LE_1M";
+            case BluetoothDevice.PHY_LE_2M:
+                return "LE_2M";
+            case BluetoothDevice.PHY_LE_CODED:
+                return "LE_CODED";
+            case ScanSettings.PHY_LE_ALL_SUPPORTED:
+                return "ALL_SUPPORTED";
+            default:
+                return "UNKNOWN[" + phy + "]";
+        }
+    }
+
+    private static String scanResultTypeToString(int scanResultType) {
+        switch (scanResultType) {
+            case ScanSettings.SCAN_RESULT_TYPE_FULL:
+                return "FULL";
+            case ScanSettings.SCAN_RESULT_TYPE_ABBREVIATED:
+                return "ABBREVIATED";
+            default:
+                return "UNKNOWN[" + scanResultType + "]";
+        }
+    }
+
+    private static String matchModeToString(int matchMode) {
+        switch (matchMode) {
+            case ScanSettings.MATCH_MODE_STICKY:
+                return "STICKY";
+            case ScanSettings.MATCH_MODE_AGGRESSIVE:
+                return "AGGRESSIVE";
+            default:
+                return "UNKNOWN[" + matchMode + "]";
+        }
+    }
+
     synchronized void dumpToString(StringBuilder sb) {
         long currentTime = System.currentTimeMillis();
         long currTime = SystemClock.elapsedRealtime();
@@ -583,7 +665,12 @@
                 }
                 sb.append("\n      └ " + "Scan Config: [ ScanMode="
                         + scanModeToString(scan.scanMode) + ", callbackType="
-                        + callbackTypeToString(scan.scanCallbackType) + " ]");
+                        + callbackTypeToString(scan.scanCallbackType) + ", isLegacy="
+                        + scan.isLegacy + " phy=" + phyToString(scan.phy) + ", scanResultType="
+                        + scanResultTypeToString(scan.scanResultType) + ", reportDelayMillis="
+                        + scan.reportDelayMillis + ", numOfMatchesPerFilter="
+                        + scan.numOfMatchesPerFilter + ", matchMode="
+                        + matchModeToString(scan.matchMode) + " ]");
                 if (scan.isFilterScan) {
                     sb.append(scan.filterString);
                 }
@@ -633,7 +720,12 @@
                 }
                 sb.append("\n      └ " + "Scan Config: [ ScanMode="
                         + scanModeToString(scan.scanMode) + ", callbackType="
-                        + callbackTypeToString(scan.scanCallbackType) + " ]");
+                        + callbackTypeToString(scan.scanCallbackType) + ", isLegacy="
+                        + scan.isLegacy + " phy=" + phyToString(scan.phy) + ", scanResultType="
+                        + scanResultTypeToString(scan.scanResultType) + ", reportDelayMillis="
+                        + scan.reportDelayMillis + ", numOfMatchesPerFilter="
+                        + scan.numOfMatchesPerFilter + ", matchMode="
+                        + matchModeToString(scan.matchMode) + " ]");
                 if (scan.isFilterScan) {
                     sb.append(scan.filterString);
                 }
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 0aaf7f5..3eeb1a3 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -109,6 +109,28 @@
     private static final int TRUNCATED_RESULT_SIZE = 11;
     private static final int TIME_STAMP_LENGTH = 2;
 
+    private enum MatchOrigin {
+        PSEUDO_ADDRESS,
+        ORIGINAL_ADDRESS
+    }
+
+    private static class MatchResult {
+        private final boolean matches;
+        private final MatchOrigin origin;
+        private MatchResult(boolean matches, MatchOrigin origin) {
+            this.matches = matches;
+            this.origin = origin;
+        }
+
+        public boolean getMatches() {
+            return matches;
+        }
+
+        public MatchOrigin getMatchOrigin() {
+            return origin;
+        }
+    }
+
     /**
      * The default floor value for LE batch scan report delays greater than 0
      */
@@ -331,7 +353,8 @@
                             }
                             for (String test : TEST_MODE_BEACONS) {
                                 onScanResultInternal(0x1b, 0x1, "DD:34:02:05:5C:4D", 1, 0, 0xff,
-                                        127, -54, 0x0, HexDump.hexStringToByteArray(test));
+                                        127, -54, 0x0, HexDump.hexStringToByteArray(test),
+                                        "DD:34:02:05:5C:4E");
                             }
                             sendEmptyMessageDelayed(0, DateUtils.SECOND_IN_MILLIS);
                         }
@@ -1133,23 +1156,24 @@
 
     void onScanResult(int eventType, int addressType, String address, int primaryPhy,
             int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
-            byte[] advData) {
+            byte[] advData, String originalAddress) {
         // When in testing mode, ignore all real-world events
         if (isTestModeEnabled()) return;
 
         onScanResultInternal(eventType, addressType, address, primaryPhy, secondaryPhy,
-                advertisingSid, txPower, rssi, periodicAdvInt, advData);
+                advertisingSid, txPower, rssi, periodicAdvInt, advData, originalAddress);
     }
 
     void onScanResultInternal(int eventType, int addressType, String address, int primaryPhy,
             int secondaryPhy, int advertisingSid, int txPower, int rssi, int periodicAdvInt,
-            byte[] advData) {
-        if (VDBG) {
+            byte[] advData, String originalAddress) {
+        if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
             Log.d(TAG, "onScanResult() - eventType=0x" + Integer.toHexString(eventType)
                     + ", addressType=" + addressType + ", address=" + address + ", primaryPhy="
                     + primaryPhy + ", secondaryPhy=" + secondaryPhy + ", advertisingSid=0x"
                     + Integer.toHexString(advertisingSid) + ", txPower=" + txPower + ", rssi="
-                    + rssi + ", periodicAdvInt=0x" + Integer.toHexString(periodicAdvInt));
+                    + rssi + ", periodicAdvInt=0x" + Integer.toHexString(periodicAdvInt)
+                    + ", originalAddress=" + originalAddress);
         }
 
         byte[] legacyAdvData = Arrays.copyOfRange(advData, 0, 62);
@@ -1157,6 +1181,9 @@
         for (ScanClient client : mScanManager.getRegularScanQueue()) {
             ScannerMap.App app = mScannerMap.getById(client.scannerId);
             if (app == null) {
+                if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
+                    Log.d(TAG, "App is null for scanner ID " + client.scannerId);
+                }
                 continue;
             }
 
@@ -1168,6 +1195,8 @@
             if (settings.getLegacy()) {
                 if ((eventType & ET_LEGACY_MASK) == 0) {
                     // If this is legacy scan, but nonlegacy result - skip.
+                    Log.i(TAG, "Non legacy result in legacy scan, skipping scanner id "
+                               + client.scannerId + ", eventType=" + eventType);
                     continue;
                 } else {
                     // Some apps are used to fixed-size advertise data.
@@ -1185,6 +1214,10 @@
 
             if (client.hasDisavowedLocation) {
                 if (mLocationDenylistPredicate.test(result)) {
+                    if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
+                        Log.d(TAG, "Result in location deny list, skipping scanner id "
+                                + client.scannerId);
+                    }
                     continue;
                 }
             }
@@ -1205,11 +1238,33 @@
                     result = sanitized;
                 }
             }
-            if (!hasPermission || !matchesFilters(client, result)) {
+            if (!hasPermission) {
+                if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
+                    Log.d(TAG, "scanner id " + client.scannerId + " has no result permission");
+                }
                 continue;
             }
 
+            MatchResult matchResult = matchesFilters(client, result, originalAddress);
+            if (!matchResult.getMatches()) {
+                if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
+                    Log.d(TAG, "result did not match filter for scanner id " + client.scannerId);
+                }
+                continue;
+            }
+
+            if (matchResult.getMatchOrigin() == MatchOrigin.ORIGINAL_ADDRESS) {
+                result = new ScanResult(getAnonymousDevice(originalAddress), eventType, primaryPhy,
+                        secondaryPhy, advertisingSid, txPower, rssi, periodicAdvInt, scanRecord,
+                            SystemClock.elapsedRealtimeNanos());
+
+            }
+
             if ((settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_ALL_MATCHES) == 0) {
+                if (VDBG || mAdapterService.getIsVerboseLoggingEnabledForAll()) {
+                    Log.d(TAG, "callback type " + settings.getCallbackType()
+                            + " is not ALL_MATCHES for scanner id " + client.scannerId);
+                }
                 continue;
             }
 
@@ -1225,7 +1280,7 @@
                             ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
                 }
             } catch (RemoteException | PendingIntent.CanceledException e) {
-                Log.e(TAG, "Exception: " + e);
+                Log.e(TAG, "Stop scan for scanner id " + client.scannerId + " due to : " + e);
                 mScannerMap.remove(client.scannerId);
                 mScanManager.stopScan(client.scannerId);
             }
@@ -1308,16 +1363,29 @@
     }
 
     // Check if a scan record matches a specific filters.
-    private boolean matchesFilters(ScanClient client, ScanResult scanResult) {
+    private MatchResult matchesFilters(ScanClient client, ScanResult scanResult) {
+        return matchesFilters(client, scanResult, null);
+    }
+
+
+    // Check if a scan record matches a specific filters.
+    private MatchResult matchesFilters(ScanClient client, ScanResult scanResult,
+            String originalAddress) {
         if (client.filters == null || client.filters.isEmpty()) {
-            return true;
+            // TODO: Do we really wanna return true here?
+            return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
         }
         for (ScanFilter filter : client.filters) {
+            // Need to check the filter matches, and the original address without changing the API
             if (filter.matches(scanResult)) {
-                return true;
+                return new MatchResult(true, MatchOrigin.PSEUDO_ADDRESS);
+            }
+            if (originalAddress != null
+                    && originalAddress.equalsIgnoreCase(filter.getDeviceAddress())) {
+                return new MatchResult(true, MatchOrigin.ORIGINAL_ADDRESS);
             }
         }
-        return false;
+        return new MatchResult(false, MatchOrigin.PSEUDO_ADDRESS);
     }
 
     void onClientRegistered(int status, int clientIf, long uuidLsb, long uuidMsb)
@@ -1900,7 +1968,7 @@
         // Reconstruct the scan results.
         ArrayList<ScanResult> results = new ArrayList<ScanResult>();
         for (ScanResult scanResult : permittedResults) {
-            if (matchesFilters(client, scanResult)) {
+            if (matchesFilters(client, scanResult).getMatches()) {
                 results.add(scanResult);
             }
         }
diff --git a/src/com/android/bluetooth/gatt/ScanFilterQueue.java b/src/com/android/bluetooth/gatt/ScanFilterQueue.java
index 4572c89..c938dc7 100644
--- a/src/com/android/bluetooth/gatt/ScanFilterQueue.java
+++ b/src/com/android/bluetooth/gatt/ScanFilterQueue.java
@@ -181,13 +181,12 @@
             addName(filter.getDeviceName());
         }
         if (filter.getDeviceAddress() != null) {
-            byte addressType = (byte) filter.getAddressType();
-            // If addressType == iADDRESS_TYPE_PUBLIC (0) then this is the original
-            // setDeviceAddress(address) API path which provided DEVICE_TYPE_ALL (2) which might map
-            // to the stack value for address type of BTM_BLE_STATIC (2)
-            // Additionally, we shouldn't confuse device type with address type.
-            addDeviceAddress(filter.getDeviceAddress(),
-                    ((addressType == 0) ? DEVICE_TYPE_ALL : addressType), filter.getIrk());
+            /*
+             * Pass the addres type here.  This address type will be used for the resolving address,
+             * however, the host stack will force the type to 0x02 for the APCF filter in
+             * btm_ble_adv_filter.cc#BTM_LE_PF_addr_filter(...)
+             */
+            addDeviceAddress(filter.getDeviceAddress(), (byte) filter.getAddressType(), filter.getIrk());
         }
         if (filter.getServiceUuid() != null) {
             if (filter.getServiceUuidMask() == null) {
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index cd63287..95348f9 100644
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -1911,6 +1911,7 @@
 
     @Override
     public void dump(StringBuilder sb) {
+        boolean isScoOn = mSystemInterface.getAudioManager().isBluetoothScoOn();
         synchronized (mStateMachines) {
             super.dump(sb);
             ProfileService.println(sb, "mMaxHeadsetConnections: " + mMaxHeadsetConnections);
@@ -1931,9 +1932,7 @@
             ProfileService.println(sb, "mForceScoAudio: " + mForceScoAudio);
             ProfileService.println(sb, "mCreated: " + mCreated);
             ProfileService.println(sb, "mStarted: " + mStarted);
-            ProfileService.println(sb,
-                    "AudioManager.isBluetoothScoOn(): " + mSystemInterface.getAudioManager()
-                            .isBluetoothScoOn());
+            ProfileService.println(sb, "AudioManager.isBluetoothScoOn(): " + isScoOn);
             ProfileService.println(sb, "Telecom.isInCall(): " + mSystemInterface.isInCall());
             ProfileService.println(sb, "Telecom.isRinging(): " + mSystemInterface.isRinging());
             for (HeadsetStateMachine stateMachine : mStateMachines.values()) {
diff --git a/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/src/com/android/bluetooth/telephony/BluetoothInCallService.java
index 86e1a37..fdf70e7 100644
--- a/src/com/android/bluetooth/telephony/BluetoothInCallService.java
+++ b/src/com/android/bluetooth/telephony/BluetoothInCallService.java
@@ -116,7 +116,7 @@
     public final HashMap<String, BluetoothCall> mBluetoothCallHashMap = new HashMap<>();
 
     // A map from Calls to indexes used to identify calls for CLCC (C* List Current Calls).
-    private final Map<BluetoothCall, Integer> mClccIndexMap = new HashMap<>();
+    private final Map<String, Integer> mClccIndexMap = new HashMap<>();
 
     private static BluetoothInCallService sInstance = null;
 
@@ -531,7 +531,7 @@
             mBluetoothCallHashMap.remove(call.getTelecomCallId());
         }
 
-        mClccIndexMap.remove(call);
+        mClccIndexMap.remove(getClccMapKey(call));
         updateHeadsetWithCallState(false /* force */);
     }
 
@@ -699,13 +699,28 @@
         }
     }
 
+    private String getClccMapKey(BluetoothCall call) {
+        if (mCallInfo.isNullCall(call) || call.getHandle() == null) {
+            return "";
+        }
+        Uri handle = call.getHandle();
+        String key;
+        if (call.hasProperty(Call.Details.PROPERTY_SELF_MANAGED)) {
+            key = handle.toString() + " self managed " + call.getTelecomCallId();
+        } else {
+            key = handle.toString();
+        }
+        return key;
+    }
+
     /**
      * Returns the caches index for the specified call.  If no such index exists, then an index is
      * given (smallest number starting from 1 that isn't already taken).
      */
     private int getIndexForCall(BluetoothCall call) {
-        if (mClccIndexMap.containsKey(call)) {
-            return mClccIndexMap.get(call);
+        String key = getClccMapKey(call);
+        if (mClccIndexMap.containsKey(key)) {
+            return mClccIndexMap.get(key);
         }
 
         int i = 1;  // Indexes for bluetooth clcc are 1-based.
@@ -714,7 +729,7 @@
         }
 
         // NOTE: Indexes are removed in {@link #onCallRemoved}.
-        mClccIndexMap.put(call, i);
+        mClccIndexMap.put(key, i);
         return i;
     }
 
diff --git a/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java b/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
index 45e1f10..f667c20 100644
--- a/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
+++ b/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java
@@ -385,8 +385,11 @@
         // BluetoothCall has been put into a CDMA "conference" with one BluetoothCall on hold.
         List<BluetoothCall> calls = new ArrayList<BluetoothCall>();
         BluetoothCall parentCall = createActiveCall();
+        when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         final BluetoothCall foregroundCall = getMockCall();
+        when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
         final BluetoothCall heldCall = createHeldCall();
+        when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002"));
         calls.add(parentCall);
         calls.add(foregroundCall);
         calls.add(heldCall);
@@ -400,9 +403,9 @@
         when(foregroundCall.isIncoming()).thenReturn(false);
         when(heldCall.isIncoming()).thenReturn(true);
         when(foregroundCall.getGatewayInfo()).thenReturn(
-                new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
-        when(heldCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
+        when(heldCall.getGatewayInfo()).thenReturn(
+                new GatewayInfo(null, null, Uri.parse("tel:555-0002")));
         addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
@@ -423,9 +426,9 @@
         mBluetoothInCallService.listCurrentCalls();
 
         verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(false), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
-        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
                 eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
+                eq(false), eq("5550002"), eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -436,6 +439,9 @@
         BluetoothCall parentCall = createActiveCall();
         final BluetoothCall confCall1 = getMockCall();
         final BluetoothCall confCall2 = createHeldCall();
+        when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+        when(confCall1.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
+        when(confCall2.getHandle()).thenReturn(Uri.parse("tel:555-0002"));
         calls.add(parentCall);
         calls.add(confCall1);
         calls.add(confCall2);
@@ -492,6 +498,7 @@
                 new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
         when(waitingCall.getState()).thenReturn(Call.STATE_RINGING);
         when(waitingCall.isConference()).thenReturn(false);
+        when(waitingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
@@ -531,6 +538,7 @@
         when(ringingCall.getState()).thenReturn(Call.STATE_RINGING);
         when(ringingCall.isIncoming()).thenReturn(true);
         when(ringingCall.isConference()).thenReturn(false);
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         when(ringingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
 
@@ -554,6 +562,7 @@
         when(ringingCall.getState()).thenReturn(Call.STATE_RINGING);
         when(ringingCall.isIncoming()).thenReturn(true);
         when(ringingCall.isConference()).thenReturn(false);
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
         when(ringingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:5550000")));
 
@@ -571,6 +580,7 @@
         when(newHoldingCall.getState()).thenReturn(Call.STATE_HOLDING);
         when(newHoldingCall.isIncoming()).thenReturn(true);
         when(newHoldingCall.isConference()).thenReturn(false);
+        when(newHoldingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
         when(newHoldingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
 
@@ -593,6 +603,7 @@
         when(dialingCall.getState()).thenReturn(Call.STATE_DIALING);
         when(dialingCall.isIncoming()).thenReturn(false);
         when(dialingCall.isConference()).thenReturn(false);
+        when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         when(dialingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
 
@@ -616,6 +627,7 @@
         when(dialingCall.getState()).thenReturn(Call.STATE_DIALING);
         when(dialingCall.isIncoming()).thenReturn(false);
         when(dialingCall.isConference()).thenReturn(false);
+        when(dialingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         when(dialingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0000")));
         BluetoothCall holdingCall = createHeldCall();
@@ -625,6 +637,7 @@
         when(holdingCall.getState()).thenReturn(Call.STATE_HOLDING);
         when(holdingCall.isIncoming()).thenReturn(true);
         when(holdingCall.isConference()).thenReturn(false);
+        when(holdingCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
         when(holdingCall.getGatewayInfo()).thenReturn(
                 new GatewayInfo(null, null, Uri.parse("tel:555-0001")));
 
@@ -650,13 +663,14 @@
         when(parentCall.isConference()).thenReturn(true);
         when(parentCall.getState()).thenReturn(Call.STATE_ACTIVE);
         when(parentCall.isIncoming()).thenReturn(true);
+        when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls);
 
         clearInvocations(mMockBluetoothHeadset);
         mBluetoothInCallService.listCurrentCalls();
 
         verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
-                eq(true), (String) isNull(), eq(-1));
+                eq(true), eq("5550000"), eq(129));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -666,6 +680,10 @@
         BluetoothCall parentCall = createHeldCall();
         BluetoothCall childCall1 = createActiveCall();
         BluetoothCall childCall2 = createActiveCall();
+        when(parentCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+        when(childCall1.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
+        when(childCall2.getHandle()).thenReturn(Uri.parse("tel:555-0002"));
+
         calls.add(parentCall);
         calls.add(childCall1);
         calls.add(childCall2);
@@ -691,9 +709,9 @@
         mBluetoothInCallService.listCurrentCalls();
 
         verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
-                eq(true), (String) isNull(), eq(-1));
+                eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
-                eq(true), (String) isNull(), eq(-1));
+                eq(true), eq("5550002"), eq(PhoneNumberUtils.TOA_Unknown));
         verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
     }
 
@@ -846,11 +864,14 @@
         // and simulate a swapConference().
         BluetoothCall parentCall = createActiveCall();
         final BluetoothCall foregroundCall = getMockCall();
+        when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
         final BluetoothCall heldCall = createHeldCall();
+        when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002"));
         addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         when(parentCall.isConference()).thenReturn(true);
         when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
+        when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
         List<String> childrenIds = Arrays.asList(foregroundCall.getTelecomCallId(),
                 heldCall.getTelecomCallId());
         when(parentCall.getChildrenIds()).thenReturn(childrenIds);
@@ -895,6 +916,8 @@
         BluetoothCall parentCall = createActiveCall();
         final BluetoothCall foregroundCall = getMockCall();
         final BluetoothCall heldCall = createHeldCall();
+        when(foregroundCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
+        when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0002"));
         addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
         removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
         when(parentCall.isConference()).thenReturn(true);
@@ -913,6 +936,7 @@
         BluetoothCall activeCall = createActiveCall();
         mBluetoothInCallService.onCallAdded(activeCall);
         doReturn(null).when(mMockCallInfo).getActiveCall();
+        when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001"));
         mBluetoothInCallService.onCallRemoved(activeCall);
 
         verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),