Merge "L2CAP ERTM initial commit"
diff --git a/binder/android/bluetooth/IBluetooth.aidl b/binder/android/bluetooth/IBluetooth.aidl
index fa2b063..d095682 100644
--- a/binder/android/bluetooth/IBluetooth.aidl
+++ b/binder/android/bluetooth/IBluetooth.aidl
@@ -146,4 +146,7 @@
 
     void onLeServiceUp();
     void onBrEdrDown();
+
+    boolean connectAllEnabledProfiles(in BluetoothDevice device);
+    boolean disconnectAllEnabledProfiles(in BluetoothDevice device);
 }
diff --git a/btif/src/btif_a2dp_sink.cc b/btif/src/btif_a2dp_sink.cc
index bb1bc49..aa75d21 100644
--- a/btif/src/btif_a2dp_sink.cc
+++ b/btif/src/btif_a2dp_sink.cc
@@ -667,7 +667,6 @@
   LOG_INFO(LOG_TAG, "%s: state=%d", __func__, state);
   LockGuard lock(g_mutex);
 
-  if (!btif_av_is_connected()) return;
   APPL_TRACE_DEBUG("%s: setting focus state to %d", __func__, state);
   btif_a2dp_sink_cb.rx_focus_state = state;
   if (btif_a2dp_sink_cb.rx_focus_state == BTIF_A2DP_SINK_FOCUS_NOT_GRANTED) {
diff --git a/gd/packet/parser/fields/array_field.cc b/gd/packet/parser/fields/array_field.cc
index 2592b6c..37dea16 100644
--- a/gd/packet/parser/fields/array_field.cc
+++ b/gd/packet/parser/fields/array_field.cc
@@ -106,9 +106,14 @@
   s << "}";
 }
 
+std::string ArrayField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void ArrayField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << GetDataType();
-  s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() {";
+  s << GetDataType() << " " << GetGetterFunctionName() << "() {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -122,13 +127,14 @@
   s << "}\n";
 }
 
-bool ArrayField::GenBuilderParameter(std::ostream& s) const {
+std::string ArrayField::GetBuilderParameterType() const {
+  std::stringstream ss;
   if (element_field_->BuilderParameterMustBeMoved()) {
-    s << "std::array<" << element_field_->GetDataType() << "," << array_size_ << "> " << GetName();
+    ss << "std::array<" << element_field_->GetDataType() << "," << array_size_ << ">";
   } else {
-    s << "const std::array<" << element_field_->GetDataType() << "," << array_size_ << ">& " << GetName();
+    ss << "const std::array<" << element_field_->GetDataType() << "," << array_size_ << ">&";
   }
-  return true;
+  return ss.str();
 }
 
 bool ArrayField::BuilderParameterMustBeMoved() const {
@@ -161,3 +167,11 @@
   // Other than that there is nothing that arrays need to be validated on other than length so nothing needs to
   // be done here.
 }
+
+bool ArrayField::IsContainerField() const {
+  return true;
+}
+
+const PacketField* ArrayField::GetElementField() const {
+  return element_field_;
+}
diff --git a/gd/packet/parser/fields/array_field.h b/gd/packet/parser/fields/array_field.h
index 6e171e6..dd49f26 100644
--- a/gd/packet/parser/fields/array_field.h
+++ b/gd/packet/parser/fields/array_field.h
@@ -40,9 +40,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool BuilderParameterMustBeMoved() const override;
 
@@ -56,6 +58,10 @@
 
   virtual void GenValidator(std::ostream&) const override;
 
+  virtual bool IsContainerField() const override;
+
+  virtual const PacketField* GetElementField() const override;
+
   const std::string name_;
 
   const PacketField* element_field_{nullptr};
diff --git a/gd/packet/parser/fields/body_field.cc b/gd/packet/parser/fields/body_field.cc
index 4457348..5e00b68 100644
--- a/gd/packet/parser/fields/body_field.cc
+++ b/gd/packet/parser/fields/body_field.cc
@@ -35,10 +35,14 @@
 
 void BodyField::GenExtractor(std::ostream&, int, bool) const {}
 
+std::string BodyField::GetGetterFunctionName() const {
+  return "";
+}
+
 void BodyField::GenGetter(std::ostream&, Size, Size) const {}
 
-bool BodyField::GenBuilderParameter(std::ostream&) const {
-  return false;
+std::string BodyField::GetBuilderParameterType() const {
+  return "";
 }
 
 bool BodyField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/body_field.h b/gd/packet/parser/fields/body_field.h
index 8a2a90b..ce4ede7 100644
--- a/gd/packet/parser/fields/body_field.h
+++ b/gd/packet/parser/fields/body_field.h
@@ -34,9 +34,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream&, Size, Size) const override;
 
-  virtual bool GenBuilderParameter(std::ostream&) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/checksum_field.cc b/gd/packet/parser/fields/checksum_field.cc
index beab91a..4647992 100644
--- a/gd/packet/parser/fields/checksum_field.cc
+++ b/gd/packet/parser/fields/checksum_field.cc
@@ -32,6 +32,10 @@
 
 void ChecksumField::GenExtractor(std::ostream&, int, bool) const {}
 
+std::string ChecksumField::GetGetterFunctionName() const {
+  return "";
+}
+
 void ChecksumField::GenGetter(std::ostream&, Size, Size) const {}
 
 bool ChecksumField::GenBuilderParameter(std::ostream&) const {
diff --git a/gd/packet/parser/fields/checksum_field.h b/gd/packet/parser/fields/checksum_field.h
index f6dfe46..c15f023 100644
--- a/gd/packet/parser/fields/checksum_field.h
+++ b/gd/packet/parser/fields/checksum_field.h
@@ -32,6 +32,8 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
   virtual bool GenBuilderParameter(std::ostream& s) const override;
diff --git a/gd/packet/parser/fields/checksum_start_field.cc b/gd/packet/parser/fields/checksum_start_field.cc
index a100aee..5531c5a 100644
--- a/gd/packet/parser/fields/checksum_start_field.cc
+++ b/gd/packet/parser/fields/checksum_start_field.cc
@@ -36,10 +36,14 @@
 
 void ChecksumStartField::GenExtractor(std::ostream&, int, bool) const {}
 
+std::string ChecksumStartField::GetGetterFunctionName() const {
+  return "";
+}
+
 void ChecksumStartField::GenGetter(std::ostream&, Size, Size) const {}
 
-bool ChecksumStartField::GenBuilderParameter(std::ostream&) const {
-  return false;
+std::string ChecksumStartField::GetBuilderParameterType() const {
+  return "";
 }
 
 bool ChecksumStartField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/checksum_start_field.h b/gd/packet/parser/fields/checksum_start_field.h
index 18a5956..c63806b 100644
--- a/gd/packet/parser/fields/checksum_start_field.h
+++ b/gd/packet/parser/fields/checksum_start_field.h
@@ -35,9 +35,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream&) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/custom_field.cc b/gd/packet/parser/fields/custom_field.cc
index 3da3b5b..4e387f8 100644
--- a/gd/packet/parser/fields/custom_field.cc
+++ b/gd/packet/parser/fields/custom_field.cc
@@ -50,8 +50,14 @@
   s << "}";
 }
 
+std::string CustomField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void CustomField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << "std::unique_ptr<" << GetDataType() << "> Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
+  s << "std::unique_ptr<" << GetDataType() << "> " << GetGetterFunctionName() << "() const {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -66,9 +72,8 @@
   s << "}\n";
 }
 
