floss: Change api to set_default_event_mask_except

The suspend implementation in Floss wants to mask away some events to
prevent spurious wakes. This change updates the btif api
|set_default_event_mask| to also accept bit masks that will be disabled
from the final event mask that is sent to the controller.

As part of this change, suspend will now stop calling |clear_event_mask|
during suspend and instead will just disable the Disconnect and Mode
change events only.

Bug: 231345733
Tag: #floss
Test: Manual test on ChromeOS.
Change-Id: I0105085c465666e5a8c0e7890c36072234fe05e2
diff --git a/system/blueberry/facade/topshim/facade.proto b/system/blueberry/facade/topshim/facade.proto
index 9b0b524..d03bf0a 100644
--- a/system/blueberry/facade/topshim/facade.proto
+++ b/system/blueberry/facade/topshim/facade.proto
@@ -16,7 +16,7 @@
   rpc SetEventFilterConnectionSetupAllDevices(google.protobuf.Empty) returns (google.protobuf.Empty) {}
   rpc AllowWakeByHid(google.protobuf.Empty) returns (google.protobuf.Empty) {}
   rpc RestoreFilterAcceptList(google.protobuf.Empty) returns (google.protobuf.Empty) {}
-  rpc SetDefaultEventMask(google.protobuf.Empty) returns (google.protobuf.Empty) {}
+  rpc SetDefaultEventMaskExcept(SetDefaultEventMaskExceptRequest) returns (google.protobuf.Empty) {}
   rpc SetEventFilterInquiryResultAllDevices(google.protobuf.Empty) returns (google.protobuf.Empty) {}
 }
 
@@ -184,6 +184,11 @@
   int32 volume = 2;
 }
 
