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.h" | 9 #include "base/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
15 #include "dbus/dbus_statistics.h" | 15 #include "dbus/dbus_statistics.h" |
16 #include "dbus/message.h" | 16 #include "dbus/message.h" |
17 #include "dbus/object_path.h" | 17 #include "dbus/object_path.h" |
18 #include "dbus/object_proxy.h" | 18 #include "dbus/object_proxy.h" |
19 #include "dbus/scoped_dbus_error.h" | 19 #include "dbus/scoped_dbus_error.h" |
20 | 20 |
21 namespace dbus { | |
22 | |
21 namespace { | 23 namespace { |
22 | 24 |
23 const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown"; | 25 const char kErrorServiceUnknown[] = "org.freedesktop.DBus.Error.ServiceUnknown"; |
24 | 26 |
25 // Used for success ratio histograms. 1 for success, 0 for failure. | 27 // Used for success ratio histograms. 1 for success, 0 for failure. |
26 const int kSuccessRatioHistogramMaxValue = 2; | 28 const int kSuccessRatioHistogramMaxValue = 2; |
27 | 29 |
28 // The path of D-Bus Object sending NameOwnerChanged signal. | 30 // The path of D-Bus Object sending NameOwnerChanged signal. |
29 const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus"; | 31 const char kDBusSystemObjectPath[] = "/org/freedesktop/DBus"; |
30 | 32 |
33 // The D-Bus Object interface. | |
34 const char kDBusSystemObjectInterface[] = "org.freedesktop.DBus"; | |
35 | |
36 // The D-Bus Object address. | |
37 const char kDBusSystemObjectAddress[] = "org.freedesktop.DBus"; | |
38 | |
39 // The NameOwnerChanged member in |kDBusSystemObjectInterface|. | |
40 const char kNameOwnerChangedMember[] = "NameOwnerChanged"; | |
41 | |
31 // Gets the absolute signal name by concatenating the interface name and | 42 // Gets the absolute signal name by concatenating the interface name and |
32 // the signal name. Used for building keys for method_table_ in | 43 // the signal name. Used for building keys for method_table_ in |
33 // ObjectProxy. | 44 // ObjectProxy. |
34 std::string GetAbsoluteSignalName( | 45 std::string GetAbsoluteSignalName( |
35 const std::string& interface_name, | 46 const std::string& interface_name, |
36 const std::string& signal_name) { | 47 const std::string& signal_name) { |
37 return interface_name + "." + signal_name; | 48 return interface_name + "." + signal_name; |
38 } | 49 } |
39 | 50 |
40 // An empty function used for ObjectProxy::EmptyResponseCallback(). | 51 // An empty function used for ObjectProxy::EmptyResponseCallback(). |
41 void EmptyResponseCallbackBody(dbus::Response* unused_response) { | 52 void EmptyResponseCallbackBody(Response* unused_response) { |
53 } | |
54 | |
55 // Gets the owner for |service_name| on |bus|. On success, returns true and | |
56 // write the owner name to |service_name_owner|. | |
57 // Set |suppress_errors| to true to avoid printing error messages. | |
58 bool GetServiceOwner(Bus* bus, | |
59 const std::string& service_name, | |
60 bool suppress_errors, | |
61 std::string* service_name_owner) { | |
62 bus->AssertOnDBusThread(); | |
63 | |
64 MethodCall get_name_owner_call(kDBusSystemObjectInterface, "GetNameOwner"); | |
65 MessageWriter writer(&get_name_owner_call); | |
66 writer.AppendString(service_name); | |
67 VLOG(1) << "Method call: " << get_name_owner_call.ToString(); | |
68 | |
69 const ObjectPath obj_path(kDBusSystemObjectPath); | |
70 if (!get_name_owner_call.SetDestination(kDBusSystemObjectAddress) || | |
71 !get_name_owner_call.SetPath(obj_path)) { | |
72 if (!suppress_errors) | |
73 LOG(ERROR) << "Failed to get name owner."; | |
74 return false; | |
75 } | |
76 | |
77 ScopedDBusError error; | |
78 DBusMessage* response_message = bus->SendWithReplyAndBlock( | |
79 get_name_owner_call.raw_message(), | |
80 ObjectProxy::TIMEOUT_USE_DEFAULT, | |
81 error.get()); | |
82 if (!response_message) { | |
83 if (!suppress_errors) { | |
84 LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " | |
85 << error.message(); | |
86 } | |
87 return false; | |
88 } | |
89 | |
90 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); | |
91 MessageReader reader(response.get()); | |
92 | |
93 if (!reader.PopString(service_name_owner)) | |
94 service_name_owner->clear(); | |
95 return true; | |
42 } | 96 } |
43 | 97 |
44 } // namespace | 98 } // namespace |
45 | 99 |
46 namespace dbus { | |
47 | |
48 ObjectProxy::ObjectProxy(Bus* bus, | 100 ObjectProxy::ObjectProxy(Bus* bus, |
49 const std::string& service_name, | 101 const std::string& service_name, |
50 const ObjectPath& object_path, | 102 const ObjectPath& object_path, |
51 int options) | 103 int options) |
52 : bus_(bus), | 104 : bus_(bus), |
53 service_name_(service_name), | 105 service_name_(service_name), |
54 object_path_(object_path), | 106 object_path_(object_path), |
55 filter_added_(false), | 107 filter_added_(false), |
56 ignore_service_unknown_errors_( | 108 ignore_service_unknown_errors_( |
57 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { | 109 options & IGNORE_SERVICE_UNKNOWN_ERRORS) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 bus_->RemoveMatch(*iter, error.get()); | 238 bus_->RemoveMatch(*iter, error.get()); |
187 if (error.is_set()) { | 239 if (error.is_set()) { |
188 // There is nothing we can do to recover, so just print the error. | 240 // There is nothing we can do to recover, so just print the error. |
189 LOG(ERROR) << "Failed to remove match rule: " << *iter; | 241 LOG(ERROR) << "Failed to remove match rule: " << *iter; |
190 } | 242 } |
191 } | 243 } |
192 match_rules_.clear(); | 244 match_rules_.clear(); |
193 } | 245 } |
194 | 246 |
195 // static | 247 // static |
248 bool ObjectProxy::ServiceHasOwner(dbus::Bus* bus, | |
249 const std::string& service_name) { | |
satorux1
2013/04/30 01:53:10
thread checking is missing. bus_->AssertOnDBusThre
| |
250 if (!bus->Connect()) | |
251 return false; | |
252 | |
253 std::string service_name_owner; | |
254 if (!GetServiceOwner(bus, service_name, true, &service_name_owner)) | |
255 return false; | |
256 return !service_name_owner.empty(); | |
257 } | |
258 | |
259 // static | |
196 ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() { | 260 ObjectProxy::ResponseCallback ObjectProxy::EmptyResponseCallback() { |
197 return base::Bind(&EmptyResponseCallbackBody); | 261 return base::Bind(&EmptyResponseCallbackBody); |
198 } | 262 } |
199 | 263 |
200 ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData( | 264 ObjectProxy::OnPendingCallIsCompleteData::OnPendingCallIsCompleteData( |
201 ObjectProxy* in_object_proxy, | 265 ObjectProxy* in_object_proxy, |
202 ResponseCallback in_response_callback, | 266 ResponseCallback in_response_callback, |
203 ErrorCallback in_error_callback, | 267 ErrorCallback in_error_callback, |
204 base::TimeTicks in_start_time) | 268 base::TimeTicks in_start_time) |
205 : object_proxy(in_object_proxy), | 269 : object_proxy(in_object_proxy), |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 DBusMessage* response_message) { | 342 DBusMessage* response_message) { |
279 bus_->AssertOnOriginThread(); | 343 bus_->AssertOnOriginThread(); |
280 | 344 |
281 bool method_call_successful = false; | 345 bool method_call_successful = false; |
282 if (!response_message) { | 346 if (!response_message) { |
283 // The response is not received. | 347 // The response is not received. |
284 error_callback.Run(NULL); | 348 error_callback.Run(NULL); |
285 } else if (dbus_message_get_type(response_message) == | 349 } else if (dbus_message_get_type(response_message) == |
286 DBUS_MESSAGE_TYPE_ERROR) { | 350 DBUS_MESSAGE_TYPE_ERROR) { |
287 // This will take |response_message| and release (unref) it. | 351 // This will take |response_message| and release (unref) it. |
288 scoped_ptr<dbus::ErrorResponse> error_response( | 352 scoped_ptr<ErrorResponse> error_response( |
289 dbus::ErrorResponse::FromRawMessage(response_message)); | 353 ErrorResponse::FromRawMessage(response_message)); |
290 error_callback.Run(error_response.get()); | 354 error_callback.Run(error_response.get()); |
291 // Delete the message on the D-Bus thread. See below for why. | 355 // Delete the message on the D-Bus thread. See below for why. |
292 bus_->PostTaskToDBusThread( | 356 bus_->PostTaskToDBusThread( |
293 FROM_HERE, | 357 FROM_HERE, |
294 base::Bind(&base::DeletePointer<dbus::ErrorResponse>, | 358 base::Bind(&base::DeletePointer<ErrorResponse>, |
295 error_response.release())); | 359 error_response.release())); |
296 } else { | 360 } else { |
297 // This will take |response_message| and release (unref) it. | 361 // This will take |response_message| and release (unref) it. |
298 scoped_ptr<dbus::Response> response( | 362 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); |
299 dbus::Response::FromRawMessage(response_message)); | |
300 // The response is successfully received. | 363 // The response is successfully received. |
301 response_callback.Run(response.get()); | 364 response_callback.Run(response.get()); |
302 // The message should be deleted on the D-Bus thread for a complicated | 365 // The message should be deleted on the D-Bus thread for a complicated |
303 // reason: | 366 // reason: |
304 // | 367 // |
305 // libdbus keeps track of the number of bytes in the incoming message | 368 // libdbus keeps track of the number of bytes in the incoming message |
306 // queue to ensure that the data size in the queue is manageable. The | 369 // queue to ensure that the data size in the queue is manageable. The |
307 // bookkeeping is partly done via dbus_message_unref(), and immediately | 370 // bookkeeping is partly done via dbus_message_unref(), and immediately |
308 // asks the client code (Chrome) to stop monitoring the underlying | 371 // asks the client code (Chrome) to stop monitoring the underlying |
309 // socket, if the number of bytes exceeds a certian number, which is set | 372 // socket, if the number of bytes exceeds a certian number, which is set |
310 // to 63MB, per dbus-transport.cc: | 373 // to 63MB, per dbus-transport.cc: |
311 // | 374 // |
312 // /* Try to default to something that won't totally hose the system, | 375 // /* Try to default to something that won't totally hose the system, |
313 // * but doesn't impose too much of a limitation. | 376 // * but doesn't impose too much of a limitation. |
314 // */ | 377 // */ |
315 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; | 378 // transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; |
316 // | 379 // |
317 // The monitoring of the socket is done on the D-Bus thread (see Watch | 380 // The monitoring of the socket is done on the D-Bus thread (see Watch |
318 // class in bus.cc), hence we should stop the monitoring from D-Bus | 381 // class in bus.cc), hence we should stop the monitoring from D-Bus |
319 // thread, not from the current thread here, which is likely UI thread. | 382 // thread, not from the current thread here, which is likely UI thread. |
320 bus_->PostTaskToDBusThread( | 383 bus_->PostTaskToDBusThread( |
321 FROM_HERE, | 384 FROM_HERE, |
322 base::Bind(&base::DeletePointer<dbus::Response>, | 385 base::Bind(&base::DeletePointer<Response>, response.release())); |
323 response.release())); | |
324 | 386 |
325 method_call_successful = true; | 387 method_call_successful = true; |
326 // Record time spent for the method call. Don't include failures. | 388 // Record time spent for the method call. Don't include failures. |
327 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", | 389 UMA_HISTOGRAM_TIMES("DBus.AsyncMethodCallTime", |
328 base::TimeTicks::Now() - start_time); | 390 base::TimeTicks::Now() - start_time); |
329 } | 391 } |
330 // Record if the method call is successful, or not. 1 if successful. | 392 // Record if the method call is successful, or not. 1 if successful. |
331 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", | 393 UMA_HISTOGRAM_ENUMERATION("DBus.AsyncMethodCallSuccess", |
332 method_call_successful, | 394 method_call_successful, |
333 kSuccessRatioHistogramMaxValue); | 395 kSuccessRatioHistogramMaxValue); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
432 | 494 |
433 // raw_message will be unrefed on exit of the function. Increment the | 495 // raw_message will be unrefed on exit of the function. Increment the |
434 // reference so we can use it in Signal. | 496 // reference so we can use it in Signal. |
435 dbus_message_ref(raw_message); | 497 dbus_message_ref(raw_message); |
436 scoped_ptr<Signal> signal( | 498 scoped_ptr<Signal> signal( |
437 Signal::FromRawMessage(raw_message)); | 499 Signal::FromRawMessage(raw_message)); |
438 | 500 |
439 // Verify the signal comes from the object we're proxying for, this is | 501 // Verify the signal comes from the object we're proxying for, this is |
440 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and | 502 // our last chance to return DBUS_HANDLER_RESULT_NOT_YET_HANDLED and |
441 // allow other object proxies to handle instead. | 503 // allow other object proxies to handle instead. |
442 const dbus::ObjectPath path = signal->GetPath(); | 504 const ObjectPath path = signal->GetPath(); |
443 if (path != object_path_) { | 505 if (path != object_path_) { |
444 if (path.value() == kDBusSystemObjectPath && | 506 if (path.value() == kDBusSystemObjectPath && |
445 signal->GetMember() == "NameOwnerChanged") { | 507 signal->GetMember() == kNameOwnerChangedMember) { |
446 // Handle NameOwnerChanged separately | 508 // Handle NameOwnerChanged separately |
447 return HandleNameOwnerChanged(signal.Pass()); | 509 return HandleNameOwnerChanged(signal.Pass()); |
448 } | 510 } |
449 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 511 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
450 } | 512 } |
451 | 513 |
452 const std::string interface = signal->GetInterface(); | 514 const std::string interface = signal->GetInterface(); |
453 const std::string member = signal->GetMember(); | 515 const std::string member = signal->GetMember(); |
454 | 516 |
455 statistics::AddReceivedSignal(service_name_, interface, member); | 517 statistics::AddReceivedSignal(service_name_, interface, member); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 bus_->AssertOnOriginThread(); | 562 bus_->AssertOnOriginThread(); |
501 | 563 |
502 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); | 564 for (std::vector<SignalCallback>::iterator iter = signal_callbacks.begin(); |
503 iter != signal_callbacks.end(); ++iter) | 565 iter != signal_callbacks.end(); ++iter) |
504 iter->Run(signal); | 566 iter->Run(signal); |
505 | 567 |
506 // Delete the message on the D-Bus thread. See comments in | 568 // Delete the message on the D-Bus thread. See comments in |
507 // RunResponseCallback(). | 569 // RunResponseCallback(). |
508 bus_->PostTaskToDBusThread( | 570 bus_->PostTaskToDBusThread( |
509 FROM_HERE, | 571 FROM_HERE, |
510 base::Bind(&base::DeletePointer<dbus::Signal>, signal)); | 572 base::Bind(&base::DeletePointer<Signal>, signal)); |
511 | 573 |
512 // Record time spent for handling the signal. | 574 // Record time spent for handling the signal. |
513 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", | 575 UMA_HISTOGRAM_TIMES("DBus.SignalHandleTime", |
514 base::TimeTicks::Now() - start_time); | 576 base::TimeTicks::Now() - start_time); |
515 } | 577 } |
516 | 578 |
517 DBusHandlerResult ObjectProxy::HandleMessageThunk( | 579 DBusHandlerResult ObjectProxy::HandleMessageThunk( |
518 DBusConnection* connection, | 580 DBusConnection* connection, |
519 DBusMessage* raw_message, | 581 DBusMessage* raw_message, |
520 void* user_data) { | 582 void* user_data) { |
(...skipping 13 matching lines...) Expand all Loading... | |
534 << ": object_path= " << object_path_.value() | 596 << ": object_path= " << object_path_.value() |
535 << ": " << error_name << ": " << error_message; | 597 << ": " << error_name << ": " << error_message; |
536 } | 598 } |
537 | 599 |
538 void ObjectProxy::OnCallMethodError(const std::string& interface_name, | 600 void ObjectProxy::OnCallMethodError(const std::string& interface_name, |
539 const std::string& method_name, | 601 const std::string& method_name, |
540 ResponseCallback response_callback, | 602 ResponseCallback response_callback, |
541 ErrorResponse* error_response) { | 603 ErrorResponse* error_response) { |
542 if (error_response) { | 604 if (error_response) { |
543 // Error message may contain the error message as string. | 605 // Error message may contain the error message as string. |
544 dbus::MessageReader reader(error_response); | 606 MessageReader reader(error_response); |
545 std::string error_message; | 607 std::string error_message; |
546 reader.PopString(&error_message); | 608 reader.PopString(&error_message); |
547 LogMethodCallFailure(interface_name, | 609 LogMethodCallFailure(interface_name, |
548 method_name, | 610 method_name, |
549 error_response->GetErrorName(), | 611 error_response->GetErrorName(), |
550 error_message); | 612 error_message); |
551 } | 613 } |
552 response_callback.Run(NULL); | 614 response_callback.Run(NULL); |
553 } | 615 } |
554 | 616 |
555 bool ObjectProxy::AddMatchRuleWithCallback( | 617 bool ObjectProxy::AddMatchRuleWithCallback( |
556 const std::string& match_rule, | 618 const std::string& match_rule, |
557 const std::string& absolute_signal_name, | 619 const std::string& absolute_signal_name, |
558 SignalCallback signal_callback) { | 620 SignalCallback signal_callback) { |
559 DCHECK(!match_rule.empty()); | 621 DCHECK(!match_rule.empty()); |
560 DCHECK(!absolute_signal_name.empty()); | 622 DCHECK(!absolute_signal_name.empty()); |
561 bus_->AssertOnDBusThread(); | 623 bus_->AssertOnDBusThread(); |
562 | 624 |
563 if (match_rules_.find(match_rule) == match_rules_.end()) { | 625 if (match_rules_.find(match_rule) == match_rules_.end()) { |
564 ScopedDBusError error; | 626 ScopedDBusError error; |
565 bus_->AddMatch(match_rule, error.get()); | 627 bus_->AddMatch(match_rule, error.get()); |
566 if (error.is_set()) { | 628 if (error.is_set()) { |
567 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 629 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
568 error.name() << ": " << error.message(); | 630 << error.name() << ": " << error.message(); |
569 return false; | 631 return false; |
570 } else { | 632 } else { |
571 // Store the match rule, so that we can remove this in Detach(). | 633 // Store the match rule, so that we can remove this in Detach(). |
572 match_rules_.insert(match_rule); | 634 match_rules_.insert(match_rule); |
573 // Add the signal callback to the method table. | 635 // Add the signal callback to the method table. |
574 method_table_[absolute_signal_name].push_back(signal_callback); | 636 method_table_[absolute_signal_name].push_back(signal_callback); |
575 return true; | 637 return true; |
576 } | 638 } |
577 } else { | 639 } else { |
578 // We already have the match rule. | 640 // We already have the match rule. |
579 method_table_[absolute_signal_name].push_back(signal_callback); | 641 method_table_[absolute_signal_name].push_back(signal_callback); |
580 return true; | 642 return true; |
581 } | 643 } |
582 } | 644 } |
583 | 645 |
584 bool ObjectProxy::AddMatchRuleWithoutCallback( | 646 bool ObjectProxy::AddMatchRuleWithoutCallback( |
585 const std::string& match_rule, | 647 const std::string& match_rule, |
586 const std::string& absolute_signal_name) { | 648 const std::string& absolute_signal_name) { |
587 DCHECK(!match_rule.empty()); | 649 DCHECK(!match_rule.empty()); |
588 DCHECK(!absolute_signal_name.empty()); | 650 DCHECK(!absolute_signal_name.empty()); |
589 bus_->AssertOnDBusThread(); | 651 bus_->AssertOnDBusThread(); |
590 | 652 |
591 if (match_rules_.find(match_rule) != match_rules_.end()) | 653 if (match_rules_.find(match_rule) != match_rules_.end()) |
592 return true; | 654 return true; |
593 | 655 |
594 ScopedDBusError error; | 656 ScopedDBusError error; |
595 bus_->AddMatch(match_rule, error.get()); | 657 bus_->AddMatch(match_rule, error.get()); |
596 if (error.is_set()) { | 658 if (error.is_set()) { |
597 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " << | 659 LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got " |
598 error.name() << ": " << error.message(); | 660 << error.name() << ": " << error.message(); |
599 return false; | 661 return false; |
600 } | 662 } |
601 // Store the match rule, so that we can remove this in Detach(). | 663 // Store the match rule, so that we can remove this in Detach(). |
602 match_rules_.insert(match_rule); | 664 match_rules_.insert(match_rule); |
603 return true; | 665 return true; |
604 } | 666 } |
605 | 667 |
606 void ObjectProxy::UpdateNameOwnerAndBlock() { | 668 void ObjectProxy::UpdateNameOwnerAndBlock() { |
607 bus_->AssertOnDBusThread(); | 669 GetServiceOwner(bus_, service_name_, false, &service_name_owner_); |
608 | |
609 MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner"); | |
610 MessageWriter writer(&get_name_owner_call); | |
611 writer.AppendString(service_name_); | |
612 VLOG(1) << "Method call: " << get_name_owner_call.ToString(); | |
613 | |
614 const dbus::ObjectPath obj_path("/org/freedesktop/DBus"); | |
615 ScopedDBusError error; | |
616 if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") || | |
617 !get_name_owner_call.SetPath(obj_path)) { | |
618 LOG(ERROR) << "Failed to get name owner."; | |
619 return; | |
620 } | |
621 | |
622 DBusMessage* response_message = bus_->SendWithReplyAndBlock( | |
623 get_name_owner_call.raw_message(), | |
624 TIMEOUT_USE_DEFAULT, | |
625 error.get()); | |
626 if (!response_message) { | |
627 LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " << | |
628 error.message(); | |
629 return; | |
630 } | |
631 scoped_ptr<Response> response(Response::FromRawMessage(response_message)); | |
632 MessageReader reader(response.get()); | |
633 | |
634 std::string new_service_name_owner; | |
635 if (reader.PopString(&new_service_name_owner)) | |
636 service_name_owner_ = new_service_name_owner; | |
637 else | |
638 service_name_owner_.clear(); | |
639 } | 670 } |
640 | 671 |
641 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( | 672 DBusHandlerResult ObjectProxy::HandleNameOwnerChanged( |
642 scoped_ptr<Signal> signal) { | 673 scoped_ptr<Signal> signal) { |
643 DCHECK(signal); | 674 DCHECK(signal); |
644 bus_->AssertOnDBusThread(); | 675 bus_->AssertOnDBusThread(); |
645 | 676 |
646 // Confirm the validity of the NameOwnerChanged signal. | 677 // Confirm the validity of the NameOwnerChanged signal. |
647 if (signal->GetMember() == "NameOwnerChanged" && | 678 if (signal->GetMember() == kNameOwnerChangedMember && |
648 signal->GetInterface() == "org.freedesktop.DBus" && | 679 signal->GetInterface() == kDBusSystemObjectInterface && |
649 signal->GetSender() == "org.freedesktop.DBus") { | 680 signal->GetSender() == kDBusSystemObjectAddress) { |
650 MessageReader reader(signal.get()); | 681 MessageReader reader(signal.get()); |
651 std::string name, old_owner, new_owner; | 682 std::string name, old_owner, new_owner; |
652 if (reader.PopString(&name) && | 683 if (reader.PopString(&name) && |
653 reader.PopString(&old_owner) && | 684 reader.PopString(&old_owner) && |
654 reader.PopString(&new_owner) && | 685 reader.PopString(&new_owner) && |
655 name == service_name_) { | 686 name == service_name_) { |
656 service_name_owner_ = new_owner; | 687 service_name_owner_ = new_owner; |
657 if (!name_owner_changed_callback_.is_null()) { | 688 if (!name_owner_changed_callback_.is_null()) { |
658 const base::TimeTicks start_time = base::TimeTicks::Now(); | 689 const base::TimeTicks start_time = base::TimeTicks::Now(); |
659 Signal* released_signal = signal.release(); | 690 Signal* released_signal = signal.release(); |
660 std::vector<SignalCallback> callbacks; | 691 std::vector<SignalCallback> callbacks; |
661 callbacks.push_back(name_owner_changed_callback_); | 692 callbacks.push_back(name_owner_changed_callback_); |
662 bus_->PostTaskToOriginThread(FROM_HERE, | 693 bus_->PostTaskToOriginThread(FROM_HERE, |
663 base::Bind(&ObjectProxy::RunMethod, | 694 base::Bind(&ObjectProxy::RunMethod, |
664 this, | 695 this, |
665 start_time, | 696 start_time, |
666 callbacks, | 697 callbacks, |
667 released_signal)); | 698 released_signal)); |
668 } | 699 } |
669 } | 700 } |
670 } | 701 } |
671 | 702 |
672 // Always return unhandled to let other object proxies handle the same | 703 // Always return unhandled to let other object proxies handle the same |
673 // signal. | 704 // signal. |
674 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 705 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
675 } | 706 } |
676 | 707 |
677 } // namespace dbus | 708 } // namespace dbus |
OLD | NEW |