Merge "MAP: Add proper version during map email use cases" into bt.lnx.5.0
diff --git a/packages_apps_bluetooth_ext/jni/Android.bp b/packages_apps_bluetooth_ext/jni/Android.bp
index 6848cb2..66c59ac 100644
--- a/packages_apps_bluetooth_ext/jni/Android.bp
+++ b/packages_apps_bluetooth_ext/jni/Android.bp
@@ -26,4 +26,7 @@
         "com_android_bluetooth_avrcp_ext.cpp",
         "com_android_bluetooth_ba.cpp",
     ],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java b/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
index 0e127bd..8724986 100644
--- a/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
+++ b/packages_apps_bluetooth_ext/src/avrcp/Avrcp_ext.java
@@ -236,7 +236,6 @@
     private final static int MESSAGE_SET_MEDIA_SESSION = 24;
     private final static int MSG_SET_AVRCP_CONNECTED_DEVICE = 25;
     private final static int MESSAGE_UPDATE_ABS_VOLUME_STATUS = 31;
-    private final static int MESSAGE_UPDATE_ABSOLUTE_VOLUME = 32;
     private static final int MSG_PLAY_STATUS_CMD_TIMEOUT = 33;
     private final static int MESSAGE_START_SHO = 34;
 
@@ -838,19 +837,6 @@
                 break;
             }
 