-bool CustomField::GenBuilderParameter(std::ostream& s) const {
-  s << GetDataType() << " " << GetName();
-  return true;
+std::string CustomField::GetBuilderParameterType() const {
+  return GetDataType();
 }
 
 bool CustomField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/custom_field.h b/gd/packet/parser/fields/custom_field.h
index 6e07d94..621a3c8 100644
--- a/gd/packet/parser/fields/custom_field.h
+++ b/gd/packet/parser/fields/custom_field.h
@@ -35,9 +35,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/group_field.cc b/gd/packet/parser/fields/group_field.cc
index 95e6428..6c9ade9 100644
--- a/gd/packet/parser/fields/group_field.cc
+++ b/gd/packet/parser/fields/group_field.cc
@@ -48,13 +48,18 @@
   ERROR(this) << "GenExtractor should never be called.";
 }
 
+std::string GroupField::GetGetterFunctionName() const {
+  ERROR(this) << "GetGetterFunctionName should never be called.";
+  return "";
+}
+
 void GroupField::GenGetter(std::ostream&, Size, Size) const {
   ERROR(this) << "GenGetter should never be called.";
 }
 
-bool GroupField::GenBuilderParameter(std::ostream&) const {
-  ERROR(this) << "GenBuilderParameter should never be called";
-  return false;
+std::string GroupField::GetBuilderParameterType() const {
+  ERROR(this) << "GetBuilderParameterType should never be called";
+  return "";
 }
 
 bool GroupField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/group_field.h b/gd/packet/parser/fields/group_field.h
index b5344a7..57e0165 100644
--- a/gd/packet/parser/fields/group_field.h
+++ b/gd/packet/parser/fields/group_field.h
@@ -39,9 +39,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream&, Size, Size) const override;
 
-  virtual bool GenBuilderParameter(std::ostream&) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/packet_field.cc b/gd/packet/parser/fields/packet_field.cc
index 026e56f..7b0bdb7 100644
--- a/gd/packet/parser/fields/packet_field.cc
+++ b/gd/packet/parser/fields/packet_field.cc
@@ -72,6 +72,15 @@
   return 0;  // num_leading_bits
 }
 
+bool PacketField::GenBuilderParameter(std::ostream& s) const {
+  auto param_type = GetBuilderParameterType();
+  if (param_type.empty()) {
+    return false;
+  }
+  s << param_type << " " << GetName();
+  return true;
+}
+
 bool PacketField::BuilderParameterMustBeMoved() const {
   return false;
 }
@@ -83,3 +92,11 @@
 void PacketField::GenBuilderParameterFromView(std::ostream& s) const {
   s << "view.Get" << util::UnderscoreToCamelCase(GetName()) << "()";
 }
+
+bool PacketField::IsContainerField() const {
+  return false;
+}
+
+const PacketField* PacketField::GetElementField() const {
+  return nullptr;
+}
diff --git a/gd/packet/parser/fields/packet_field.h b/gd/packet/parser/fields/packet_field.h
index 55313e6..d369a92 100644
--- a/gd/packet/parser/fields/packet_field.h
+++ b/gd/packet/parser/fields/packet_field.h
@@ -54,14 +54,20 @@
   // Calculate field_begin and field_end using the given offsets and size, return the number of leading bits
   virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset, Size size) const;
 
+  // Get the name of the getter function, return empty string if there is a getter function
+  virtual std::string GetGetterFunctionName() const = 0;
+
   // Get parser getter definition. Start_offset points to the first bit of the
   // field. end_offset is the first bit after the field. If an offset is empty
   // that means that there was a field with an unknown size when trying to
   // calculate the offset.
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const = 0;
 