+message SetDefaultEventMaskExceptRequest {
+  uint64 mask = 1;
+  uint64 le_mask = 2;
+}
+
 // A Token representing an ACL connection.
 // It's acquired via a Connect on the Host service (Bluetooth Core stack in our case).
 message Connection {
diff --git a/system/blueberry/tests/topshim/lib/adapter_client.py b/system/blueberry/tests/topshim/lib/adapter_client.py
index a85e72e..a15b4f1 100644
--- a/system/blueberry/tests/topshim/lib/adapter_client.py
+++ b/system/blueberry/tests/topshim/lib/adapter_client.py
@@ -106,8 +106,9 @@
     async def restore_filter_accept_list(self):
         await self.__adapter_stub.RestoreFilterAcceptList(empty_proto.Empty())
 
-    async def set_default_event_mask(self):
-        await self.__adapter_stub.SetDefaultEventMask(empty_proto.Empty())
+    async def set_default_event_mask_except(self, mask, le_mask):
+        await self.__adapter_stub.SetDefaultEventMaskExcept(
+            facade_pb2.SetDefaultEventMaskExceptRequest(mask=mask, le_mask=le_mask))
 
     async def set_event_filter_inquiry_result_all_devices(self):
         await self.__adapter_stub.SetEventFilterInquiryResultAllDevices(empty_proto.Empty())
diff --git a/system/blueberry/tests/topshim/lib/topshim_device.py b/system/blueberry/tests/topshim/lib/topshim_device.py
index 2ff8043..e36499b 100644
--- a/system/blueberry/tests/topshim/lib/topshim_device.py
+++ b/system/blueberry/tests/topshim/lib/topshim_device.py
@@ -135,8 +135,8 @@
     def allow_wake_by_hid(self):
         self.__post(self.__adapter.allow_wake_by_hid())
 
-    def set_default_event_mask(self):
-        self.__post(self.__adapter.set_default_event_mask())
+    def set_default_event_mask_except(self, mask, le_mask):
+        self.__post(self.__adapter.set_default_event_mask(mask, le_mask))
 
     def set_event_filter_inquiry_result_all_devices(self):
         self.__post(self.__adapter.set_event_filter_inquiry_result_all_devices())
diff --git a/system/blueberry/tests/topshim/power/suspend_test.py b/system/blueberry/tests/topshim/power/suspend_test.py
index 79f0900..4292c05 100644
--- a/system/blueberry/tests/topshim/power/suspend_test.py
+++ b/system/blueberry/tests/topshim/power/suspend_test.py
@@ -35,7 +35,7 @@
 
     def __verify_no_wake_resume(self):
         # Start resume work
-        self.dut().set_default_event_mask()
+        self.dut().set_default_event_mask_except(0, 0)
         self.dut().set_event_filter_inquiry_result_all_devices()
         self.dut().set_event_filter_connection_setup_all_devices()
         self.dut().le_rand()
@@ -55,7 +55,7 @@
 
     def __verify_wakeful_resume(self, was_a2dp_connected):
         # Start resume work
-        self.dut().set_default_event_mask()
+        self.dut().set_default_event_mask_except(0, 0)
         self.dut().set_event_filter_inquiry_result_all_devices()
         self.dut().set_event_filter_connection_setup_all_devices()
         if was_a2dp_connected:
diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc
index ba8a93c..a1e35a0 100644
--- a/system/bta/dm/bta_dm_act.cc
+++ b/system/bta/dm/bta_dm_act.cc
@@ -4208,16 +4208,19 @@
 
 /*******************************************************************************
  *
- * Function        BTA_DmSetDefaultEventMask
+ * Function       BTA_DmSetDefaultEventMaskExcept
  *
- * Description    Floss: Set the default event mask for Classic and LE
+ * Description    Floss: Set the default event mask for Classic and LE except
+ *                the given values (they will be disabled in the final set
+ *                mask).
  *
- * Parameters
+ * Parameters     Bits set for event mask and le event mask that should be
+ *                disabled in the final value.
  *
  *******************************************************************************/
-void bta_dm_set_default_event_mask() {
+void bta_dm_set_default_event_mask_except(uint64_t mask, uint64_t le_mask) {
   // Autoplumbed
-  bluetooth::shim::BTM_SetDefaultEventMask();
+  bluetooth::shim::BTM_SetDefaultEventMaskExcept(mask, le_mask);
 }
 
 /*******************************************************************************
diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc
index 6be4b3c..e90a97a 100644
--- a/system/bta/dm/bta_dm_api.cc
+++ b/system/bta/dm/bta_dm_api.cc
@@ -751,9 +751,10 @@
   do_in_main_thread(FROM_HERE, base::Bind(bta_dm_restore_filter_accept_list));
 }
 
-void BTA_DmSetDefaultEventMask() {
-  APPL_TRACE_API("BTA_DmSetDefaultEventMask");
-  do_in_main_thread(FROM_HERE, base::Bind(bta_dm_set_default_event_mask));
+void BTA_DmSetDefaultEventMaskExcept(uint64_t mask, uint64_t le_mask) {
+  APPL_TRACE_API("BTA_DmSetDefaultEventMaskExcept");
+  do_in_main_thread(FROM_HERE, base::Bind(bta_dm_set_default_event_mask_except,
+                                          mask, le_mask));
 }
 
 void BTA_DmSetEventFilterInquiryResultAllDevices() {
diff --git a/system/bta/dm/bta_dm_int.h b/system/bta/dm/bta_dm_int.h
index 0d4a3d9..f881ef6 100644
--- a/system/bta/dm/bta_dm_int.h
+++ b/system/bta/dm/bta_dm_int.h
@@ -550,7 +550,8 @@
 extern void bta_dm_allow_wake_by_hid(
     std::vector<std::pair<RawAddress, uint8_t>> le_hid_devices);
 extern void bta_dm_restore_filter_accept_list();
-extern void bta_dm_set_default_event_mask();
+extern void bta_dm_set_default_event_mask_except(uint64_t mask,
+                                                 uint64_t le_mask);
 extern void bta_dm_set_event_filter_inquiry_result_all_devices();
 
 extern void bta_dm_ble_reset_id(void);
diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h
index effbc30..2dd8804 100644
--- a/system/bta/include/bta_api.h
+++ b/system/bta/include/bta_api.h
@@ -1314,14 +1314,17 @@
 
 /*******************************************************************************
  *
- * Function        BTA_DmSetDefaultEventMask
+ * Function       BTA_DmSetDefaultEventMaskExcept
  *
- * Description    Floss: Set the default event mask for Classic and LE
+ * Description    Floss: Set the default event mask for Classic and LE except
+ *                the given values (they will be disabled in the final set
+ *                mask).
  *
- * Parameters
+ * Parameters     Bits set for event mask and le event mask that should be
+ *                disabled in the final value.
  *
  *******************************************************************************/
-extern void BTA_DmSetDefaultEventMask();
+extern void BTA_DmSetDefaultEventMaskExcept(uint64_t mask, uint64_t le_mask);
 
 /*******************************************************************************
  *
diff --git a/system/btif/include/btif_dm.h b/system/btif/include/btif_dm.h
index 7333809..5b8fb32 100644
--- a/system/btif/include/btif_dm.h
+++ b/system/btif/include/btif_dm.h
@@ -84,7 +84,7 @@
 void btif_dm_set_event_filter_connection_setup_all_devices();
 void btif_dm_allow_wake_by_hid();
 void btif_dm_restore_filter_accept_list();
-void btif_dm_set_default_event_mask();
+void btif_dm_set_default_event_mask_except(uint64_t mask, uint64_t le_mask);
 void btif_dm_set_event_filter_inquiry_result_all_devices();
 
 /*callout for reading SMP properties from Text file*/
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index 9bd7cbe..e8cf3a6 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -710,9 +710,11 @@
   return BT_STATUS_SUCCESS;
 }
 
-static int set_default_event_mask() {
+static int set_default_event_mask_except(uint64_t mask, uint64_t le_mask) {
   if (!interface_ready()) return BT_STATUS_NOT_READY;
-  do_in_main_thread(FROM_HERE, base::BindOnce(btif_dm_set_default_event_mask));
+  do_in_main_thread(
+      FROM_HERE,
+      base::BindOnce(btif_dm_set_default_event_mask_except, mask, le_mask));
   return BT_STATUS_SUCCESS;
 }
 
@@ -1000,7 +1002,7 @@
     .le_rand = le_rand,
     .set_event_filter_inquiry_result_all_devices =
         set_event_filter_inquiry_result_all_devices,
-    .set_default_event_mask = set_default_event_mask,
+    .set_default_event_mask_except = set_default_event_mask_except,
     .restore_filter_accept_list = restore_filter_accept_list,
     .allow_wake_by_hid = allow_wake_by_hid,
     .set_event_filter_connection_setup_all_devices =
diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc
index 91316f4..52e7004 100644
--- a/system/btif/src/btif_dm.cc
+++ b/system/btif/src/btif_dm.cc
@@ -3579,9 +3579,9 @@
   BTA_DmRestoreFilterAcceptList();
 }
 
-void btif_dm_set_default_event_mask() {
+void btif_dm_set_default_event_mask_except(uint64_t mask, uint64_t le_mask) {
   // Autoplumbed
-  BTA_DmSetDefaultEventMask();
+  BTA_DmSetDefaultEventMaskExcept(mask, le_mask);
 }
 
 void btif_dm_set_event_filter_inquiry_result_all_devices() {
diff --git a/system/device/include/controller.h b/system/device/include/controller.h
index 760a392..00130aa 100644
--- a/system/device/include/controller.h
+++ b/system/device/include/controller.h
@@ -122,7 +122,7 @@
   uint8_t (*le_rand)(LeRandCallback);
   uint8_t (*set_event_filter_connection_setup_all_devices)(void);
   uint8_t (*allow_wake_by_hid)(void);
-  uint8_t (*set_default_event_mask)(void);
+  uint8_t (*set_default_event_mask_except)(uint64_t mask, uint64_t le_mask);
   uint8_t (*set_event_filter_inquiry_result_all_devices)(void);
 
 } controller_t;
diff --git a/system/gd/rust/linux/stack/src/suspend.rs b/system/gd/rust/linux/stack/src/suspend.rs
index a85c18f..54a36bd 100644
--- a/system/gd/rust/linux/stack/src/suspend.rs
+++ b/system/gd/rust/linux/stack/src/suspend.rs
@@ -49,6 +49,12 @@
     fn on_resumed(&self, suspend_id: i32);
 }
 
+/// Events that are disabled when we go into suspend. This prevents spurious wakes from
+/// events we know can happen but are not useful.
+/// Bit 4 = Disconnect Complete.
+/// Bit 19 = Mode Change.
+const MASKED_EVENTS_FOR_SUSPEND: u64 = (1u64 << 4) | (1u64 << 19);
+
 #[derive(FromPrimitive, ToPrimitive)]
 #[repr(u32)]
 pub enum SuspendType {
@@ -149,13 +155,17 @@
     }
 
     fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) {
-        self.intf.lock().unwrap().clear_event_mask();
+        // Set suspend event mask
+        self.intf.lock().unwrap().set_default_event_mask_except(MASKED_EVENTS_FOR_SUSPEND, 0u64);
+
         self.intf.lock().unwrap().clear_event_filter();
         self.intf.lock().unwrap().clear_filter_accept_list();
+
         // TODO(224602924): How do we get the advertising ids?
         self.gatt.lock().unwrap().stop_advertising_set(0);
         // TODO(224602924): How do we get the scanning ids?
         self.gatt.lock().unwrap().stop_scan(0);
+
         self.intf.lock().unwrap().disconnect_all_acls();
 
         // Handle wakeful cases (Connected/Other)
@@ -194,7 +204,7 @@
     }
 
     fn resume(&mut self) -> bool {
-        self.intf.lock().unwrap().set_default_event_mask();
+        self.intf.lock().unwrap().set_default_event_mask_except(0u64, 0u64);
         self.intf.lock().unwrap().set_event_filter_inquiry_result_all_devices();
         self.intf.lock().unwrap().set_event_filter_connection_setup_all_devices();
         if self.is_connected_suspend {
diff --git a/system/gd/rust/topshim/facade/src/adapter_service.rs b/system/gd/rust/topshim/facade/src/adapter_service.rs
index 11c5d55..0d132c4 100644
--- a/system/gd/rust/topshim/facade/src/adapter_service.rs
+++ b/system/gd/rust/topshim/facade/src/adapter_service.rs
@@ -5,8 +5,8 @@
 
 use bt_topshim_facade_protobuf::empty::Empty;
 use bt_topshim_facade_protobuf::facade::{
-    EventType, FetchEventsRequest, FetchEventsResponse, SetDiscoveryModeRequest,
-    SetDiscoveryModeResponse, ToggleStackRequest, ToggleStackResponse,
+    EventType, FetchEventsRequest, FetchEventsResponse, SetDefaultEventMaskExceptRequest,
+    SetDiscoveryModeRequest, SetDiscoveryModeResponse, ToggleStackRequest, ToggleStackResponse,
 };
 use bt_topshim_facade_protobuf::facade_grpc::{create_adapter_service, AdapterService};
 use futures::sink::SinkExt;
@@ -185,8 +185,13 @@
         })
     }
 
