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