1*635a8641SAndroid Build Coastguard WorkerFrom c2e55024c6a03dcb099270718e70139542d8b0e4 Mon Sep 17 00:00:00 2001
2*635a8641SAndroid Build Coastguard WorkerFrom: Bing Xue <[email protected]>
3*635a8641SAndroid Build Coastguard WorkerDate: Thu, 1 Aug 2019 15:47:10 -0700
4*635a8641SAndroid Build Coastguard WorkerSubject: [PATCH] Connect to NameOwnerChanged signal when setting callback
5*635a8641SAndroid Build Coastguard Worker
6*635a8641SAndroid Build Coastguard WorkerIn ObjectManager, when ConnectToNameOwnerChangedSignal is called the first time,
7*635a8641SAndroid Build Coastguard Workerwe could have already missed the NameOwnerChanged signal if we get a value from
8*635a8641SAndroid Build Coastguard WorkerUpdateNameOwnerAndBlock. This means NameOwnerChanged callbacks will
9*635a8641SAndroid Build Coastguard Workernever be called until that service restarts. In ObjectManager we run
10*635a8641SAndroid Build Coastguard Workerinto this problem:
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker1. ObjectManager::SetupMatchRuleAndFilter is called, calling
13*635a8641SAndroid Build Coastguard Workerbus_->GetServiceOwnerAndBlock shows empty service name owner.
14*635a8641SAndroid Build Coastguard Worker
15*635a8641SAndroid Build Coastguard Worker2. ObjectManager::OnSetupManagerRuleAndFilterComplete callback will call
16*635a8641SAndroid Build Coastguard Workerobject_proxy_->ConnectToSignal, which in turn calls
17*635a8641SAndroid Build Coastguard WorkerConnectToNameOwnerChangedSignal the first time. At this point,
18*635a8641SAndroid Build Coastguard WorkerUpdateNameOwnerAndBlock calling bus_->GetServiceOwnerAndBlock returns the
19*635a8641SAndroid Build Coastguard Workercurrent name owner of the service, this means the NameOwnerChanged signal
20*635a8641SAndroid Build Coastguard Workeris already sent on system bus.
21*635a8641SAndroid Build Coastguard Worker
22*635a8641SAndroid Build Coastguard Worker3. As a result, ObjectManager::NameOwnerChanged is never called while
23*635a8641SAndroid Build Coastguard Workerthe service is already online. This in turn causes GetManagedObject to
24*635a8641SAndroid Build Coastguard Workernever be called, and the object manager interface never added.
25*635a8641SAndroid Build Coastguard Worker
26*635a8641SAndroid Build Coastguard WorkerSee detailed sample logs in b/138416411.
27*635a8641SAndroid Build Coastguard Worker
28*635a8641SAndroid Build Coastguard WorkerThis CL adds the following:
29*635a8641SAndroid Build Coastguard Worker
30*635a8641SAndroid Build Coastguard Worker1. Make SetNameOwnerChangedCallback run
31*635a8641SAndroid Build Coastguard WorkerConnectToNameOwnerChangedSignal when called. Since ObjectManager calls
32*635a8641SAndroid Build Coastguard WorkerSetNameOwnerChangedCallback before posting SetupMatchRuleAndFilter (in which
33*635a8641SAndroid Build Coastguard WorkerObjectManager attempts to get the service name owner through a blocking call),
34*635a8641SAndroid Build Coastguard Workerthis removes the time gap described above that causes lost signal.
35*635a8641SAndroid Build Coastguard Worker
36*635a8641SAndroid Build Coastguard Worker2. Make dbus thread the only writer to |service_name_owner_|, given that
37*635a8641SAndroid Build Coastguard Workerconnecting to the NameOwnerChanged signal right away in ObjectManager
38*635a8641SAndroid Build Coastguard Workerctor causes potential data race in writing to |service_name_owner_| in
39*635a8641SAndroid Build Coastguard Workerboth NameOwnerChanged (on origin thread) and SetupMatchRuleAndFilter (on
40*635a8641SAndroid Build Coastguard Workerdbus thread).
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard WorkerBUG=b:138416411
43*635a8641SAndroid Build Coastguard WorkerTEST=Manually on device.
44*635a8641SAndroid Build Coastguard Worker
45*635a8641SAndroid Build Coastguard WorkerChange-Id: Ie95a5b7b303637acadebda151cc478e52b6a1af5
46*635a8641SAndroid Build Coastguard Worker---
47*635a8641SAndroid Build Coastguard Worker dbus/object_manager.cc | 20 +++++++++++++++++---
48*635a8641SAndroid Build Coastguard Worker dbus/object_manager.h  |  5 +++++
49*635a8641SAndroid Build Coastguard Worker dbus/object_proxy.cc   | 13 +++++++++++++
50*635a8641SAndroid Build Coastguard Worker dbus/object_proxy.h    |  3 +++
51*635a8641SAndroid Build Coastguard Worker 4 files changed, 38 insertions(+), 3 deletions(-)
52*635a8641SAndroid Build Coastguard Worker
53*635a8641SAndroid Build Coastguard Workerdiff --git a/dbus/object_manager.cc b/dbus/object_manager.cc
54*635a8641SAndroid Build Coastguard Workerindex 05d4b2ddeabd..44f120864310 100644
55*635a8641SAndroid Build Coastguard Worker--- a/dbus/object_manager.cc
56*635a8641SAndroid Build Coastguard Worker+++ b/dbus/object_manager.cc
57*635a8641SAndroid Build Coastguard Worker@@ -187,8 +187,12 @@ bool ObjectManager::SetupMatchRuleAndFilter() {
58*635a8641SAndroid Build Coastguard Worker   if (!bus_->Connect() || !bus_->SetUpAsyncOperations())
59*635a8641SAndroid Build Coastguard Worker     return false;
60*635a8641SAndroid Build Coastguard Worker
61*635a8641SAndroid Build Coastguard Worker-  service_name_owner_ =
62*635a8641SAndroid Build Coastguard Worker-      bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS);
63*635a8641SAndroid Build Coastguard Worker+  // Try to get |service_name_owner_| from dbus if we haven't received any
64*635a8641SAndroid Build Coastguard Worker+  // NameOwnerChanged signals.
65*635a8641SAndroid Build Coastguard Worker+  if (service_name_owner_.empty()) {
66*635a8641SAndroid Build Coastguard Worker+    service_name_owner_ =
67*635a8641SAndroid Build Coastguard Worker+        bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS);
68*635a8641SAndroid Build Coastguard Worker+  }
69*635a8641SAndroid Build Coastguard Worker
70*635a8641SAndroid Build Coastguard Worker   const std::string match_rule =
71*635a8641SAndroid Build Coastguard Worker       base::StringPrintf(
72*635a8641SAndroid Build Coastguard Worker@@ -224,6 +228,7 @@ void ObjectManager::OnSetupMatchRuleAndFilterComplete(bool success) {
73*635a8641SAndroid Build Coastguard Worker   DCHECK(bus_);
74*635a8641SAndroid Build Coastguard Worker   DCHECK(object_proxy_);
75*635a8641SAndroid Build Coastguard Worker   DCHECK(setup_success_);
76*635a8641SAndroid Build Coastguard Worker+  bus_->AssertOnOriginThread();
77*635a8641SAndroid Build Coastguard Worker
78*635a8641SAndroid Build Coastguard Worker   // |object_proxy_| is no longer valid if the Bus was shut down before this
79*635a8641SAndroid Build Coastguard Worker   // call. Don't initiate any other action from the origin thread.
80*635a8641SAndroid Build Coastguard Worker@@ -505,9 +510,18 @@ void ObjectManager::RemoveInterface(const ObjectPath& object_path,
81*635a8641SAndroid Build Coastguard Worker   }
82*635a8641SAndroid Build Coastguard Worker }
83*635a8641SAndroid Build Coastguard Worker
84*635a8641SAndroid Build Coastguard Worker+void ObjectManager::UpdateServiceNameOwner(const std::string& new_owner) {
85*635a8641SAndroid Build Coastguard Worker+  bus_->AssertOnDBusThread();
86*635a8641SAndroid Build Coastguard Worker+  service_name_owner_ = new_owner;
87*635a8641SAndroid Build Coastguard Worker+}
88*635a8641SAndroid Build Coastguard Worker+
89*635a8641SAndroid Build Coastguard Worker void ObjectManager::NameOwnerChanged(const std::string& old_owner,
90*635a8641SAndroid Build Coastguard Worker                                      const std::string& new_owner) {
91*635a8641SAndroid Build Coastguard Worker-  service_name_owner_ = new_owner;
92*635a8641SAndroid Build Coastguard Worker+  bus_->AssertOnOriginThread();
93*635a8641SAndroid Build Coastguard Worker+
94*635a8641SAndroid Build Coastguard Worker+  bus_->GetDBusTaskRunner()->PostTask(
95*635a8641SAndroid Build Coastguard Worker+      FROM_HERE,
96*635a8641SAndroid Build Coastguard Worker+      base::BindOnce(&ObjectManager::UpdateServiceNameOwner, this, new_owner));
97*635a8641SAndroid Build Coastguard Worker
98*635a8641SAndroid Build Coastguard Worker   if (!old_owner.empty()) {
99*635a8641SAndroid Build Coastguard Worker     ObjectMap::iterator iter = object_map_.begin();
100*635a8641SAndroid Build Coastguard Workerdiff --git a/dbus/object_manager.h b/dbus/object_manager.h
101*635a8641SAndroid Build Coastguard Workerindex 05388de8e6eb..4b5fb790412d 100644
102*635a8641SAndroid Build Coastguard Worker--- a/dbus/object_manager.h
103*635a8641SAndroid Build Coastguard Worker+++ b/dbus/object_manager.h
104*635a8641SAndroid Build Coastguard Worker@@ -317,6 +317,11 @@ class CHROME_DBUS_EXPORT ObjectManager final
105*635a8641SAndroid Build Coastguard Worker   void NameOwnerChanged(const std::string& old_owner,
106*635a8641SAndroid Build Coastguard Worker                         const std::string& new_owner);
107*635a8641SAndroid Build Coastguard Worker
108*635a8641SAndroid Build Coastguard Worker+  // Write |new_owner| to |service_name_owner_|. This method makes sure write
109*635a8641SAndroid Build Coastguard Worker+  // happens on the DBus thread, which is the sole writer to
110*635a8641SAndroid Build Coastguard Worker+  // |service_name_owner_|.
111*635a8641SAndroid Build Coastguard Worker+  void UpdateServiceNameOwner(const std::string& new_owner);
112*635a8641SAndroid Build Coastguard Worker+
113*635a8641SAndroid Build Coastguard Worker   Bus* bus_;
114*635a8641SAndroid Build Coastguard Worker   std::string service_name_;
115*635a8641SAndroid Build Coastguard Worker   std::string service_name_owner_;
116*635a8641SAndroid Build Coastguard Workerdiff --git a/dbus/object_proxy.cc b/dbus/object_proxy.cc
117*635a8641SAndroid Build Coastguard Workerindex 7adf8f179471..de5785e98307 100644
118*635a8641SAndroid Build Coastguard Worker--- a/dbus/object_proxy.cc
119*635a8641SAndroid Build Coastguard Worker+++ b/dbus/object_proxy.cc
120*635a8641SAndroid Build Coastguard Worker@@ -274,6 +274,10 @@ void ObjectProxy::SetNameOwnerChangedCallback(
121*635a8641SAndroid Build Coastguard Worker   bus_->AssertOnOriginThread();
122*635a8641SAndroid Build Coastguard Worker
123*635a8641SAndroid Build Coastguard Worker   name_owner_changed_callback_ = callback;
124*635a8641SAndroid Build Coastguard Worker+
125*635a8641SAndroid Build Coastguard Worker+  bus_->GetDBusTaskRunner()->PostTask(
126*635a8641SAndroid Build Coastguard Worker+      FROM_HERE,
127*635a8641SAndroid Build Coastguard Worker+      base::BindOnce(&ObjectProxy::TryConnectToNameOwnerChangedSignal, this));
128*635a8641SAndroid Build Coastguard Worker }
129*635a8641SAndroid Build Coastguard Worker
130*635a8641SAndroid Build Coastguard Worker void ObjectProxy::WaitForServiceToBeAvailable(
131*635a8641SAndroid Build Coastguard Worker@@ -458,6 +462,15 @@ bool ObjectProxy::ConnectToNameOwnerChangedSignal() {
132*635a8641SAndroid Build Coastguard Worker   return success;
133*635a8641SAndroid Build Coastguard Worker }
134*635a8641SAndroid Build Coastguard Worker
135*635a8641SAndroid Build Coastguard Worker+void ObjectProxy::TryConnectToNameOwnerChangedSignal() {
136*635a8641SAndroid Build Coastguard Worker+  bus_->AssertOnDBusThread();
137*635a8641SAndroid Build Coastguard Worker+
138*635a8641SAndroid Build Coastguard Worker+  bool success = ConnectToNameOwnerChangedSignal();
139*635a8641SAndroid Build Coastguard Worker+  LOG_IF(WARNING, !success)
140*635a8641SAndroid Build Coastguard Worker+      << "Failed to connect to NameOwnerChanged signal for object: "
141*635a8641SAndroid Build Coastguard Worker+      << object_path_.value();
142*635a8641SAndroid Build Coastguard Worker+}
143*635a8641SAndroid Build Coastguard Worker+
144*635a8641SAndroid Build Coastguard Worker bool ObjectProxy::ConnectToSignalInternal(const std::string& interface_name,
145*635a8641SAndroid Build Coastguard Worker                                           const std::string& signal_name,
146*635a8641SAndroid Build Coastguard Worker                                           SignalCallback signal_callback) {
147*635a8641SAndroid Build Coastguard Workerdiff --git a/dbus/object_proxy.h b/dbus/object_proxy.h
148*635a8641SAndroid Build Coastguard Workerindex 22e44f1d64c0..b1bf622a12cb 100644
149*635a8641SAndroid Build Coastguard Worker--- a/dbus/object_proxy.h
150*635a8641SAndroid Build Coastguard Worker+++ b/dbus/object_proxy.h
151*635a8641SAndroid Build Coastguard Worker@@ -267,6 +267,9 @@ class CHROME_DBUS_EXPORT ObjectProxy
152*635a8641SAndroid Build Coastguard Worker   // Connects to NameOwnerChanged signal.
153*635a8641SAndroid Build Coastguard Worker   bool ConnectToNameOwnerChangedSignal();
154*635a8641SAndroid Build Coastguard Worker
155*635a8641SAndroid Build Coastguard Worker+  // Tries to connect to NameOwnerChanged signal, ignores any error.
156*635a8641SAndroid Build Coastguard Worker+  void TryConnectToNameOwnerChangedSignal();
157*635a8641SAndroid Build Coastguard Worker+
158*635a8641SAndroid Build Coastguard Worker   // Helper function for ConnectToSignal().
159*635a8641SAndroid Build Coastguard Worker   bool ConnectToSignalInternal(const std::string& interface_name,
160*635a8641SAndroid Build Coastguard Worker                                const std::string& signal_name,
161*635a8641SAndroid Build Coastguard Worker--
162*635a8641SAndroid Build Coastguard Worker2.22.0.770.g0f2c4a37fd-goog
163*635a8641SAndroid Build Coastguard Worker
164