Snap for 6949450 from 59e34d30a1b92f70bf32f9b0dfc5687874dc5e88 to android11-tests-release

Change-Id: Idfd0e74d0fecd45d639c66a5d262430a330f936a
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index f0da558..d1b260c 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -3804,6 +3804,16 @@
 
       break;
 
+    case BTM_LE_CONSENT_REQ_EVT:
+      sec_event.ble_req.bd_addr = bda;
+      p_name = BTM_SecReadDevName(bda);
+      if (p_name != NULL)
+        strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
+      else
+        sec_event.ble_req.bd_name[0] = 0;
+      bta_dm_cb.p_sec_cback(BTA_DM_BLE_CONSENT_REQ_EVT, &sec_event);
+      break;
+
     case BTM_LE_SEC_REQUEST_EVT:
       sec_event.ble_req.bd_addr = bda;
       p_name = BTM_SecReadDevName(bda);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 5079232..b7d7d30 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -380,6 +380,7 @@
                                     */
 #define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
 #define BTA_DM_BLE_SC_OOB_REQ_EVT 29 /* SMP SC OOB request event */
+#define BTA_DM_BLE_CONSENT_REQ_EVT 30 /* SMP consent request event */
 typedef uint8_t tBTA_DM_SEC_EVT;
 
 /* Structure associated with BTA_DM_ENABLE_EVT */
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index 31c5e77..f9b8886 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -134,6 +134,18 @@
 
 /*******************************************************************************
  *
+ * Function         is_atv_device
+ *
+ * Description      Returns true if the local device is an Android TV
+ *                  device, false if it is not.
+ *
+ * Returns          bool
+ *
+ ******************************************************************************/
+bool is_atv_device(void);
+
+/*******************************************************************************
+ *
  * Function         btif_get_adapter_properties
  *
  * Description      Fetches all local adapter properties
diff --git a/btif/include/btif_dm.h b/btif/include/btif_dm.h
index 63ff0e7..fae8929 100644
--- a/btif/include/btif_dm.h
+++ b/btif/include/btif_dm.h
@@ -102,7 +102,7 @@
                                 tBTA_BLE_LOCAL_ID_KEYS* p_id_keys);
 void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr);
 void btif_dm_remove_ble_bonding_keys(void);
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req);
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent);
 
 void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr,
                                           BD_NAME bd_name,
diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc
index 0187b1d..a00c0c6 100644
--- a/btif/src/bluetooth.cc
+++ b/btif/src/bluetooth.cc
@@ -88,6 +88,7 @@
 bool niap_mode = false;
 const int CONFIG_COMPARE_ALL_PASS = 0b11;
 int niap_config_compare_result = CONFIG_COMPARE_ALL_PASS;
+bool is_local_device_atv = false;
 
 /*******************************************************************************
  *  Externs
@@ -140,7 +141,7 @@
  ****************************************************************************/
 
 static int init(bt_callbacks_t* callbacks, bool start_restricted,
-                bool is_niap_mode, int config_compare_result) {
+                bool is_niap_mode, int config_compare_result, bool is_atv) {
   LOG_INFO(LOG_TAG,
            "%s: start restricted = %d ; niap = %d, config compare result = %d",
            __func__, start_restricted, is_niap_mode, config_compare_result);
@@ -161,6 +162,7 @@
   restricted_mode = start_restricted;
   niap_mode = is_niap_mode;
   niap_config_compare_result = config_compare_result;
+  is_local_device_atv = is_atv;
 
   stack_manager_get_interface()->init_stack();
   btif_debug_init();
@@ -191,6 +193,8 @@
   return niap_mode ? niap_config_compare_result : CONFIG_COMPARE_ALL_PASS;
 }
 
+bool is_atv_device() { return is_local_device_atv; }
+
 static int get_adapter_properties(void) {
   /* sanity check */
   if (!interface_ready()) return BT_STATUS_NOT_READY;
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index f2fcee8..48d3290 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -1816,9 +1816,13 @@
           break;
       }
       break;
+    case BTA_DM_BLE_CONSENT_REQ_EVT:
+      BTIF_TRACE_DEBUG("BTA_DM_BLE_CONSENT_REQ_EVT. ");
+      btif_dm_ble_sec_req_evt(&p_data->ble_req, true);
+      break;
     case BTA_DM_BLE_SEC_REQ_EVT:
       BTIF_TRACE_DEBUG("BTA_DM_BLE_SEC_REQ_EVT. ");
-      btif_dm_ble_sec_req_evt(&p_data->ble_req);
+      btif_dm_ble_sec_req_evt(&p_data->ble_req, false);
       break;
     case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
       BTIF_TRACE_DEBUG("BTA_DM_BLE_PASSKEY_NOTIF_EVT. ");
