Check whether local device is an ATV device to determine whether to show
the consent dialog for BLE pairing in JUSTWORKS and ENCRYPTION_ONLY mode

Tag: #feature
Bug: 157038281
Test: Manual
Merged-In: I6d06f5996da71e5a1407e544b0023d82924aa56f
Change-Id: I6d06f5996da71e5a1407e544b0023d82924aa56f
(cherry picked from commit e198eb931d834a3117005f31ece43a83ecc0cd60)
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/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/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/smp/smp_act.cc b/stack/smp/smp_act.cc
index 1239542..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,8 +1302,9 @@
         smp_int_data.status = SMP_PAIR_AUTH_FAIL;
         int_evt = SMP_AUTH_CMPL_EVT;
       } else {
-        if (p_cb->local_io_capability != SMP_IO_CAP_NONE &&
-            p_cb->local_io_capability != SMP_IO_CAP_IN) {
+        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;
@@ -1656,8 +1658,9 @@
       }
 
       if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
-        if (p_cb->local_io_capability != SMP_IO_CAP_NONE &&
-            p_cb->local_io_capability != SMP_IO_CAP_IN) {
+        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;
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.";