Merge "Fix an "array index out of bound" bug for RPA." into lmp-dev
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 4f7e908..8964f5c 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -678,10 +678,6 @@
 
     btif_config_flush();
 
-#if (BLE_INCLUDED == TRUE)
-     BTA_VendorCleanup();
-#endif
-
     if (status != BTA_SUCCESS)
     {
         BTIF_TRACE_ERROR("disable bt failed (%d)", status);
@@ -714,7 +710,11 @@
     bte_main_enable_lpm(FALSE);
 #endif
 
-    bte_main_disable();
+#if (BLE_INCLUDED == TRUE)
+     BTA_VendorCleanup();
+#endif
+
+     bte_main_disable();
 
     /* update local state */
     btif_core_state = BTIF_CORE_STATE_DISABLED;
diff --git a/hci/src/bt_hci_bdroid.c b/hci/src/bt_hci_bdroid.c
index 4038424..74a315b 100644
--- a/hci/src/bt_hci_bdroid.c
+++ b/hci/src/bt_hci_bdroid.c
@@ -357,14 +357,17 @@
         ALOGW("init has been called repeatedly without calling cleanup ?");
     }
 
+    // Set prio here and let hci worker thread inherit prio
+    // remove once new thread api (thread_set_priority() ?)
+    // can switch prio
+    raise_priority_a2dp(TASK_HIGH_HCI_WORKER);
+
     hc_cb.worker_thread = thread_new("bt_hc_worker");
     if (!hc_cb.worker_thread) {
         ALOGE("%s unable to create worker thread.", __func__);
         return BT_HC_STATUS_FAIL;
     }
 
-    // TODO(sharvil): increase thread priority (raise_priority_a2dp)
-
     return BT_HC_STATUS_SUCCESS;
 }
 
diff --git a/stack/btm/btm_ble.c b/stack/btm/btm_ble.c
index a40fc9e..9b8a7bb 100644
--- a/stack/btm/btm_ble.c
+++ b/stack/btm/btm_ble.c
@@ -1660,7 +1660,7 @@
 
         /* possiblly receive connection complete with resolvable random on
            slave role while the device has been paired */
-        if (!match && role == HCI_ROLE_SLAVE && BTM_BLE_IS_RESOLVE_BDA(bda))
+        if (!match && /*role == HCI_ROLE_SLAVE && */BTM_BLE_IS_RESOLVE_BDA(bda))
         {
             btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_conn_cmpl, p_data);
         }
diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c
index f66c559..a6f095f 100644
--- a/stack/btm/btm_ble_gap.c
+++ b/stack/btm/btm_ble_gap.c
@@ -467,6 +467,10 @@
     if (btm_cb.cmn_ble_vsc_cb.max_filter > 0)
     {
         btm_ble_adv_filter_init();
+    }
+
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz > 0)
+    {
         btm_ble_vendor_init(btm_cb.cmn_ble_vsc_cb.max_irk_list_sz);
     }
 
@@ -1716,8 +1720,7 @@
 
 #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
         /* enable IRK list */
-        if (btm_cb.cmn_ble_vsc_cb.rpa_offloading == TRUE)
-            btm_ble_vendor_irk_list_known_dev (TRUE);
+        btm_ble_vendor_irk_list_known_dev (TRUE);
 #endif
         status = btm_ble_start_scan(BTM_BLE_DUPLICATE_DISABLE);
     }
@@ -3041,12 +3044,6 @@
         /* toggle back the adv mode */
         p_cb->adv_mode = !p_cb->adv_mode;
     }
-
-#if (BLE_PRIVACY_SPT == TRUE)
-    if ((p_cb->adv_mode == BTM_BLE_ADV_DISABLE) &&
-        (btm_cb.cmn_ble_vsc_cb.rpa_offloading == TRUE))
-        btm_ble_vendor_disable_irk_list();
-#endif
 }
 
 /*******************************************************************************
diff --git a/stack/btu/btu_task.c b/stack/btu/btu_task.c
index 3db8d7e..24a1194 100644
--- a/stack/btu/btu_task.c
+++ b/stack/btu/btu_task.c
@@ -39,6 +39,7 @@
 #include "l2c_int.h"
 #include "btu.h"
 #include "bt_utils.h"
+#include <sys/prctl.h>
 
 #include "sdpint.h"
 
@@ -221,6 +222,8 @@
     /* Send a startup evt message to BTIF_TASK to kickstart the init procedure */
     GKI_send_event(BTIF_TASK, BT_EVT_TRIGGER_STACK_INIT);
 