-           case MESSAGE_UPDATE_ABSOLUTE_VOLUME:
-            {
-                int vol = msg.arg2;
-                deviceIndex = msg.arg1;
-                Log.e(TAG, "Device switch: setting volume: " + vol);
-                if(deviceFeatures[deviceIndex].isAbsoluteVolumeSupportingDevice) {
-                    notifyVolumeChanged(vol, false);
-                } else {
-                    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, vol, 0);
-                }
-                break;
-            }
-
             case MSG_NATIVE_REQ_GET_RC_FEATURES:
             {
                 String address = (String) msg.obj;
@@ -1183,7 +1169,8 @@
                     isShowUI = false;
                     deviceFeatures[deviceIndex].mInitialRemoteVolume = absVol;
                     //Avoid fluction of volume during device add in blacklist
-                    if(deviceFeatures[deviceIndex].mBlackListVolume != -1) {
+                    if(deviceFeatures[deviceIndex].mBlackListVolume != -1 &&
+                       deviceFeatures[deviceIndex].isActiveDevice) {
                         resetBlackList(address);
                         if (DEBUG) Log.v(TAG, "remote initial volume as audio stream volume : " +
                             deviceFeatures[deviceIndex].mBlackListVolume);
@@ -1197,7 +1184,7 @@
                         break;
                     }
                     else if (mAbsVolThreshold > 0 && mAbsVolThreshold < mAudioStreamMax &&
-                        volIndex > mAbsVolThreshold) {
+                        volIndex > mAbsVolThreshold && deviceFeatures[deviceIndex].isActiveDevice) {
                         if (DEBUG) Log.v(TAG, "remote inital volume too high " + volIndex + ">" +
                             mAbsVolThreshold);
                         Message msg1 = mHandler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME,
@@ -2625,7 +2612,7 @@
         }
         if (requested || ((deviceFeatures[i].mLastReportedPosition != playPositionMs) &&
              ((playPositionMs >= deviceFeatures[i].mNextPosMs) ||
-             (playPositionMs <= deviceFeatures[i].mPrevPosMs)))) {
+             (playPositionMs <= deviceFeatures[i].mPrevPosMs))) && deviceFeatures[i].isActiveDevice) {
             if (!requested) deviceFeatures[i].mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
             if (deviceFeatures[i].mCurrentDevice != null)
                 registerNotificationRspPlayPosNative(deviceFeatures[i].mPlayPosChangedNT,
diff --git a/system_bt_ext/bta/Android.bp b/system_bt_ext/bta/Android.bp
index 5d79a17..8907668 100644
--- a/system_bt_ext/bta/Android.bp
+++ b/system_bt_ext/bta/Android.bp
@@ -39,4 +39,7 @@
         "libbt-utils",
     ],
     cflags: ["-DBUILDCFG"],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/system_bt_ext/bta/include/bta_ag_twsp_dev.h b/system_bt_ext/bta/include/bta_ag_twsp_dev.h
index 592038c..c1e2b23 100644
--- a/system_bt_ext/bta/include/bta_ag_twsp_dev.h
+++ b/system_bt_ext/bta/include/bta_ag_twsp_dev.h
@@ -64,10 +64,11 @@
 #define TWSPLUS_QDSP_ECHO_CANCELLATION 1
 
 enum {
-  TWSPLUS_EB_STATE_OFF,
+  TWSPLUS_EB_STATE_UNKNOWN,
   TWSPLUS_EB_STATE_INCASE,
   TWSPLUS_EB_STATE_OUT_OF_EAR,
   TWSPLUS_EB_STATE_INEAR,
+  TWSPLUS_EB_STATE_OFF
 };
 
 enum {
@@ -100,6 +101,7 @@
 bool twsp_get_right_eb_addr(RawAddress& eb_addr);
 bool twsp_get_left_eb_addr(RawAddress& eb_addr);
 uint8_t get_twsp_role(tBTA_AG_SCB *p_scb);
+uint8_t get_twsp_state(tBTA_AG_SCB *p_scb);
 tBTA_AG_SCB* twsp_get_best_mic_scb ();
 int twsp_get_idx_by_scb(tBTA_AG_SCB* p_scb);
 
diff --git a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
index 125e889..fde7388 100644
--- a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
+++ b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_dev.cc
@@ -84,7 +84,7 @@
 
     twsp_devices[eb_idx].p_scb = NULL;
     twsp_devices[eb_idx].battery_charge = TWSPLUS_MIN_BATTERY_CHARGE;
-    twsp_devices[eb_idx].state = TWSPLUS_EB_STATE_OFF;
+    twsp_devices[eb_idx].state = TWSPLUS_EB_STATE_UNKNOWN;
     twsp_devices[eb_idx].role =  TWSPLUS_EB_ROLE_INVALID;
     twsp_devices[eb_idx].mic_path_delay = TWSPLUS_INVALID_MICPATH_DELAY;
     twsp_devices[eb_idx].mic_quality = TWSPLUS_MIN_MIC_QUALITY;
@@ -99,7 +99,7 @@
             APPL_TRACE_WARNING("%s: idx: %d, p_scb: %x", __func__, i, p_scb);
             twsp_devices[i].p_scb = p_scb;
             twsp_devices[i].battery_charge = TWSPLUS_MIN_BATTERY_CHARGE;
-            twsp_devices[i].state = TWSPLUS_EB_STATE_OFF;
+            twsp_devices[i].state = TWSPLUS_EB_STATE_UNKNOWN;
 
             int other_idx = (i == PRIMARY_EB_IDX) ? SECONDARY_EB_IDX : PRIMARY_EB_IDX;
             if (twsp_devices[other_idx].p_scb != NULL &&
@@ -387,7 +387,7 @@
         return false;
     }
 
-    if (state < TWSPLUS_EB_STATE_OFF || state > TWSPLUS_EB_STATE_INEAR) {
+    if (state < TWSPLUS_EB_STATE_UNKNOWN || state > TWSPLUS_EB_STATE_INEAR) {
         APPL_TRACE_WARNING("%s: Invalid state: %d\n", __func__, state);
         return false;
     }
@@ -459,6 +459,20 @@
     return role;
 }
 
+uint8_t get_twsp_state(tBTA_AG_SCB *p_scb) {
+    APPL_TRACE_DEBUG("%s: p_scb : %d\n", __func__, p_scb);
+    uint8_t state = TWSPLUS_EB_STATE_UNKNOWN;
+    for (int i=0; i<=SECONDARY_EB_IDX; i++) {
+        if (p_scb == twsp_devices[i].p_scb)
+        {
+           state = twsp_devices[i].state;
+           break;
+        }
+    }
+    APPL_TRACE_DEBUG("%s: returns  : %d", __func__, state);
+    return state;
+}
+
 bool twsp_is_ring_sent(tBTA_AG_SCB *p_scb) {
     int sel_idx = -1;
     bool ret = false;
diff --git a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_sco.cc b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_sco.cc
index 5f6af9b..614c80d 100644
--- a/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_sco.cc
+++ b/system_bt_ext/bta/tws_plus/ag/bta_ag_twsp_sco.cc
@@ -315,7 +315,8 @@
                 bta_ag_create_sco(p_scb, false);
                 p_sco->state = BTA_AG_SCO_LISTEN_ST;
                 other_scb = get_other_twsp_scb((p_scb->peer_addr));
-                if (other_scb && twsp_sco_active(other_scb) == false) {
+                if (other_scb && twsp_sco_active(other_scb) == false &&
+                     get_twsp_state(other_scb) == TWSPLUS_EB_STATE_INEAR) {
                     //Atleast try bringing up the other EB eSCO
                     APPL_TRACE_WARNING("Calling SCO open for other EB");
                     dispatch_event_primary_peer_device(p_scb, BTA_AG_SCO_OPEN_E);
diff --git a/system_bt_ext/btconfigstore/Android.bp b/system_bt_ext/btconfigstore/Android.bp
index 2c82531..c1de2b1 100644
--- a/system_bt_ext/btconfigstore/Android.bp
+++ b/system_bt_ext/btconfigstore/Android.bp
@@ -33,4 +33,7 @@
     required: [
         "bt_configstore.conf",
     ],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/system_bt_ext/btif/Android.bp b/system_bt_ext/btif/Android.bp
index 76cfb3a..f6fbc99 100644
--- a/system_bt_ext/btif/Android.bp
+++ b/system_bt_ext/btif/Android.bp
@@ -51,5 +51,7 @@
         "-DBUILDCFG",
         "-DHAS_NO_BDROID_BUILDCFG",
     ],
-
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/system_bt_ext/conf/interop_database.conf b/system_bt_ext/conf/interop_database.conf
index b80522f..d909adf 100644
--- a/system_bt_ext/conf/interop_database.conf
+++ b/system_bt_ext/conf/interop_database.conf
@@ -8,7 +8,7 @@
 #1. Below are the four tags for blacklist
 #   A. Address_Based   C. Manufacturer_based
 #   B. Name_Based      D. Vndr_Prdt_Based
-#   E. SSR_Max_Lat_Based
+#   E. SSR_Max_Lat_Based F: Version_Based
 ##
 #   A. Address_Based :  This tag refers to Address based blacklist
 #   Input Type       :   Input value should be only 3 to 6 bytes of BD address
@@ -28,16 +28,21 @@
 #####
 #   D. Vndr_Prdt_Based : This tag refers to vendor and product based blacklist
 #   Input type  : Input should be in Hexadecimal value
-#   Format Type : 4 bytes hex value( 2bytes of vendor  and 2 bytes of product),
+#   Format Type : 4 bytes hex value( 2 bytes of vendor  and 2 bytes of product),
 #                 Vendor and product hex values should be separated with delimiter(-).
 #   Examples    : 0X00AB-0X00BC = Vndr_Prdt_Based
 #####
-#   E. SSR_Max_Lat_Based : This tag refers to SSR Max LAtency based blacklist
+#   E. SSR_Max_Lat_Based : This tag refers to SSR Max Latency based blacklist
 #   Input type  : Input value should be combination of first 3 bytes of BD address and
 #                 Hexadecimal value of SSR Max Latency
 #   Format Type : Address should be in XX:XX:XX format followed by 2 bytes hex value
 #                 of max latency Address and Max Latency should be separated with delimiter(-).
 #   Examples    : 00:01:03-0X00AB = SSR_Max_Lat_Based
+#####
+#   F. Version_Based : This tag refers to DID Version based blacklist
+#   Input type  : Input value should be Hexadecimal value
+#   Format Type : 2 bytes hex value
+#   Examples    : 0X00AB = Version_Based
 # ******************************* Start of Blacklist Database ********************************
 #Disable secure connections
 #This is for pre BT 4.1/2 devices that do not handle secure mode very well.
@@ -114,6 +119,7 @@
 00:1E:7C = Address_Based
 C8:84:47 = Address_Based
 D0:8A:55 = Address_Based
+48:F0:7B = Address_Based
 
 # Some HID pointing devices have proven problematic behaviour if pairing is initiated with
 # them, resulting in no response for authentication request and ultimately resulting
diff --git a/system_bt_ext/device/Android.bp b/system_bt_ext/device/Android.bp
index 44babef..8a83a90 100644
--- a/system_bt_ext/device/Android.bp
+++ b/system_bt_ext/device/Android.bp
@@ -28,4 +28,7 @@
         "libosi_qti",
         "libbluetooth-types",
     ],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/system_bt_ext/device/include/interop_config.h b/system_bt_ext/device/include/interop_config.h
index a2c5e62..35f3e8c 100644
--- a/system_bt_ext/device/include/interop_config.h
+++ b/system_bt_ext/device/include/interop_config.h
@@ -34,6 +34,7 @@
 void interop_database_add_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
 void interop_database_add_addr_max_lat(const interop_feature_t feature, const RawAddress *addr,
           size_t length, uint16_t max_lat);
+void interop_database_add_version(const interop_feature_t feature, uint16_t version);
 
 // API's for removing entries from dynamic interop database
 bool interop_database_remove_addr(const interop_feature_t feature, const RawAddress *addr);
@@ -42,6 +43,7 @@
 bool interop_database_remove_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
 bool interop_database_remove_addr_max_lat(const interop_feature_t feature,
           const RawAddress *addr, size_t length, uint16_t max_lat);
+bool interop_database_remove_version(const interop_feature_t feature, uint16_t version);
 
 // API's to match entries with in dynamic interop database
 bool interop_database_match_addr(const interop_feature_t feature, const RawAddress *addr);
@@ -50,4 +52,5 @@
 bool interop_database_match_vndr_prdt(const interop_feature_t feature, uint16_t vendor_id, uint16_t product_id);
 bool interop_database_match_addr_get_max_lat(const interop_feature_t feature,
           const RawAddress *addr, uint16_t *max_lat);
+bool interop_database_match_version(const interop_feature_t feature, uint16_t version);
 
diff --git a/system_bt_ext/device/src/interop.cc b/system_bt_ext/device/src/interop.cc
index 637fe44..2381669 100644
--- a/system_bt_ext/device/src/interop.cc
+++ b/system_bt_ext/device/src/interop.cc
@@ -69,6 +69,7 @@
 #define VALID_VNDR_PRDT_LEN   (13)
 #define VALID_MNFR_STR_LEN    (6)
 #define VALID_SSR_LAT_LEN   (15)
+#define VALID_VERSION_LEN   (6)
 #define VENDOR_VALUE_SEPARATOR  "-"
 
 #define ADDR_BASED    "Address_Based"
@@ -76,6 +77,7 @@
 #define MNFR_BASED    "Manufacturer_Based"
 #define VNDR_PRDT_BASED   "Vndr_Prdt_Based"
 #define SSR_MAX_LAT_BASED   "SSR_Max_Lat_Based"
+#define VERSION_BASED   "Version_Based"
 
 struct config_t {
   list_t *sections;
@@ -98,12 +100,18 @@
   interop_feature_t feature;
 } interop_hid_ssr_max_lat_t;
 
+typedef struct {
+  uint16_t version;
+  interop_feature_t feature;
+} interop_version_t;
+
 typedef enum {
     INTEROP_BL_TYPE_ADDR = 0,
     INTEROP_BL_TYPE_NAME,
     INTEROP_BL_TYPE_MANUFACTURE,
     INTEROP_BL_TYPE_VNDR_PRDT,
     INTEROP_BL_TYPE_SSR_MAX_LAT,
+    INTEROP_BL_TYPE_VERSION,
 
 } interop_bl_type;
 
@@ -123,6 +131,7 @@
         interop_manufacturer_t mnfr_entry;
         interop_hid_multitouch_t vnr_pdt_entry;
         interop_hid_ssr_max_lat_t ssr_max_lat_entry;
+        interop_version_t version_entry;
     } entry_type;
 
 } interop_db_entry_t;
@@ -488,6 +497,18 @@
         interop_config_flush();
         break;
       }
