Add API ignore_auto_connect_after_disconnect

Bug: 180781174
Test: cert
Tag: #refactor

Change-Id: Ic587965e57c87174cb39bd0b79321c22842dbbad
diff --git a/system/stack/acl/acl.cc b/system/stack/acl/acl.cc
index d0377fd..acae99e 100644
--- a/system/stack/acl/acl.cc
+++ b/system/stack/acl/acl.cc
@@ -14,7 +14,12 @@
  * limitations under the License.
  */
 
+#include <unordered_set>
+
+#include "main/shim/dumpsys.h"
+#include "osi/include/log.h"
 #include "stack/acl/acl.h"
+#include "types/raw_address.h"
 
 tBTM_PM_MODE tACL_CONN::sPolicy::Mode() const { return this->mode.mode_; }
 
@@ -46,3 +51,26 @@
   switch_role_state_ = BTM_ACL_SWKEY_STATE_IDLE;
   sca = 0;
 }
+
+// When the local device initiates an le ACL disconnect the address
+// should not be re-added to the acceptlist.
+void tACL_CB::AddToIgnoreAutoConnectAfterDisconnect(const RawAddress& bd_addr) {
+  if (!ignore_auto_connect_after_disconnect_set_.insert(bd_addr).second) {
+    LOG_WARN(
+        "Unexpectedly found device address already in ignore auto connect "
+        "device:%s",
+        PRIVATE_ADDRESS(bd_addr));
+  }
+}
+
+// A check and clear mechanism used to determine if the address should be
+// re-added to the acceptlist after an le ACL disconnect is received from a
+// peer.
+bool tACL_CB::CheckAndClearIgnoreAutoConnectAfterDisconnect(
+    const RawAddress& bd_addr) {
+  return (ignore_auto_connect_after_disconnect_set_.erase(bd_addr) > 0);
+}
+
+void tACL_CB::ClearAllIgnoreAutoConnectAfterDisconnect() {
+  ignore_auto_connect_after_disconnect_set_.clear();
+}
diff --git a/system/stack/acl/acl.h b/system/stack/acl/acl.h
index ed20b61..1aa21e5 100644
--- a/system/stack/acl/acl.h
+++ b/system/stack/acl/acl.h
@@ -18,6 +18,7 @@
 
 #include <cstdint>
 #include <string>
+#include <unordered_set>
 #include <vector>
 
 #include "stack/include/acl_api_types.h"
@@ -409,4 +410,12 @@
     }
     return cnt;
   }
+
+ private:
+  std::unordered_set<RawAddress> ignore_auto_connect_after_disconnect_set_;
+
+ public:
+  void AddToIgnoreAutoConnectAfterDisconnect(const RawAddress& bd_addr);
+  bool CheckAndClearIgnoreAutoConnectAfterDisconnect(const RawAddress& bd_addr);
+  void ClearAllIgnoreAutoConnectAfterDisconnect();
 };
diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc
index 4a54ce0..78d3e54 100644
--- a/system/stack/acl/btm_acl.cc
+++ b/system/stack/acl/btm_acl.cc
@@ -2867,3 +2867,17 @@
 
   return HCI_LMP_TRANSPNT_SUPPORTED(p_acl->peer_lmp_feature_pages[0]);
 }
+
+void acl_add_to_ignore_auto_connect_after_disconnect(
+    const RawAddress& bd_addr) {
+  btm_cb.acl_cb_.AddToIgnoreAutoConnectAfterDisconnect(bd_addr);
+}
+
+bool acl_check_and_clear_ignore_auto_connect_after_disconnect(
+    const RawAddress& bd_addr) {
+  return btm_cb.acl_cb_.CheckAndClearIgnoreAutoConnectAfterDisconnect(bd_addr);
+}
+
+void acl_clear_all_ignore_auto_connect_after_disconnect() {
+  btm_cb.acl_cb_.ClearAllIgnoreAutoConnectAfterDisconnect();
+}
diff --git a/system/stack/include/acl_api.h b/system/stack/include/acl_api.h
index a635678..dc0cfce 100644
--- a/system/stack/include/acl_api.h
+++ b/system/stack/include/acl_api.h
@@ -310,3 +310,8 @@
 void ACL_RegisterClient(struct acl_client_callback_s* callbacks);
 void ACL_UnregisterClient(struct acl_client_callback_s* callbacks);
 bool ACL_SupportTransparentSynchronousData(const RawAddress& bd_addr);
+
+void acl_add_to_ignore_auto_connect_after_disconnect(const RawAddress& bd_addr);
+bool acl_check_and_clear_ignore_auto_connect_after_disconnect(
+    const RawAddress& bd_addr);
+void acl_clear_all_ignore_auto_connect_after_disconnect();
diff --git a/system/stack/test/common/mock_acl.cc b/system/stack/test/common/mock_acl.cc
new file mode 100644
index 0000000..1349443
--- /dev/null
+++ b/system/stack/test/common/mock_acl.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Generated mock file from original source file
+ *   Functions generated:14
+ */
+
+#include <map>
+#include <string>
+
+extern std::map<std::string, int> mock_function_count_map;
+
+#define LOG_TAG "bt_shim"
+#include "gd/common/init_flags.h"
+#include "gd/os/log.h"
+#include "main/shim/entry.h"
+#include "main/shim/shim.h"
+#include "types/raw_address.h"
+
+#ifndef UNUSED_ATTR
+#define UNUSED_ATTR
+#endif
+
+void acl_add_to_ignore_auto_connect_after_disconnect(
+    const RawAddress& bd_addr) {
+  mock_function_count_map[__func__]++;
+}
+
+bool acl_check_and_clear_ignore_auto_connect_after_disconnect(
+    const RawAddress& bd_addr) {
+  mock_function_count_map[__func__]++;
+  return false;
+}
+
+void acl_clear_all_ignore_auto_connect_after_disconnect() {
+  mock_function_count_map[__func__]++;
+}