OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "dbus/bus.h" | 5 #include "dbus/bus.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/strings/string_piece.h" | 11 #include "base/strings/string_piece.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "base/task_runner_util.h" |
13 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
14 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
15 #include "dbus/dbus_statistics.h" | 16 #include "dbus/dbus_statistics.h" |
16 #include "dbus/message.h" | 17 #include "dbus/message.h" |
17 #include "dbus/object_path.h" | 18 #include "dbus/object_path.h" |
18 #include "dbus/object_proxy.h" | 19 #include "dbus/object_proxy.h" |
19 #include "dbus/scoped_dbus_error.h" | 20 #include "dbus/scoped_dbus_error.h" |
20 | 21 |
21 namespace dbus { | 22 namespace dbus { |
22 | 23 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 // Wait for the response in the D-Bus thread. | 165 // Wait for the response in the D-Bus thread. |
165 bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, task); | 166 bus_->GetDBusTaskRunner()->PostTask(FROM_HERE, task); |
166 } | 167 } |
167 | 168 |
168 void ObjectProxy::ConnectToSignal(const std::string& interface_name, | 169 void ObjectProxy::ConnectToSignal(const std::string& interface_name, |
169 const std::string& signal_name, | 170 const std::string& signal_name, |
170 SignalCallback signal_callback, | 171 SignalCallback signal_callback, |
171 OnConnectedCallback on_connected_callback) { | 172 OnConnectedCallback on_connected_callback) { |
172 bus_->AssertOnOriginThread(); | 173 bus_->AssertOnOriginThread(); |
173 | 174 |
174 bus_->GetDBusTaskRunner()->PostTask( | 175 base::PostTaskAndReplyWithResult( |
| 176 bus_->GetDBusTaskRunner(), |
175 FROM_HERE, | 177 FROM_HERE, |
176 base::Bind(&ObjectProxy::ConnectToSignalInternal, | 178 base::Bind(&ObjectProxy::ConnectToSignalInternal, |
177 this, | 179 this, |
178 interface_name, | 180 interface_name, |
179 signal_name, | 181 signal_name, |
180 signal_callback, | 182 signal_callback), |
181 on_connected_callback)); | 183 base::Bind(on_connected_callback, |
| 184 interface_name, |
| 185 signal_name)); |
182 } | 186 } |
183 | 187 |
184 void ObjectProxy::Detach() { | 188 void ObjectProxy::Detach() { |
185 bus_->AssertOnDBusThread(); | 189 bus_->AssertOnDBusThread(); |
186 | 190 |
187 if (filter_added_) { | 191 if (filter_added_) { |
188 if (!bus_->RemoveFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { | 192 if (!bus_->RemoveFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { |
189 LOG(ERROR) << "Failed to remove filter function"; | 193 LOG(ERROR) << "Failed to remove filter function"; |
190 } | 194 } |
191 } | 195 } |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 OnPendingCallIsCompleteData* data = | 350 OnPendingCallIsCompleteData* data = |
347 reinterpret_cast<OnPendingCallIsCompleteData*>(user_data); | 351 reinterpret_cast<OnPendingCallIsCompleteData*>(user_data); |
348 ObjectProxy* self = data->object_proxy; | 352 ObjectProxy* self = data->object_proxy; |
349 self->OnPendingCallIsComplete(pending_call, | 353 self->OnPendingCallIsComplete(pending_call, |
350 data->response_callback, | 354 data->response_callback, |
351 data->error_callback, | 355 data->error_callback, |
352 data->start_time); | 356 data->start_time); |
353 delete data; | 357 delete data; |
354 } | 358 } |
355 | 359 |
356 void ObjectProxy::ConnectToSignalInternal( | 360 bool ObjectProxy::ConnectToSignalInternal(const std::string& interface_name, |
357 const std::string& interface_name, | 361 const std::string& signal_name, |
358 const std::string& signal_name, | 362 SignalCallback signal_callback) { |
359 SignalCallback signal_callback, | |
360 OnConnectedCallback on_connected_callback) { | |
361 bus_->AssertOnDBusThread(); | 363 bus_->AssertOnDBusThread(); |
362 | 364 |
363 const std::string absolute_signal_name = | 365 const std::string absolute_signal_name = |
364 GetAbsoluteSignalName(interface_name, signal_name); | 366 GetAbsoluteSignalName(interface_name, signal_name); |
365 | 367 |
366 // Will become true, if everything is successful. | 368 if (!bus_->Connect() || !bus_->SetUpAsyncOperations()) |
367 bool success = false; | 369 return false; |
368 | 370 |
369 if (bus_->Connect() && bus_->SetUpAsyncOperations()) { | 371 // We should add the filter only once. Otherwise, HandleMessage() will |
370 // We should add the filter only once. Otherwise, HandleMessage() will | 372 // be called more than once. |
371 // be called more than once. | 373 if (!filter_added_) { |
372 if (!filter_added_) { | 374 if (bus_->AddFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { |
373 if (bus_->AddFilterFunction(&ObjectProxy::HandleMessageThunk, this)) { | 375 filter_added_ = true; |
374 filter_added_ = true; | 376 } else { |
375 } else { | 377 LOG(ERROR) << "Failed to add filter function"; |
376 LOG(ERROR) << "Failed to add filter function"; | |
377 } | |
378 } | 378 } |
379 // Add a match rule so the signal goes through HandleMessage(). | 379 } |
380 const std::string match_rule = | 380 // Add a match rule so the signal goes through HandleMessage(). |
381 base::StringPrintf("type='signal', interface='%s', path='%s'", | 381 const std::string match_rule = |
382 interface_name.c_str(), | 382 base::StringPrintf("type='signal', interface='%s', path='%s'", |
383 object_path_.value().c_str()); | 383 interface_name.c_str(), |
384 // Add a match_rule listening NameOwnerChanged for the well-known name | 384 object_path_.value().c_str()); |
385 // |service_name_|. | 385 // Add a match_rule listening NameOwnerChanged for the well-known name |
386 const std::string name_owner_changed_match_rule = | 386 // |service_name_|. |
387 base::StringPrintf( | 387 const std::string name_owner_changed_match_rule = |
388 "type='signal',interface='org.freedesktop.DBus'," | 388 base::StringPrintf( |
389 "member='NameOwnerChanged',path='/org/freedesktop/DBus'," | 389 "type='signal',interface='org.freedesktop.DBus'," |
390 "sender='org.freedesktop.DBus',arg0='%s'", | 390 "member='NameOwnerChanged',path='/org/freedesktop/DBus'," |
391 service_name_.c_str()); | 391 "sender='org.freedesktop.DBus',arg0='%s'", |
392 if (AddMatchRuleWithCallback(match_rule, | 392 service_name_.c_str()); |
393 absolute_signal_name, | |
394 signal_callback) && | |
395 AddMatchRuleWithoutCallback(name_owner_changed_match_rule, | |
396 "org.freedesktop.DBus.NameOwnerChanged")) { | |
397 success = true; | |
398 } | |
399 | 393 |
400 // Try getting the current name owner. It's not guaranteed that we can get | 394 const bool success = |
401 // the name owner at this moment, as the service may not yet be started. If | 395 AddMatchRuleWithCallback(match_rule, |
402 // that's the case, we'll get the name owner via NameOwnerChanged signal, | 396 absolute_signal_name, |
403 // as soon as the service is started. | 397 signal_callback) && |
404 UpdateNameOwnerAndBlock(); | 398 AddMatchRuleWithoutCallback(name_owner_changed_match_rule, |
405 } | 399 "org.freedesktop.DBus.NameOwnerChanged"); |
406 | 400 |
407 // Run on_connected_callback in the origin thread. | 401 // Try getting the current name owner. It's not guaranteed that we can get |
408 bus_->GetOriginTaskRunner()->PostTask( | 402 // the name owner at this moment, as the service may not yet be started. If |
409 FROM_HERE, | 403 // that's the case, we'll get the name owner via NameOwnerChanged signal, |
410 base::Bind(&ObjectProxy::OnConnected, | 404 // as soon as the service is started. |
411 this, | 405 UpdateNameOwnerAndBlock(); |
412 on_connected_callback, | |
413 interface_name, | |
414 signal_name, | |
415 success)); | |
416 } | |
417 | 406 |
418 void ObjectProxy::OnConnected(OnConnectedCallback on_connected_callback, | 407 return success; |
419 const std::string& interface_name, | |
420 const std::string& signal_name, | |
421 bool success) { | |
422 bus_->AssertOnOriginThread(); | |
423 | |
424 on_connected_callback.Run(interface_name, signal_name, success); | |
425 } | 408 } |
426 | 409 |
427 void ObjectProxy::SetNameOwnerChangedCallback(SignalCallback callback) { | 410 void ObjectProxy::SetNameOwnerChangedCallback(SignalCallback callback) { |
428 bus_->AssertOnOriginThread(); | 411 bus_->AssertOnOriginThread(); |
429 | 412 |
430 name_owner_changed_callback_ = callback; | 413 name_owner_changed_callback_ = callback; |
431 } | 414 } |
432 | 415 |
433 DBusHandlerResult ObjectProxy::HandleMessage( | 416 DBusHandlerResult ObjectProxy::HandleMessage( |
434 DBusConnection* connection, | 417 DBusConnection* connection, |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 } | 635 } |
653 } | 636 } |
654 } | 637 } |
655 | 638 |
656 // Always return unhandled to let other object proxies handle the same | 639 // Always return unhandled to let other object proxies handle the same |
657 // signal. | 640 // signal. |
658 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 641 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
659 } | 642 } |
660 | 643 |
661 } // namespace dbus | 644 } // namespace dbus |
OLD | NEW |