+    case INTEROP_BL_TYPE_VERSION:
+      {
+        interop_feature_t feature =
+          db_entry->entry_type.version_entry.feature;
+        char m_vendor[KEY_MAX_LENGTH] = { '\0' };
+        snprintf(m_vendor, sizeof(m_vendor), "0x%04x",
+            db_entry->entry_type.version_entry.version);
+        interop_config_set_str(interop_feature_string_(feature),
+            m_vendor, VERSION_BASED);
+        interop_config_flush();
+        break;
+      }
   }
 }
 
@@ -594,6 +615,20 @@
           }
           break;
         }
+      case INTEROP_BL_TYPE_VERSION:
+        {
+          interop_version_t *src = &entry->entry_type.version_entry;
+          interop_version_t *cur = &db_entry->entry_type.version_entry;
+
+          if ((src->feature == cur->feature) &&
+              (src->version == cur->version)) {
+            if (ret_entry) {
+              *ret_entry = db_entry;
+            }
+            found = true;
+          }
+          break;
+        }
     }
 
     if (found) {
@@ -690,6 +725,19 @@
         interop_config_flush();
         break;
       }
+    case INTEROP_BL_TYPE_VERSION:
+      {
+        interop_version_t *src = &entry->entry_type.version_entry;
+
+        interop_feature_t feature = src->feature;
+        char m_version[KEY_MAX_LENGTH] = { '\0' };
+        snprintf(m_version, sizeof(m_version), "0x%04x",
+            src->version);
+        interop_config_remove(interop_feature_string_(feature),
+            m_version);
+        interop_config_flush();
+        break;
+      }
     default:
     status = false;
   }