@@ -3028,14 +3032,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req) {
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent) {
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
 
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+  if (!is_consent && pairing_cb.state == BT_BOND_STATE_BONDING) {
     BTIF_TRACE_DEBUG("%s Discard security request", __func__);
     return;
   }
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 8ac32b2..4251005 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -473,9 +473,10 @@
    * The |is_niap_mode| flag inits the adapter in NIAP mode.
    * The |config_compare_result| flag show the config checksum check result if
    * is in NIAP mode.
+   * The |is_atv| flag indicates whether the local device is an Android TV
    */
   int (*init)(bt_callbacks_t* callbacks, bool guest_mode, bool is_niap_mode,
-              int config_compare_result);
+              int config_compare_result, bool is_atv);
 
   /** Enable Bluetooth. */
   int (*enable)();
diff --git a/service/hal/bluetooth_interface.cc b/service/hal/bluetooth_interface.cc
index 8043785..42eeb00 100644
--- a/service/hal/bluetooth_interface.cc
+++ b/service/hal/bluetooth_interface.cc
@@ -254,7 +254,7 @@
 
     // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
     // callbacks.
-    status = hal_iface_->init(&bt_callbacks, false, false, 0);
+    status = hal_iface_->init(&bt_callbacks, false, false, 0, false);
     if (status != BT_STATUS_SUCCESS) {
       LOG(ERROR) << "Failed to initialize Bluetooth stack";
       return false;
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index 1c4aa37..06a597a 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -2012,6 +2012,7 @@
         p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
         FALLTHROUGH_INTENDED; /* FALLTHROUGH */
 
+      case SMP_CONSENT_REQ_EVT:
       case SMP_SEC_REQUEST_EVT:
         if (event == SMP_SEC_REQUEST_EVT &&
             btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) {
@@ -2019,7 +2020,9 @@
           break;
         }
         btm_cb.pairing_bda = bd_addr;
-        p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+        if (event != SMP_CONSENT_REQ_EVT) {
+          p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+        }
         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
         FALLTHROUGH_INTENDED; /* FALLTHROUGH */
 
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 63e4f6c..5d7d0f9 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4358,6 +4358,7 @@
               << p_dev_rec->bd_addr;
 
     bta_dm_remove_device(p_dev_rec->bd_addr);
+    return;
   }
 
   BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h
index b291ce5..05f12f0 100755
--- a/stack/include/btm_api_types.h
+++ b/stack/include/btm_api_types.h
@@ -1504,6 +1504,7 @@
 #define BTM_LE_LAST_FROM_SMP BTM_LE_BR_KEYS_REQ_EVT
 /* KEY update event */
 #define BTM_LE_KEY_EVT (BTM_LE_LAST_FROM_SMP + 1)
+#define BTM_LE_CONSENT_REQ_EVT SMP_CONSENT_REQ_EVT
 typedef uint8_t tBTM_LE_EVT;
 
 #define BTM_LE_KEY_NONE 0
diff --git a/stack/include/smp_api_types.h b/stack/include/smp_api_types.h
index cee1204..96e7d9e 100644
--- a/stack/include/smp_api_types.h
+++ b/stack/include/smp_api_types.h
@@ -59,6 +59,7 @@
 /* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */
 #define SMP_SC_LOC_OOB_DATA_UP_EVT 10
 #define SMP_BR_KEYS_REQ_EVT 12 /* SMP over BR keys request event */
+#define SMP_CONSENT_REQ_EVT 14 /* Consent request event */
 typedef uint8_t tSMP_EVT;
 
 /* pairing failure reason code */
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 21b960b..22d9958 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -19,6 +19,7 @@
 #include <cutils/log.h>
 #include <log/log.h>
 #include <string.h>
+#include "btif_api.h"
 #include "btif_common.h"
 #include "btif_storage.h"
 #include "device/include/interop.h"
