xref: /aosp_15_r20/external/libbrillo/brillo/dbus/async_event_sequencer.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2014 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #include <brillo/dbus/async_event_sequencer.h>
6*1a96fba6SXin Li 
7*1a96fba6SXin Li #include <base/bind.h>
8*1a96fba6SXin Li #include <base/callback.h>
9*1a96fba6SXin Li 
10*1a96fba6SXin Li namespace brillo {
11*1a96fba6SXin Li 
12*1a96fba6SXin Li namespace dbus_utils {
13*1a96fba6SXin Li 
AsyncEventSequencer()14*1a96fba6SXin Li AsyncEventSequencer::AsyncEventSequencer() {
15*1a96fba6SXin Li }
~AsyncEventSequencer()16*1a96fba6SXin Li AsyncEventSequencer::~AsyncEventSequencer() {
17*1a96fba6SXin Li }
18*1a96fba6SXin Li 
GetHandler(const std::string & descriptive_message,bool failure_is_fatal)19*1a96fba6SXin Li AsyncEventSequencer::Handler AsyncEventSequencer::GetHandler(
20*1a96fba6SXin Li     const std::string& descriptive_message,
21*1a96fba6SXin Li     bool failure_is_fatal) {
22*1a96fba6SXin Li   CHECK(!started_) << "Cannot create handlers after OnAllTasksCompletedCall()";
23*1a96fba6SXin Li   int unique_registration_id = ++registration_counter_;
24*1a96fba6SXin Li   outstanding_registrations_.insert(unique_registration_id);
25*1a96fba6SXin Li   return base::Bind(&AsyncEventSequencer::HandleFinish,
26*1a96fba6SXin Li                     this,
27*1a96fba6SXin Li                     unique_registration_id,
28*1a96fba6SXin Li                     descriptive_message,
29*1a96fba6SXin Li                     failure_is_fatal);
30*1a96fba6SXin Li }
31*1a96fba6SXin Li 
GetExportHandler(const std::string & interface_name,const std::string & method_name,const std::string & descriptive_message,bool failure_is_fatal)32*1a96fba6SXin Li AsyncEventSequencer::ExportHandler AsyncEventSequencer::GetExportHandler(
33*1a96fba6SXin Li     const std::string& interface_name,
34*1a96fba6SXin Li     const std::string& method_name,
35*1a96fba6SXin Li     const std::string& descriptive_message,
36*1a96fba6SXin Li     bool failure_is_fatal) {
37*1a96fba6SXin Li   auto finish_handler = GetHandler(descriptive_message, failure_is_fatal);
38*1a96fba6SXin Li   return base::Bind(&AsyncEventSequencer::HandleDBusMethodExported,
39*1a96fba6SXin Li                     this,
40*1a96fba6SXin Li                     finish_handler,
41*1a96fba6SXin Li                     interface_name,
42*1a96fba6SXin Li                     method_name);
43*1a96fba6SXin Li }
44*1a96fba6SXin Li 
OnAllTasksCompletedCall(std::vector<CompletionAction> actions)45*1a96fba6SXin Li void AsyncEventSequencer::OnAllTasksCompletedCall(
46*1a96fba6SXin Li     std::vector<CompletionAction> actions) {
47*1a96fba6SXin Li   CHECK(!started_) << "OnAllTasksCompletedCall called twice!";
48*1a96fba6SXin Li   started_ = true;
49*1a96fba6SXin Li   completion_actions_.assign(actions.begin(), actions.end());
50*1a96fba6SXin Li   // All of our callbacks might have been called already.
51*1a96fba6SXin Li   PossiblyRunCompletionActions();
52*1a96fba6SXin Li }
53*1a96fba6SXin Li 
54*1a96fba6SXin Li namespace {
IgnoreSuccess(const AsyncEventSequencer::CompletionTask & task,bool)55*1a96fba6SXin Li void IgnoreSuccess(const AsyncEventSequencer::CompletionTask& task,
56*1a96fba6SXin Li                    bool /*success*/) {
57*1a96fba6SXin Li   task.Run();
58*1a96fba6SXin Li }
DoNothing(bool)59*1a96fba6SXin Li void DoNothing(bool /* success */) {
60*1a96fba6SXin Li }
61*1a96fba6SXin Li }  // namespace
62*1a96fba6SXin Li 
WrapCompletionTask(const CompletionTask & task)63*1a96fba6SXin Li AsyncEventSequencer::CompletionAction AsyncEventSequencer::WrapCompletionTask(
64*1a96fba6SXin Li     const CompletionTask& task) {
65*1a96fba6SXin Li   return base::Bind(&IgnoreSuccess, task);
66*1a96fba6SXin Li }
67*1a96fba6SXin Li 
68*1a96fba6SXin Li AsyncEventSequencer::CompletionAction
GetDefaultCompletionAction()69*1a96fba6SXin Li AsyncEventSequencer::GetDefaultCompletionAction() {
70*1a96fba6SXin Li   return base::Bind(&DoNothing);
71*1a96fba6SXin Li }
72*1a96fba6SXin Li 
HandleFinish(int registration_number,const std::string & error_message,bool failure_is_fatal,bool success)73*1a96fba6SXin Li void AsyncEventSequencer::HandleFinish(int registration_number,
74*1a96fba6SXin Li                                        const std::string& error_message,
75*1a96fba6SXin Li                                        bool failure_is_fatal,
76*1a96fba6SXin Li                                        bool success) {
77*1a96fba6SXin Li   RetireRegistration(registration_number);
78*1a96fba6SXin Li   CheckForFailure(failure_is_fatal, success, error_message);
79*1a96fba6SXin Li   PossiblyRunCompletionActions();
80*1a96fba6SXin Li }
81*1a96fba6SXin Li 
HandleDBusMethodExported(const AsyncEventSequencer::Handler & finish_handler,const std::string & expected_interface_name,const std::string & expected_method_name,const std::string & actual_interface_name,const std::string & actual_method_name,bool success)82*1a96fba6SXin Li void AsyncEventSequencer::HandleDBusMethodExported(
83*1a96fba6SXin Li     const AsyncEventSequencer::Handler& finish_handler,
84*1a96fba6SXin Li     const std::string& expected_interface_name,
85*1a96fba6SXin Li     const std::string& expected_method_name,
86*1a96fba6SXin Li     const std::string& actual_interface_name,
87*1a96fba6SXin Li     const std::string& actual_method_name,
88*1a96fba6SXin Li     bool success) {
89*1a96fba6SXin Li   CHECK_EQ(expected_method_name, actual_method_name)
90*1a96fba6SXin Li       << "Exported DBus method '" << actual_method_name << "' "
91*1a96fba6SXin Li       << "but expected '" << expected_method_name << "'";
92*1a96fba6SXin Li   CHECK_EQ(expected_interface_name, actual_interface_name)
93*1a96fba6SXin Li       << "Exported method DBus interface '" << actual_interface_name << "' "
94*1a96fba6SXin Li       << "but expected '" << expected_interface_name << "'";
95*1a96fba6SXin Li   finish_handler.Run(success);
96*1a96fba6SXin Li }
97*1a96fba6SXin Li 
RetireRegistration(int registration_number)98*1a96fba6SXin Li void AsyncEventSequencer::RetireRegistration(int registration_number) {
99*1a96fba6SXin Li   const size_t handlers_retired =
100*1a96fba6SXin Li       outstanding_registrations_.erase(registration_number);
101*1a96fba6SXin Li   CHECK_EQ(1U, handlers_retired) << "Tried to retire invalid handler "
102*1a96fba6SXin Li                                  << registration_number << ")";
103*1a96fba6SXin Li }
104*1a96fba6SXin Li 
CheckForFailure(bool failure_is_fatal,bool success,const std::string & error_message)105*1a96fba6SXin Li void AsyncEventSequencer::CheckForFailure(bool failure_is_fatal,
106*1a96fba6SXin Li                                           bool success,
107*1a96fba6SXin Li                                           const std::string& error_message) {
108*1a96fba6SXin Li   if (failure_is_fatal) {
109*1a96fba6SXin Li     CHECK(success) << error_message;
110*1a96fba6SXin Li   }
111*1a96fba6SXin Li   if (!success) {
112*1a96fba6SXin Li     LOG(ERROR) << error_message;
113*1a96fba6SXin Li     had_failures_ = true;
114*1a96fba6SXin Li   }
115*1a96fba6SXin Li }
116*1a96fba6SXin Li 
PossiblyRunCompletionActions()117*1a96fba6SXin Li void AsyncEventSequencer::PossiblyRunCompletionActions() {
118*1a96fba6SXin Li   if (!started_ || !outstanding_registrations_.empty()) {
119*1a96fba6SXin Li     // Don't run completion actions if we have any outstanding
120*1a96fba6SXin Li     // Handlers outstanding or if any more handlers might
121*1a96fba6SXin Li     // be scheduled in the future.
122*1a96fba6SXin Li     return;
123*1a96fba6SXin Li   }
124*1a96fba6SXin Li   for (const auto& completion_action : completion_actions_) {
125*1a96fba6SXin Li     // Should this be put on the message loop or run directly?
126*1a96fba6SXin Li     completion_action.Run(!had_failures_);
127*1a96fba6SXin Li   }
128*1a96fba6SXin Li   // Discard our references to those actions.
129*1a96fba6SXin Li   completion_actions_.clear();
130*1a96fba6SXin Li }
131*1a96fba6SXin Li 
132*1a96fba6SXin Li }  // namespace dbus_utils
133*1a96fba6SXin Li 
134*1a96fba6SXin Li }  // namespace brillo
135