-    fn set_default_event_mask(&mut self, ctx: RpcContext<'_>, _req: Empty, sink: UnarySink<Empty>) {
-        self.btif_intf.lock().unwrap().set_default_event_mask();
+    fn set_default_event_mask_except(
+        &mut self,
+        ctx: RpcContext<'_>,
+        req: SetDefaultEventMaskExceptRequest,
+        sink: UnarySink<Empty>,
+    ) {
+        self.btif_intf.lock().unwrap().set_default_event_mask_except(req.mask, req.le_mask);
         ctx.spawn(async move {
             sink.success(Empty::default()).await.unwrap();
         })
diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs
index fcf9120..6f63b27 100644
--- a/system/gd/rust/topshim/src/btif.rs
+++ b/system/gd/rust/topshim/src/btif.rs
@@ -1205,8 +1205,8 @@
         ccall!(self, restore_filter_accept_list)
     }
 
-    pub fn set_default_event_mask(&self) -> i32 {
-        ccall!(self, set_default_event_mask)
+    pub fn set_default_event_mask_except(&self, mask: u64, le_mask: u64) -> i32 {
+        ccall!(self, set_default_event_mask_except, mask, le_mask)
     }
 
     pub fn set_event_filter_inquiry_result_all_devices(&self) -> i32 {
diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h
index 3295cec..8d15d2a 100644
--- a/system/include/hardware/bluetooth.h
+++ b/system/include/hardware/bluetooth.h
@@ -852,10 +852,11 @@
 
   /**
    *
-   * Floss: Set the default event mask for Classic and LE
+   * Floss: Set the default event mask for Classic and LE except the given
+   *        values (they will be disabled in the final set mask).
    *
    */
-  int (*set_default_event_mask)();
+  int (*set_default_event_mask_except)(uint64_t mask, uint64_t le_mask);
 
   /**
    *
diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc
index 0972101..159e7cf 100644
--- a/system/main/shim/btm_api.cc
+++ b/system/main/shim/btm_api.cc
@@ -1389,9 +1389,10 @@
   return BTM_SUCCESS;
 }
 
-tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMask() {
+tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMaskExcept(uint64_t mask,
+                                                           uint64_t le_mask) {
   // Autoplumbed
-  controller_get_interface()->set_default_event_mask();
+  controller_get_interface()->set_default_event_mask_except(mask, le_mask);
   return BTM_SUCCESS;
 }
 
diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h
index 9fe29f2..82846ff 100644
--- a/system/main/shim/btm_api.h
+++ b/system/main/shim/btm_api.h
@@ -1905,14 +1905,17 @@
 
 /*******************************************************************************
  *
- * Function        BTM_SetDefaultEventMask
+ * Function        BTM_SetDefaultEventMaskExcept
  *
- * Description    Floss: Set the default event mask for Classic and LE
+ * Description    Floss: Set the default event mask for Classic and LE except
+ *                the given values (they will be disabled in the final set
+ *                mask).
  *
- * Parameters
+ * Parameters     Bits set for event mask and le event mask that should be
+ *                disabled in the final value.
  *
  *******************************************************************************/
-tBTM_STATUS BTM_SetDefaultEventMask(void);
+tBTM_STATUS BTM_SetDefaultEventMaskExcept(uint64_t mask, uint64_t le_mask);
 
 /*******************************************************************************
  *
diff --git a/system/main/shim/controller.cc b/system/main/shim/controller.cc
index b46b639..b28323c 100644
--- a/system/main/shim/controller.cc
+++ b/system/main/shim/controller.cc
@@ -340,11 +340,15 @@
   return BTM_SUCCESS;
 }
 
-static uint8_t controller_set_default_event_mask() {
-  bluetooth::shim::GetController()->SetEventMask(
-      bluetooth::hci::Controller::kDefaultEventMask);
-  bluetooth::shim::GetController()->LeSetEventMask(
-      bluetooth::hci::Controller::kDefaultLeEventMask);
+static uint8_t controller_set_default_event_mask_except(uint64_t mask,
+                                                        uint64_t le_mask) {
+  uint64_t applied_mask =
+      bluetooth::hci::Controller::kDefaultEventMask & ~(mask);
+  uint64_t applied_le_mask =
+      bluetooth::hci::Controller::kDefaultLeEventMask & ~(le_mask);
+
+  bluetooth::shim::GetController()->SetEventMask(applied_mask);
+  bluetooth::shim::GetController()->LeSetEventMask(applied_le_mask);
   return BTM_SUCCESS;
 }
 
@@ -457,7 +461,7 @@
     .set_event_filter_connection_setup_all_devices =
         controller_set_event_filter_connection_setup_all_devices,
     .allow_wake_by_hid = controller_allow_wake_by_hid,
-    .set_default_event_mask = controller_set_default_event_mask,
+    .set_default_event_mask_except = controller_set_default_event_mask_except,
     .set_event_filter_inquiry_result_all_devices =
         controller_set_event_filter_inquiry_result_all_devices};
 
diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc
index bcd7382..4616890 100644
--- a/system/service/hal/fake_bluetooth_interface.cc
+++ b/system/service/hal/fake_bluetooth_interface.cc
@@ -89,7 +89,7 @@
     nullptr, /* set_event_filter_connection_setup_all_devices */
     nullptr, /* allow_wake_by_hid */
     nullptr, /* restore_filter_accept_list */
-    nullptr, /* set_default_event_mask */
+    nullptr, /* set_default_event_mask_except */
     nullptr, /* set_event_filter_inquiry_result_all_devices */
     nullptr, /* get_wbs_supported */
 };
diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc
index ed63b61..1dfcce7 100644
--- a/system/test/mock/mock_bluetooth_interface.cc
+++ b/system/test/mock/mock_bluetooth_interface.cc
@@ -161,7 +161,9 @@
 
 static int set_event_filter_inquiry_result_all_devices() { return 0; }
 
-static int set_default_event_mask() { return 0; }
+static int set_default_event_mask_except(uint64_t mask, uint64_t le_mask) {
+  return 0;
+}
 
 static int restore_filter_accept_list() { return 0; }
 
@@ -217,7 +219,7 @@
     set_event_filter_connection_setup_all_devices,
     allow_wake_by_hid,
     restore_filter_accept_list,
-    set_default_event_mask,
+    set_default_event_mask_except,
     set_event_filter_inquiry_result_all_devices};
 
 // callback reporting helpers
diff --git a/system/test/mock/mock_device_controller.cc b/system/test/mock/mock_device_controller.cc
index dc76733..8936b45 100644
--- a/system/test/mock/mock_device_controller.cc
+++ b/system/test/mock/mock_device_controller.cc
@@ -376,7 +376,9 @@
   return BTM_SUCCESS;
 }
 tBTM_STATUS allow_wake_by_hid() { return BTM_SUCCESS; }