@@ -1301,18 +1302,28 @@
         smp_int_data.status = SMP_PAIR_AUTH_FAIL;
         int_evt = SMP_AUTH_CMPL_EVT;
       } else {
-        p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
-        SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
-                        p_cb->sec_level);
+        if (!is_atv_device() &&
+            (p_cb->local_io_capability == SMP_IO_CAP_IO ||
+             p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) {
+          /* display consent dialog if this device has a display */
+          SMP_TRACE_DEBUG("ENCRYPTION_ONLY showing Consent Dialog");
+          p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+          smp_set_state(SMP_STATE_WAIT_NONCE);
+          smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+        } else {
+          p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
+          SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
+                          p_cb->sec_level);
 
-        tSMP_KEY key;
-        key.key_type = SMP_KEY_TYPE_TK;
-        key.p_data = p_cb->tk.data();
-        smp_int_data.key = key;
+          tSMP_KEY key;
+          key.key_type = SMP_KEY_TYPE_TK;
+          key.p_data = p_cb->tk.data();
+          smp_int_data.key = key;
 
-        p_cb->tk = {0};
-        /* TK, ready  */
-        int_evt = SMP_KEY_READY_EVT;
+          p_cb->tk = {0};
+          /* TK, ready  */
+          int_evt = SMP_KEY_READY_EVT;
+        }
       }
       break;
 
@@ -1647,8 +1658,18 @@
       }
 
       if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
-        /* go directly to phase 2 */
-        smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+        if (!is_atv_device() &&
+            (p_cb->local_io_capability == SMP_IO_CAP_IO ||
+             p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) {
+          /* display consent dialog */
+          SMP_TRACE_DEBUG("JUST WORKS showing Consent Dialog");
+          p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+          smp_set_state(SMP_STATE_WAIT_NONCE);
+          smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+        } else {
+          /* go directly to phase 2 */
+          smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+        }
       } else /* numeric comparison */
       {
         smp_set_state(SMP_STATE_WAIT_NONCE);
diff --git a/stack/smp/smp_api.cc b/stack/smp/smp_api.cc
index e082356..f2c7ed8 100644
--- a/stack/smp/smp_api.cc
+++ b/stack/smp/smp_api.cc
@@ -249,6 +249,44 @@
 void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res) {
   SMP_TRACE_EVENT("SMP_SecurityGrant ");
 
+  // If just showing consent dialog, send response
+  if (smp_cb.cb_evt == SMP_CONSENT_REQ_EVT) {
+    // If JUSTWORKS, this is used to display the consent dialog
+    if (smp_cb.selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
+      if (res == SMP_SUCCESS) {
+        smp_sm_event(&smp_cb, SMP_SC_NC_OK_EVT, NULL);
+      } else {
+        SMP_TRACE_WARNING("%s() - Consent dialog fails for JUSTWORKS",
+                          __func__);
+        /* send pairing failure */
+        tSMP_INT_DATA smp_int_data;
+        smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+        smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+      }
+    } else if (smp_cb.selected_association_model == SMP_MODEL_ENCRYPTION_ONLY) {
+      if (res == SMP_SUCCESS) {
+        smp_cb.sec_level = SMP_SEC_UNAUTHENTICATE;
+
+        tSMP_KEY key;
+        tSMP_INT_DATA smp_int_data;
+        key.key_type = SMP_KEY_TYPE_TK;
+        key.p_data = smp_cb.tk.data();
+        smp_int_data.key = key;
+
+        smp_cb.tk = {0};
+        smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &smp_int_data);
+      } else {
+        SMP_TRACE_WARNING("%s() - Consent dialog fails for ENCRYPTION_ONLY",
+                          __func__);
+        /* send pairing failure */
+        tSMP_INT_DATA smp_int_data;
+        smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+        smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+      }
+    }
+    return;
+  }
+
   if (smp_cb.smp_over_br) {
     if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
         smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) {
diff --git a/test/headless/headless.cc b/test/headless/headless.cc
index 4eadcb6..9083e9c 100644
--- a/test/headless/headless.cc
+++ b/test/headless/headless.cc
@@ -141,7 +141,7 @@
 void HeadlessStack::SetUp() {
   LOG(INFO) << __func__ << " Entry";
 
-  int status = bluetoothInterface.init(&bt_callbacks, false, false, 0);
+  int status = bluetoothInterface.init(&bt_callbacks, false, false, 0, false);
   (status == BT_STATUS_SUCCESS)
       ? LOG(INFO) << __func__ << " Initialized bluetooth callbacks"
       : LOG(FATAL) << "Failed to initialize Bluetooth stack";
diff --git a/test/suite/adapter/adapter_unittest.cc b/test/suite/adapter/adapter_unittest.cc
index d68ad0f..85549b0 100644
--- a/test/suite/adapter/adapter_unittest.cc
+++ b/test/suite/adapter/adapter_unittest.cc
@@ -179,7 +179,7 @@
   ASSERT_TRUE(bt_callbacks != nullptr);
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    bt_interface()->init(bt_callbacks, false, false, 0);
+    bt_interface()->init(bt_callbacks, false, false, 0, false);
     EXPECT_EQ(bt_interface()->enable(), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";