+    prctl(PR_SET_NAME, (unsigned long)"BTU TASK", 0, 0, 0);
+
     raise_priority_a2dp(TASK_HIGH_BTU);
 
     /* Wait for, and process, events */
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index 2b933e8..1bafe67 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -648,9 +648,14 @@
     memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
 
 #if BLE_PRIVACY_SPT == TRUE
-    if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
+    /* if RPA offloading supported */
+    if (btm_ble_vendor_irk_list_load_dev(p_dev_rec))
+        btm_random_pseudo_to_public(init_addr, &init_addr_type);
+    /* otherwise, if remote is RPA enabled, use latest RPA */
+    else if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
     {
         init_addr_type = BLE_ADDR_RANDOM;
+        memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
     }
     /* if privacy is on and current do not consider using reconnection address */
     if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
@@ -663,12 +668,6 @@
         L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation");
         return FALSE;
     }
-    if (btm_ble_vendor_irk_list_load_dev(p_dev_rec) &&
-        (btm_cb.cmn_ble_vsc_cb.rpa_offloading == TRUE ))
-    {
-        btm_ble_vendor_enable_irk_feature(TRUE);
-        btm_random_pseudo_to_public(init_addr, &init_addr_type);
-    }
 
     if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int      */
                                         scan_win, /* UINT16 scan_win      */
diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c
index a876076..b9caa1b 100644
--- a/udrv/ulinux/uipc.c
+++ b/udrv/ulinux/uipc.c
@@ -480,6 +480,8 @@
 
     prctl(PR_SET_NAME, (unsigned long)"uipc-main", 0, 0, 0);
 
+    raise_priority_a2dp(TASK_UIPC_READ);
+
     while (uipc_main.running)
     {
         uipc_main.read_set = uipc_main.active_set;
diff --git a/utils/include/bt_utils.h b/utils/include/bt_utils.h
index 512e1b5..47f0e30 100644
--- a/utils/include/bt_utils.h
+++ b/utils/include/bt_utils.h
@@ -29,6 +29,7 @@
     TASK_HIGH_BTU,
     TASK_HIGH_HCI_WORKER,
     TASK_HIGH_USERIAL_READ,
+    TASK_UIPC_READ,
     TASK_HIGH_MAX
 } tHIGH_PRIORITY_TASK;
 
diff --git a/utils/src/bt_utils.c b/utils/src/bt_utils.c
index df1fd04..ab618b0 100644
--- a/utils/src/bt_utils.c
+++ b/utils/src/bt_utils.c
@@ -120,6 +120,7 @@
 void raise_priority_a2dp(tHIGH_PRIORITY_TASK high_task) {
     int rc = 0;
     int tid = gettid();
+    int priority = ANDROID_PRIORITY_AUDIO;
 
     pthread_mutex_lock(&gIdxLock);
     g_TaskIdx = high_task;
@@ -136,8 +137,15 @@
         ALOGW("failed to change sched policy, tid %d, err: %d", tid, errno);
     }
 
-    if (setpriority(PRIO_PROCESS, tid, ANDROID_PRIORITY_AUDIO) < 0) {
-        ALOGW("failed to change priority tid: %d to %d", tid, ANDROID_PRIORITY_AUDIO);
+    // always use urgent priority for HCI worker thread until we can adjust
+    // its prio individually. All other threads can be dynamically adjusted voa
+    // adjust_priority_a2dp()
+
+    if (high_task == TASK_HIGH_HCI_WORKER)
+       priority = ANDROID_PRIORITY_URGENT_AUDIO;
+
+    if (setpriority(PRIO_PROCESS, tid, priority) < 0) {
+        ALOGW("failed to change priority tid: %d to %d", tid, priority);
     }
 }
 
@@ -157,7 +165,7 @@
     int tid;
     int i;
 
-    for (i = TASK_HIGH_GKI_TIMER; i < TASK_HIGH_MAX; i++)
+    for (i = 0; i < TASK_HIGH_MAX; i++)
     {
         tid = g_TaskIDs[i];
         if (tid != INVALID_TASK_ID)
diff --git a/vnd/ble/vendor_ble.c b/vnd/ble/vendor_ble.c
index be436a7..61d6780 100644
--- a/vnd/ble/vendor_ble.c
+++ b/vnd/ble/vendor_ble.c
@@ -68,7 +68,7 @@
     p_q->irk_q_action[p_q->q_next] = to_add;
 
     p_q->q_next ++;
-    p_q->q_next %= btm_cb.cmn_ble_vsc_cb.max_irk_list_sz;;
+    p_q->q_next %= btm_cb.cmn_ble_vsc_cb.max_irk_list_sz;
 #endif
     return ;
 }