+  // Get the type of parameter used in Create(), return empty string if a parameter type was NOT generated
+  virtual std::string GetBuilderParameterType() const = 0;
+
   // Generate the parameter for Create(), return true if a parameter was added.
-  virtual bool GenBuilderParameter(std::ostream& s) const = 0;
+  virtual bool GenBuilderParameter(std::ostream& s) const;
 
   // Return true if the Builder parameter has to be moved.
   virtual bool BuilderParameterMustBeMoved() const;
@@ -94,6 +100,13 @@
   // see if they contain the correct value.
   virtual void GenValidator(std::ostream& s) const = 0;
 
+  // Some fields are containers of other fields, e.g. array, vector, etc.
+  // Assume STL containers that support swap()
+  virtual bool IsContainerField() const;
+
+  // Get field of nested elements if this is a container field, nullptr if none
+  virtual const PacketField* GetElementField() const;
+
   std::string GetDebugName() const override;
 
   ParseLocation GetLocation() const override;
diff --git a/gd/packet/parser/fields/padding_field.cc b/gd/packet/parser/fields/padding_field.cc
index 0ae99c9..5f438f8 100644
--- a/gd/packet/parser/fields/padding_field.cc
+++ b/gd/packet/parser/fields/padding_field.cc
@@ -40,10 +40,14 @@
 
 void PaddingField::GenExtractor(std::ostream&, int, bool) const {}
 
+std::string PaddingField::GetGetterFunctionName() const {
+  return "";
+}
+
 void PaddingField::GenGetter(std::ostream&, Size, Size) const {}
 
-bool PaddingField::GenBuilderParameter(std::ostream&) const {
-  return false;
+std::string PaddingField::GetBuilderParameterType() const {
+  return "";
 }
 
 bool PaddingField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/padding_field.h b/gd/packet/parser/fields/padding_field.h
index 5c22c1a..bb99d42 100644
--- a/gd/packet/parser/fields/padding_field.h
+++ b/gd/packet/parser/fields/padding_field.h
@@ -37,9 +37,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream&) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/payload_field.cc b/gd/packet/parser/fields/payload_field.cc
index a13a6de..c075996 100644
--- a/gd/packet/parser/fields/payload_field.cc
+++ b/gd/packet/parser/fields/payload_field.cc
@@ -58,8 +58,12 @@
   ERROR(this) << __func__ << " should never be called. ";
 }
 
+std::string PayloadField::GetGetterFunctionName() const {
+  return "GetPayload";
+}
+
 void PayloadField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << "PacketView<kLittleEndian> GetPayload() const {";
+  s << "PacketView<kLittleEndian> " << GetGetterFunctionName() << "() const {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -67,7 +71,7 @@
   s << "return GetLittleEndianSubview(field_begin, field_end);";
   s << "}\n\n";
 
-  s << "PacketView<!kLittleEndian> GetPayloadBigEndian() const {";
+  s << "PacketView<!kLittleEndian> " << GetGetterFunctionName() << "BigEndian() const {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -76,8 +80,11 @@
   s << "}\n";
 }
 
-bool PayloadField::GenBuilderParameter(std::ostream& s) const {
-  s << "std::unique_ptr<BasePacketBuilder> payload";
+std::string PayloadField::GetBuilderParameterType() const {
+  return "std::unique_ptr<BasePacketBuilder>";
+}
+
+bool PayloadField::BuilderParameterMustBeMoved() const {
   return true;
 }
 
diff --git a/gd/packet/parser/fields/payload_field.h b/gd/packet/parser/fields/payload_field.h
index 12cec07..11e6267 100644
--- a/gd/packet/parser/fields/payload_field.h
+++ b/gd/packet/parser/fields/payload_field.h
@@ -36,9 +36,13 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
+
+  virtual bool BuilderParameterMustBeMoved() const override;
 
   virtual void GenBuilderParameterFromView(std::ostream& s) const override;
 
diff --git a/gd/packet/parser/fields/reserved_field.cc b/gd/packet/parser/fields/reserved_field.cc
index b0a62f1..0acf7b7 100644
--- a/gd/packet/parser/fields/reserved_field.cc
+++ b/gd/packet/parser/fields/reserved_field.cc
@@ -38,13 +38,17 @@
 
 void ReservedField::GenExtractor(std::ostream&, int, bool) const {}
 
+std::string ReservedField::GetGetterFunctionName() const {
+  return "";
+}
+
 void ReservedField::GenGetter(std::ostream&, Size, Size) const {
   // There is no Getter for a reserved field
 }
 
-bool ReservedField::GenBuilderParameter(std::ostream&) const {
+std::string ReservedField::GetBuilderParameterType() const {
   // There is no builder parameter for a reserved field
-  return false;
+  return "";
 }
 
 bool ReservedField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/reserved_field.h b/gd/packet/parser/fields/reserved_field.h
index b2df0f1..7d36352 100644
--- a/gd/packet/parser/fields/reserved_field.h
+++ b/gd/packet/parser/fields/reserved_field.h
@@ -33,9 +33,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream&, Size, Size) const override;
 
-  virtual bool GenBuilderParameter(std::ostream&) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/scalar_field.cc b/gd/packet/parser/fields/scalar_field.cc
index 47b1a43..c6d2ecf 100644
--- a/gd/packet/parser/fields/scalar_field.cc
+++ b/gd/packet/parser/fields/scalar_field.cc
@@ -88,9 +88,14 @@
   s << "*" << GetName() << "_ptr = static_cast<" << GetDataType() << ">(extracted_value);";
 }
 