-tBTM_STATUS set_default_event_mask() { return BTM_SUCCESS; }
+tBTM_STATUS set_default_event_mask_except(uint64_t mask, uint64_t le_mask) {
+  return BTM_SUCCESS;
+}
 tBTM_STATUS set_event_filter_inquiry_result_all_devices() {
   return BTM_SUCCESS;
 }
@@ -471,7 +473,7 @@
     le_rand,
     set_event_filter_connection_setup_all_devices,
     allow_wake_by_hid,
-    set_default_event_mask,
+    set_default_event_mask_except,
     set_event_filter_inquiry_result_all_devices};
 
 }  // namespace device_controller
diff --git a/system/test/mock/mock_main_shim_btm_api.cc b/system/test/mock/mock_main_shim_btm_api.cc
index dc71b6b..928592e 100644
--- a/system/test/mock/mock_main_shim_btm_api.cc
+++ b/system/test/mock/mock_main_shim_btm_api.cc
@@ -466,7 +466,8 @@
   return BTM_SUCCESS;
 }
 
-tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMask() {
+tBTM_STATUS bluetooth::shim::BTM_SetDefaultEventMaskExcept(uint64_t mask,
+                                                           uint64_t le_mask) {
   mock_function_count_map[__func__]++;
   return BTM_SUCCESS;
 }