@@ -923,6 +971,28 @@
     entry->entry_type.ssr_max_lat_entry.length = len;
     entry->entry_type.ssr_max_lat_entry.max_lat = max_lat;
     interop_database_add_(entry, false);
+  } else if ( !strncasecmp( value, VERSION_BASED, strlen(VERSION_BASED))) {
+
+    uint16_t version;
+    char *e;
+
+    if ( strlen(key) != VALID_VERSION_LEN ) {
+      LOG_WARN(LOG_TAG,
+      " ignoring %s due to invalid version in config file", key);
+      return false;
+    }
+
+    version = (uint16_t)strtoul(key, &e, 16);
+    errno = 0;
+    if( *e || errno == EINVAL || errno == ERANGE )
+       return false;
+
+    interop_db_entry_t *entry = (interop_db_entry_t *)osi_calloc(sizeof(interop_db_entry_t));
+    entry->bl_type = INTEROP_BL_TYPE_VERSION;
+    entry->bl_entry_type = entry_type;
+    entry->entry_type.version_entry.feature = (interop_feature_t)feature;
+    entry->entry_type.version_entry.version = version;
+    interop_database_add_(entry, false);
   }
   LOG_WARN(LOG_TAG, " feature:: %d, key :: %s, value :: %s",
                     feature, key, value);