+std::string ScalarField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void ScalarField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << GetDataType();
-  s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
+  s << GetDataType() << " " << GetGetterFunctionName() << "() const {";
   s << "ASSERT(was_validated_);";
   s << "auto to_bound = begin();";
   int num_leading_bits = GenBounds(s, start_offset, end_offset, GetSize());
@@ -101,9 +106,8 @@
   s << "}";
 }
 
-bool ScalarField::GenBuilderParameter(std::ostream& s) const {
-  s << GetDataType() << " " << GetName();
-  return true;
+std::string ScalarField::GetBuilderParameterType() const {
+  return GetDataType();
 }
 
 bool ScalarField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/scalar_field.h b/gd/packet/parser/fields/scalar_field.h
index 480dc28..65f897e 100644
--- a/gd/packet/parser/fields/scalar_field.h
+++ b/gd/packet/parser/fields/scalar_field.h
@@ -35,9 +35,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/struct_field.cc b/gd/packet/parser/fields/struct_field.cc
index 1a37d24..fbdafcf 100644
--- a/gd/packet/parser/fields/struct_field.cc
+++ b/gd/packet/parser/fields/struct_field.cc
@@ -44,8 +44,14 @@
   s << GetDataType() << "::Parse(" << GetName() << "_ptr, " << GetName() << "_it);";
 }
 
+std::string StructField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void StructField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << GetDataType() << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
+  s << GetDataType() << " " << GetGetterFunctionName() << "() const {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -58,9 +64,8 @@
   s << "}\n";
 }
 
-bool StructField::GenBuilderParameter(std::ostream& s) const {
-  s << GetDataType() << " " << GetName();
-  return true;
+std::string StructField::GetBuilderParameterType() const {
+  return GetDataType();
 }
 
 bool StructField::HasParameterValidator() const {
diff --git a/gd/packet/parser/fields/struct_field.h b/gd/packet/parser/fields/struct_field.h
index 7f1d7d0..1f4f100 100644
--- a/gd/packet/parser/fields/struct_field.h
+++ b/gd/packet/parser/fields/struct_field.h
@@ -35,9 +35,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool HasParameterValidator() const override;
 
diff --git a/gd/packet/parser/fields/variable_length_struct_field.cc b/gd/packet/parser/fields/variable_length_struct_field.cc
index c07bc2c..51a46e4 100644
--- a/gd/packet/parser/fields/variable_length_struct_field.cc
+++ b/gd/packet/parser/fields/variable_length_struct_field.cc
@@ -49,8 +49,14 @@
   s << "}";
 }
 
+std::string VariableLengthStructField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void VariableLengthStructField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << "std::unique_ptr<" << type_name_ << "> Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
+  s << GetDataType() << " " << GetGetterFunctionName() << "() const {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -61,9 +67,8 @@
   s << "}\n";
 }
 