@@ -389,6 +389,9 @@
     tBTM_STATUS     st;
     tBTM_BLE_VENDOR_CB  *p_cb = &btm_ble_vendor_cb;
 
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return BTM_MODE_UNSUPPORTED;
+
     p = param;
     memset(param, 0, 20);
 
@@ -427,6 +430,9 @@
     UINT8           param[20], *p;
     tBTM_STATUS     st;
 
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return BTM_MODE_UNSUPPORTED;
+
     p = param;
     memset(param, 0, 20);
 
@@ -457,9 +463,12 @@
 #if BLE_PRIVACY_SPT == TRUE
     UINT8           param[20], *p;
     tBTM_STATUS     st = BTM_UNKNOWN_ADDR;
-    tBTM_BLE_IRK_ENTRY *p_entry = btm_ble_vendor_find_irk_entry(target_bda);
+    tBTM_BLE_IRK_ENTRY *p_entry;
 
-    if (p_entry == NULL)
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return BTM_MODE_UNSUPPORTED;
+
+    if ((p_entry = btm_ble_vendor_find_irk_entry(target_bda)) == NULL)
         return st;
 
     p = param;
@@ -498,6 +507,9 @@
     UINT8               count = 0;
     tBTM_SEC_DEV_REC    *p_dev_rec = &btm_cb.sec_dev_rec[0];
 
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return;
+
     /* add all known device with random address into IRK list */
     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i ++, p_dev_rec ++)
     {
@@ -534,6 +546,9 @@
     BTM_TRACE_DEBUG ("btm_ble_vendor_irk_list_load_dev:max_irk_size=%d", p_cb->irk_avail_size);
     memset(param, 0, 40);
 
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return FALSE;
+
     if (p_dev_rec != NULL && /* RPA is being used and PID is known */
         (p_dev_rec->ble.key_type & BTM_LE_KEY_PID) != 0)
     {
@@ -560,6 +575,8 @@
                     btm_ble_vendor_enq_irk_pending(p_dev_rec->ble.static_addr, p_dev_rec->bd_addr, TRUE);
                     p_cb->irk_list_size ++;
                     rt = TRUE;
+
+                    btm_ble_vendor_enable_irk_feature(TRUE);
                 }
             }
         }
@@ -594,6 +611,9 @@
     tBTM_BLE_VENDOR_CB  *p_cs_cb = &btm_ble_vendor_cb;
     tBTM_BLE_IRK_ENTRY *p_irk_entry;
 
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return;
+
     if ((p_irk_entry = btm_ble_vendor_find_irk_entry_by_psuedo_addr(p_dev_rec->bd_addr)) != NULL &&
         btm_ble_vendor_find_irk_pending_entry(p_dev_rec->bd_addr, FALSE) == FALSE)
     {
@@ -645,15 +665,23 @@
     tBTM_STATUS     st = BTM_WRONG_MODE;
     tBTM_BLE_PF_COUNT *p_bda_filter;
 
-    p = param;
-    memset(param, 0, 20);
+    if (btm_cb.cmn_ble_vsc_cb.max_irk_list_sz == 0)
+        return BTM_MODE_UNSUPPORTED;
 
-    /* select feature based on control block settings */
-    UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
-    UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
+    if (btm_ble_vendor_cb.enable != enable)
+    {
+        p = param;
+        memset(param, 0, 20);
 
-    st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
-                               param, btm_ble_vendor_irk_vsc_op_cmpl);
+        /* select feature based on control block settings */
+        UINT8_TO_STREAM(p, BTM_BLE_META_IRK_ENABLE);
+        UINT8_TO_STREAM(p, enable ? 0x01 : 0x00);
+
+        st = BTM_VendorSpecificCommand (HCI_VENDOR_BLE_RPA_VSC, BTM_BLE_IRK_ENABLE_LEN,
+                                        param, btm_ble_vendor_irk_vsc_op_cmpl);
+
+        btm_ble_vendor_cb.enable = enable;
+    }
 
     return st;
 #endif