@@ -1065,6 +1135,17 @@
   interop_database_add_(entry, true);
 }
 
+void interop_database_add_version(const interop_feature_t feature, uint16_t version)
+{
+
+  interop_db_entry_t *entry = (interop_db_entry_t *)osi_calloc(sizeof(interop_db_entry_t));
+  entry->bl_type = INTEROP_BL_TYPE_VERSION;
+  entry->bl_entry_type = INTEROP_ENTRY_TYPE_DYNAMIC;
+  entry->entry_type.version_entry.feature = (interop_feature_t)feature;
+  entry->entry_type.version_entry.version = version;
+  interop_database_add_(entry, true);
+}
+
 bool interop_database_match_manufacturer(const interop_feature_t feature,
                       uint16_t manufacturer)
 {
@@ -1178,6 +1259,27 @@
   return false;
 }
 
+bool interop_database_match_version(const interop_feature_t feature, uint16_t version)
+{
+
+  interop_db_entry_t entry;
+  interop_db_entry_t *ret_entry = NULL;
+
+  entry.bl_type = INTEROP_BL_TYPE_VERSION;
+
+  entry.entry_type.version_entry.feature = (interop_feature_t)feature;
+  entry.entry_type.version_entry.version = version;
+  if (interop_database_match_(&entry, &ret_entry,  (interop_entry_type)(INTEROP_ENTRY_TYPE_STATIC  |
+    INTEROP_ENTRY_TYPE_DYNAMIC))) {
+    LOG_WARN(LOG_TAG,
+      "%s() Device with version: 0x%04x is a match for interop workaround %s", __func__, version,
+      interop_feature_string_(feature));
+    return true;
+  }
+
+  return false;
+}
+
 bool interop_database_remove_name( const interop_feature_t feature, const char *name)
 {
   assert(name);
@@ -1291,3 +1393,25 @@
   return false;
 }
 
+bool interop_database_remove_version(const interop_feature_t feature, uint16_t version)
+{
+
+  interop_db_entry_t entry;
+
+  entry.bl_type = INTEROP_BL_TYPE_VERSION;
+  entry.bl_entry_type = INTEROP_ENTRY_TYPE_DYNAMIC;
+
+  entry.entry_type.version_entry.feature = (interop_feature_t)feature;
+  entry.entry_type.version_entry.version = version;
+
+  if (interop_database_remove_(&entry)) {
+    LOG_WARN(LOG_TAG,
+      "%s() Device with version: 0x%04x is removed from"
+      "interop workaround %s", __func__, version,
+      interop_feature_string_(feature));
+    return true;
+  }
+  return false;
+}
+
+
diff --git a/system_bt_ext/osi/Android.bp b/system_bt_ext/osi/Android.bp
index 456ab11..438e8fe 100644
--- a/system_bt_ext/osi/Android.bp
+++ b/system_bt_ext/osi/Android.bp
@@ -24,4 +24,7 @@
         "libbt-utils",
     ],
     cflags: ["-DBUILDCFG"],
+    sanitize: {
+        never: true,
+    },
 }
diff --git a/system_bt_ext/stack/Android.bp b/system_bt_ext/stack/Android.bp
index cca03cb..97b18e6 100644
--- a/system_bt_ext/stack/Android.bp
+++ b/system_bt_ext/stack/Android.bp
@@ -39,4 +39,7 @@
         "libcutils",
         "liblog",
     ],
+    sanitize: {
+        never: true,
+    },
 }