-bool VariableLengthStructField::GenBuilderParameter(std::ostream& s) const {
-  s << GetDataType() << " " << GetName();
-  return true;
+std::string VariableLengthStructField::GetBuilderParameterType() const {
+  return GetDataType();
 }
 
 bool VariableLengthStructField::BuilderParameterMustBeMoved() const {
diff --git a/gd/packet/parser/fields/variable_length_struct_field.h b/gd/packet/parser/fields/variable_length_struct_field.h
index 4b5d62b..0b1b97f 100644
--- a/gd/packet/parser/fields/variable_length_struct_field.h
+++ b/gd/packet/parser/fields/variable_length_struct_field.h
@@ -35,9 +35,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool BuilderParameterMustBeMoved() const override;
 
diff --git a/gd/packet/parser/fields/vector_field.cc b/gd/packet/parser/fields/vector_field.cc
index 77fb546..ab47c4f 100644
--- a/gd/packet/parser/fields/vector_field.cc
+++ b/gd/packet/parser/fields/vector_field.cc
@@ -144,9 +144,14 @@
   s << "}";
 }
 
+std::string VectorField::GetGetterFunctionName() const {
+  std::stringstream ss;
+  ss << "Get" << util::UnderscoreToCamelCase(GetName());
+  return ss.str();
+}
+
 void VectorField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
-  s << GetDataType();
-  s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() {";
+  s << GetDataType() << " " << GetGetterFunctionName() << "() {";
   s << "ASSERT(was_validated_);";
   s << "size_t end_index = size();";
   s << "auto to_bound = begin();";
@@ -160,13 +165,14 @@
   s << "}\n";
 }
 
-bool VectorField::GenBuilderParameter(std::ostream& s) const {
+std::string VectorField::GetBuilderParameterType() const {
+  std::stringstream ss;
   if (element_field_->BuilderParameterMustBeMoved()) {
-    s << "std::vector<" << element_field_->GetDataType() << "> " << GetName();
+    ss << "std::vector<" << element_field_->GetDataType() << ">";
   } else {
-    s << "const std::vector<" << element_field_->GetDataType() << ">& " << GetName();
+    ss << "const std::vector<" << element_field_->GetDataType() << ">&";
   }
-  return true;
+  return ss.str();
 }
 
 bool VectorField::BuilderParameterMustBeMoved() const {
@@ -216,3 +222,11 @@
 const std::string& VectorField::GetSizeModifier() const {
   return size_modifier_;
 }
+
+bool VectorField::IsContainerField() const {
+  return true;
+}
+
+const PacketField* VectorField::GetElementField() const {
+  return element_field_;
+}
diff --git a/gd/packet/parser/fields/vector_field.h b/gd/packet/parser/fields/vector_field.h
index f8c1578..b2ae95d 100644
--- a/gd/packet/parser/fields/vector_field.h
+++ b/gd/packet/parser/fields/vector_field.h
@@ -41,9 +41,11 @@
 
   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const override;
 
+  virtual std::string GetGetterFunctionName() const override;
+
   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
 
-  virtual bool GenBuilderParameter(std::ostream& s) const override;
+  virtual std::string GetBuilderParameterType() const override;
 
   virtual bool BuilderParameterMustBeMoved() const override;
 
@@ -61,6 +63,10 @@
 
   const std::string& GetSizeModifier() const;
 
+  virtual bool IsContainerField() const override;
+
+  virtual const PacketField* GetElementField() const override;
+
   const std::string name_;
 
   const PacketField* element_field_{nullptr};
diff --git a/gd/packet/parser/main.cc b/gd/packet/parser/main.cc
index 8c6e4e1..a53d71d 100644
--- a/gd/packet/parser/main.cc
+++ b/gd/packet/parser/main.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include <errno.h>
 #include <unistd.h>
+#include <cerrno>
 #include <cstdio>
 #include <filesystem>
 #include <fstream>
@@ -37,21 +37,21 @@
 
 namespace {
 
-void parse_namespace(std::string root_namespace, std::filesystem::path input_file_relative_path,
-                     std::vector<std::string>& token) {
+void parse_namespace(const std::string& root_namespace, const std::filesystem::path& input_file_relative_path,
+                     std::vector<std::string>* token) {
   std::filesystem::path gen_namespace = root_namespace / input_file_relative_path;
   std::string gen_namespace_str = gen_namespace;
   std::regex path_tokenizer("/");
   auto it = std::sregex_token_iterator(gen_namespace_str.cbegin(), gen_namespace_str.cend(), path_tokenizer, -1);
-  std::sregex_token_iterator it_end;
+  std::sregex_token_iterator it_end = {};
   for (; it != it_end; ++it) {
-    token.push_back(it->str());
+    token->push_back(it->str());
   }
 }
 
 void generate_namespace_open(const std::vector<std::string>& token, std::ostream& output) {
-  for (auto it = token.begin(); it != token.end(); ++it) {
-    output << "namespace " << *it << " {" << std::endl;
+  for (const auto& ns : token) {
+    output << "namespace " << ns << " {" << std::endl;
   }
 }
 
@@ -61,17 +61,7 @@
   }
 }
 
-bool parse_one_file(std::filesystem::path input_file, std::filesystem::path include_dir, std::filesystem::path out_dir,
-                    std::string root_namespace) {
-  auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path();
-
-  auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl"));
-  auto gen_path = out_dir / gen_relative_path;
-
-  std::filesystem::create_directories(gen_path);
-
-  auto gen_file = gen_path / (input_filename + ".h");
-
+bool parse_declarations_one_file(const std::filesystem::path& input_file, Declarations* declarations) {
   void* scanner;
   yylex_init(&scanner);
 
@@ -83,6 +73,43 @@
 
   yyset_in(in_file, scanner);
 
+  int ret = yy::parser(scanner, declarations).parse();
+  if (ret != 0) {
+    std::cerr << "yylex parsing failed: returned " << ret << std::endl;
+    return false;
+  }
+
+  yylex_destroy(scanner);
+
+  fclose(in_file);
+
+  // Set endianess before returning
+  for (auto& s : declarations->type_defs_queue_) {
+    if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) {
+      auto* struct_def = dynamic_cast<StructDef*>(s.second);
+      struct_def->SetEndianness(declarations->is_little_endian);
+    }
+  }
+
+  for (auto& packet_def : declarations->packet_defs_queue_) {
+    packet_def.second.SetEndianness(declarations->is_little_endian);
+  }
+
+  return true;
+}
+
+bool generate_cpp_headers_one_file(const Declarations& decls, const std::filesystem::path& input_file,
+                                   const std::filesystem::path& include_dir, const std::filesystem::path& out_dir,
+                                   const std::string& root_namespace) {
+  auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path();
+
+  auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl"));
+  auto gen_path = out_dir / gen_relative_path;
+
+  std::filesystem::create_directories(gen_path);
+
+  auto gen_file = gen_path / (input_filename + ".h");
+
   std::ofstream out_file;
   out_file.open(gen_file);
   if (!out_file.is_open()) {
@@ -90,16 +117,6 @@
     return false;
   }
 
-  Declarations decls;
-  int ret = yy::parser(scanner, &decls).parse();
-
-  yylex_destroy(scanner);
-
-  if (ret != 0) {
-    std::cerr << "yylex parsing failed: returned " << ret << std::endl;
-    return false;
-  }
-
   out_file << "\n\n";
   out_file << "#pragma once\n";
   out_file << "\n\n";
@@ -127,7 +144,7 @@
   out_file << "\n\n";
 
   std::vector<std::string> namespace_list;
-  parse_namespace(root_namespace, gen_relative_path, namespace_list);
+  parse_namespace(root_namespace, gen_relative_path, &namespace_list);
   generate_namespace_open(namespace_list, out_file);
   out_file << "\n\n";
 
@@ -152,36 +169,40 @@
 
   for (const auto& e : decls.type_defs_queue_) {
     if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) {
-      EnumGen gen(*(EnumDef*)e.second);
+      const auto* enum_def = dynamic_cast<const EnumDef*>(e.second);
+      EnumGen gen(*enum_def);
       gen.GenDefinition(out_file);
       out_file << "\n\n";
     }
   }
   for (const auto& e : decls.type_defs_queue_) {
     if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) {
-      EnumGen gen(*(EnumDef*)e.second);
+      const auto* enum_def = dynamic_cast<const EnumDef*>(e.second);
+      EnumGen gen(*enum_def);
       gen.GenLogging(out_file);
       out_file << "\n\n";
     }
   }
   for (const auto& ch : decls.type_defs_queue_) {
     if (ch.second->GetDefinitionType() == TypeDef::Type::CHECKSUM) {
-      ((ChecksumDef*)ch.second)->GenChecksumCheck(out_file);
+      const auto* checksum_def = dynamic_cast<const ChecksumDef*>(ch.second);
+      checksum_def->GenChecksumCheck(out_file);
     }
   }
   out_file << "\n/* Done ChecksumChecks */\n";
 
   for (const auto& c : decls.type_defs_queue_) {
     if (c.second->GetDefinitionType() == TypeDef::Type::CUSTOM && c.second->size_ == -1 /* Variable Size */) {
-      ((CustomFieldDef*)c.second)->GenCustomFieldCheck(out_file, decls.is_little_endian);
+      const auto* custom_field_def = dynamic_cast<const CustomFieldDef*>(c.second);
+      custom_field_def->GenCustomFieldCheck(out_file, decls.is_little_endian);
     }
   }
   out_file << "\n";
 
   for (auto& s : decls.type_defs_queue_) {
     if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) {
-      ((StructDef*)s.second)->SetEndianness(decls.is_little_endian);
-      ((StructDef*)s.second)->GenDefinition(out_file);
+      const auto* struct_def = dynamic_cast<const StructDef*>(s.second);
+      struct_def->GenDefinition(out_file);
       out_file << "\n";
     }
   }
@@ -192,21 +213,19 @@
     out_file << "\n\n";
   }
 
-  for (size_t i = 0; i < decls.packet_defs_queue_.size(); i++) {
-    decls.packet_defs_queue_[i].second.SetEndianness(decls.is_little_endian);
-    decls.packet_defs_queue_[i].second.GenParserDefinition(out_file);
+  for (const auto& packet_def : decls.packet_defs_queue_) {
+    packet_def.second.GenParserDefinition(out_file);
     out_file << "\n\n";
   }
 
-  for (const auto p : decls.packet_defs_queue_) {
-    p.second.GenBuilderDefinition(out_file);
+  for (const auto& packet_def : decls.packet_defs_queue_) {
+    packet_def.second.GenBuilderDefinition(out_file);
     out_file << "\n\n";
   }
 
   generate_namespace_close(namespace_list, out_file);
 
   out_file.close();
-  fclose(in_file);
 
   return true;
 }
@@ -245,10 +264,15 @@
   }
 
   while (!input_files.empty()) {
-    if (!parse_one_file(input_files.front(), include_dir, out_dir, root_namespace)) {
-      std::cerr << "Didn't parse " << input_files.front() << " correctly" << std::endl;
+    Declarations declarations;
+    if (!parse_declarations_one_file(input_files.front(), &declarations)) {
+      std::cerr << "Cannot parse " << input_files.front() << " correctly" << std::endl;
       return 2;
     }
+    if (!generate_cpp_headers_one_file(declarations, input_files.front(), include_dir, out_dir, root_namespace)) {
+      std::cerr << "Didn't generate cpp headers for " << input_files.front() << std::endl;
+      return 3;
+    }
     input_files.pop();
   }
 
diff --git a/gd/packet/parser/struct_parser_generator.cc b/gd/packet/parser/struct_parser_generator.cc
index c5ccb88..352219e 100644
--- a/gd/packet/parser/struct_parser_generator.cc
+++ b/gd/packet/parser/struct_parser_generator.cc
@@ -16,11 +16,12 @@
 
 #include "struct_parser_generator.h"
 
-StructParserGenerator::StructParserGenerator(Declarations& decls) {
+StructParserGenerator::StructParserGenerator(const Declarations& decls) {
   is_little_endian = decls.is_little_endian;
-  for (auto& s : decls.type_defs_queue_) {
+  for (const auto& s : decls.type_defs_queue_) {
     if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) {
-      variable_struct_fields_.push_back((StructDef*)s.second);
+      const auto* struct_def = dynamic_cast<const StructDef*>(s.second);
+      variable_struct_fields_.emplace_back(struct_def);
     }
   }
   for (const auto& node : variable_struct_fields_) {
@@ -36,10 +37,10 @@
 
 void StructParserGenerator::explore_children(const TreeNode& node, std::ostream& s) const {
   auto field = node.packet_field_;
-  if (node.children_.size() > 0) {
+  if (!node.children_.empty()) {
     s << "bool " << field->GetName() << "_child_found = false; /* Greedy match */";
   }
-  for (const auto child : node.children_) {
+  for (const auto& child : node.children_) {
     s << "if (!" << field->GetName() << "_child_found && ";
     s << child->struct_def_->name_ << "::IsInstance(*" << field->GetName() << "_value.get())) {";
     s << field->GetName() << "_child_found = true;";
@@ -65,32 +66,33 @@
 
 void StructParserGenerator::Generate(std::ostream& s) const {
   for (const auto& node : variable_struct_fields_) {
-    if (node.children_.size() > 0) {
-      auto field = node.packet_field_;
-      s << "inline std::unique_ptr<" << node.struct_def_->name_ << "> Parse" << node.struct_def_->name_;
-      if (is_little_endian) {
-        s << "(Iterator<kLittleEndian> to_bound) {";
-      } else {
-        s << "(Iterator<!kLittleEndian> to_bound) {";
-      }
-      s << field->GetDataType() << " " << field->GetName() << "_value = ";
-      s << "std::make_unique<" << node.struct_def_->name_ << ">();";
-
-      s << "auto " << field->GetName() << "_it = to_bound;";
-      s << "auto optional_it = ";
-      s << node.struct_def_->name_ << "::Parse( " << field->GetName() << "_value.get(), ";
-      s << field->GetName() << "_it";
-      if (node.struct_def_->parent_ != nullptr) {
-        s << ", true);";
-      } else {
-        s << ");";
-      }
-      s << "if (optional_it) {";
-      s << field->GetName() << "_it = *optional_it;";
-      s << "} else { return nullptr; }";
-
-      explore_children(node, s);
-      s << "return " << field->GetName() << "_value; }";
+    if (node.children_.empty()) {
+      continue;
     }
+    auto field = node.packet_field_;
+    s << "inline std::unique_ptr<" << node.struct_def_->name_ << "> Parse" << node.struct_def_->name_;
+    if (is_little_endian) {
+      s << "(Iterator<kLittleEndian> to_bound) {";
+    } else {
+      s << "(Iterator<!kLittleEndian> to_bound) {";
+    }
+    s << field->GetDataType() << " " << field->GetName() << "_value = ";
+    s << "std::make_unique<" << node.struct_def_->name_ << ">();";
+
+    s << "auto " << field->GetName() << "_it = to_bound;";
+    s << "auto optional_it = ";
+    s << node.struct_def_->name_ << "::Parse( " << field->GetName() << "_value.get(), ";
+    s << field->GetName() << "_it";
+    if (node.struct_def_->parent_ != nullptr) {
+      s << ", true);";
+    } else {
+      s << ");";
+    }
+    s << "if (optional_it) {";
+    s << field->GetName() << "_it = *optional_it;";
+    s << "} else { return nullptr; }";
+
+    explore_children(node, s);
+    s << "return " << field->GetName() << "_value; }";
   }
 }
diff --git a/gd/packet/parser/struct_parser_generator.h b/gd/packet/parser/struct_parser_generator.h
index 2c1ff6d..0315460 100644
--- a/gd/packet/parser/struct_parser_generator.h
+++ b/gd/packet/parser/struct_parser_generator.h
@@ -24,14 +24,14 @@
 
 class StructParserGenerator {
  public:
-  StructParserGenerator(Declarations& declarations);
+  explicit StructParserGenerator(const Declarations& declarations);
 
   void Generate(std::ostream& s) const;
 
  private:
   class TreeNode {
    public:
-    TreeNode(const StructDef* s)
+    explicit TreeNode(const StructDef* s)
         : struct_def_(s), packet_field_(s->GetNewField(s->name_ + "_parse", ParseLocation())) {}
     const StructDef* struct_def_;
     const PacketField* packet_field_;
diff --git a/gd/security/internal/security_manager_impl.cc b/gd/security/internal/security_manager_impl.cc
index 7b886f5..26179b5 100644
--- a/gd/security/internal/security_manager_impl.cc
+++ b/gd/security/internal/security_manager_impl.cc
@@ -100,55 +100,43 @@
   // Signal Remove from database
 }
 
-void SecurityManagerImpl::RegisterCallbackListener(ISecurityManagerListener* listener) {
-  if (listeners_.size() < 1) {
-    listeners_.push_back(listener);
-  } else {
-    bool found = false;
-    for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
-      found = *it == listener;
-      if (found) break;
-    }
-
-    if (found) {
-      LOG_ERROR("Listener has already been registered!");
-    } else {
-      listeners_.push_back(listener);
+void SecurityManagerImpl::RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler) {
+  for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
+    if (it->first == listener) {
+      LOG_ALWAYS_FATAL("Listener has already been registered!");
     }
   }
+
+  listeners_.push_back({listener, handler});
 }
 
 void SecurityManagerImpl::UnregisterCallbackListener(ISecurityManagerListener* listener) {
-  if (listeners_.size() < 1) {
-    LOG_ERROR("Listener has not been registered!");
-  } else {
-    bool found = false;
-    auto it = listeners_.begin();
-    while (it != listeners_.end()) {
-      found = *it == listener;
-      if (found) break;
-      ++it;
-    }
-    if (found) {
+  for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
+    if (it->first == listener) {
       listeners_.erase(it);
+      return;
     }
   }
+
+  LOG_ALWAYS_FATAL("Listener has not been registered!");
 }
 
-void SecurityManagerImpl::FireDeviceBondedCallbacks(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceBonded(std::shared_ptr<Device> device) {
   for (auto& iter : listeners_) {
-    iter->handler_->Post(common::Bind(&ISecurityManagerListener::OnDeviceBonded, common::Unretained(iter), device));
+    iter.second->Post(common::Bind(&ISecurityManagerListener::OnDeviceBonded, common::Unretained(iter.first), device));
   }
 }
 
-void SecurityManagerImpl::FireBondFailedCallbacks(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceBondFailed(std::shared_ptr<Device> device) {
   for (auto& iter : listeners_) {
-    iter->handler_->Post(common::Bind(&ISecurityManagerListener::OnDeviceBondFailed, common::Unretained(iter), device));
+    iter.second->Post(
+        common::Bind(&ISecurityManagerListener::OnDeviceBondFailed, common::Unretained(iter.first), device));
   }
 }
 
-void SecurityManagerImpl::FireUnbondCallbacks(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceUnbonded(std::shared_ptr<Device> device) {
   for (auto& iter : listeners_) {
-    iter->handler_->Post(common::Bind(&ISecurityManagerListener::OnDeviceUnbonded, common::Unretained(iter), device));
+    iter.second->Post(
+        common::Bind(&ISecurityManagerListener::OnDeviceUnbonded, common::Unretained(iter.first), device));
   }
 }
diff --git a/gd/security/internal/security_manager_impl.h b/gd/security/internal/security_manager_impl.h
index 1e17770..23b39e1 100644
--- a/gd/security/internal/security_manager_impl.h
+++ b/gd/security/internal/security_manager_impl.h
@@ -22,6 +22,8 @@
 #include "os/handler.h"
 #include "security/channel/security_manager_channel.h"
 
+#include <utility>
+
 namespace bluetooth {
 namespace security {
 
@@ -80,7 +82,7 @@
    *
    * @param listener ISecurityManagerListener instance to handle callbacks
    */
-  void RegisterCallbackListener(ISecurityManagerListener* listener);
+  void RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler);
 
   /**
    * Unregister listener for callback events from SecurityManager
@@ -90,10 +92,10 @@
   void UnregisterCallbackListener(ISecurityManagerListener* listener);
 
  protected:
-  std::vector<ISecurityManagerListener*> listeners_;
-  void FireDeviceBondedCallbacks(std::shared_ptr<bluetooth::hci::Device> device);
-  void FireBondFailedCallbacks(std::shared_ptr<bluetooth::hci::Device> device);
-  void FireUnbondCallbacks(std::shared_ptr<bluetooth::hci::Device> device);
+  std::vector<std::pair<ISecurityManagerListener*, os::Handler*>> listeners_;
+  void NotifyDeviceBonded(std::shared_ptr<bluetooth::hci::Device> device);
+  void NotifyDeviceBondFailed(std::shared_ptr<bluetooth::hci::Device> device);
+  void NotifyDeviceUnbonded(std::shared_ptr<bluetooth::hci::Device> device);
 
   // ISecurityManagerChannel
   void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device,
diff --git a/gd/security/security_manager.cc b/gd/security/security_manager.cc
index da2b30b..40858a9 100644
--- a/gd/security/security_manager.cc
+++ b/gd/security/security_manager.cc
@@ -21,6 +21,9 @@
 
 using namespace bluetooth::security;
 
+// Definition of Pure Virtual Destructor
+ISecurityManagerListener::~ISecurityManagerListener() {}
+
 void SecurityManager::Init() {
   security_handler_->Post(
       common::BindOnce(&internal::SecurityManagerImpl::Init, common::Unretained(security_manager_impl_)));
@@ -44,14 +47,12 @@
                                            std::forward<std::shared_ptr<hci::ClassicDevice>>(device)));
 }
 
-void SecurityManager::RegisterCallbackListener(ISecurityManagerListener* listener) {
+void SecurityManager::RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler) {
   security_handler_->Post(common::BindOnce(&internal::SecurityManagerImpl::RegisterCallbackListener,
-                                           common::Unretained(security_manager_impl_),
-                                           std::forward<ISecurityManagerListener*>(listener)));
+                                           common::Unretained(security_manager_impl_), listener, handler));
 }
 
 void SecurityManager::UnregisterCallbackListener(ISecurityManagerListener* listener) {
   security_handler_->Post(common::BindOnce(&internal::SecurityManagerImpl::UnregisterCallbackListener,
-                                           common::Unretained(security_manager_impl_),
-                                           std::forward<ISecurityManagerListener*>(listener)));
+                                           common::Unretained(security_manager_impl_), listener));
 }
diff --git a/gd/security/security_manager.h b/gd/security/security_manager.h
index 6ccdd6e..deb2788 100644
--- a/gd/security/security_manager.h
+++ b/gd/security/security_manager.h
@@ -33,35 +33,28 @@
  */
 class ISecurityManagerListener {
  public:
-  ISecurityManagerListener(os::Handler* handler) : handler_(handler) {}
-  virtual ~ISecurityManagerListener() = default;
+  virtual ~ISecurityManagerListener() = 0;
 
   /**
    * Called when a device is successfully bonded.
    *
    * @param device pointer to the bonded device
    */
-  virtual void OnDeviceBonded(std::shared_ptr<bluetooth::hci::Device> device);
+  virtual void OnDeviceBonded(std::shared_ptr<bluetooth::hci::Device> device) = 0;
 
   /**
    * Called when a device is successfully un-bonded.
    *
    * @param device pointer to the device that is no longer bonded
    */
-  virtual void OnDeviceUnbonded(std::shared_ptr<bluetooth::hci::Device> device);
+  virtual void OnDeviceUnbonded(std::shared_ptr<bluetooth::hci::Device> device) = 0;
 
   /**
    * Called as a result of a failure during the bonding process.
    *
    * @param device pointer to the device that is no longer bonded
    */
-  virtual void OnDeviceBondFailed(std::shared_ptr<bluetooth::hci::Device> device);
-
-  bool operator==(const ISecurityManagerListener& rhs) const {
-    return &*this == &rhs;
-  }
-
-  os::Handler* handler_ = nullptr;
+  virtual void OnDeviceBondFailed(std::shared_ptr<bluetooth::hci::Device> device) = 0;
 };
 
 /**
@@ -103,7 +96,7 @@
    *
    * @param listener ISecurityManagerListener instance to handle callbacks
    */
-  void RegisterCallbackListener(ISecurityManagerListener* listener);
+  void RegisterCallbackListener(ISecurityManagerListener* listener, os::Handler* handler);
 
   /**
    * Unregister listener for callback events from SecurityManager