Index: chromeos/dbus/ibus/ibus_config_client.cc |
diff --git a/chromeos/dbus/ibus/ibus_config_client.cc b/chromeos/dbus/ibus/ibus_config_client.cc |
index 659cde41bae779420cb748a81ec0c4286f16c0e9..7844e785d4415a8c321da1365d906e7d0a6e235a 100644 |
--- a/chromeos/dbus/ibus/ibus_config_client.cc |
+++ b/chromeos/dbus/ibus/ibus_config_client.cc |
@@ -4,6 +4,8 @@ |
#include "chromeos/dbus/ibus/ibus_config_client.h" |
+#include <vector> |
+ |
#include "base/bind.h" |
#include "base/callback.h" |
#include "chromeos/dbus/ibus/ibus_constants.h" |
@@ -21,19 +23,46 @@ namespace { |
class IBusConfigClientImpl : public IBusConfigClient { |
public: |
explicit IBusConfigClientImpl(dbus::Bus* bus) |
- : proxy_(bus->GetObjectProxy(ibus::kServiceName, |
- dbus::ObjectPath( |
- ibus::config::kServicePath))), |
+ : proxy_(NULL), |
+ bus_(bus), |
weak_ptr_factory_(this) { |
} |
virtual ~IBusConfigClientImpl() {} |
// IBusConfigClient override. |
+ virtual void AsyncInitialize(const OnIBusConfigReady& on_ready) OVERRIDE { |
+ // We should check that the ibus-config daemon actually works first, so we |
+ // can't initialize synchronously. |
+ dbus::ObjectProxy* dbus_proxy = bus_->GetObjectProxy( |
+ ibus::kServiceName, |
+ dbus::ObjectPath(ibus::kDBusObjectPath)); |
+ dbus::MethodCall method_call(ibus::kDBusInterface, |
+ ibus::kGetNameOwnerMethod); |
+ dbus::MessageWriter writer(&method_call); |
+ writer.AppendString(ibus::config::kServiceName); |
+ dbus_proxy->CallMethod( |
+ &method_call, |
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&IBusConfigClientImpl::OnGetNameOwner, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ on_ready)); |
+ |
+ // Also watch NameOwnerChanged signal which is fired when the ibus-config |
+ // daemon request its name ownership. |
+ dbus_proxy->SetNameOwnerChangedCallback( |
+ base::Bind(&IBusConfigClientImpl::OnNameOwnerChanged, |
+ weak_ptr_factory_.GetWeakPtr(), |
+ on_ready)); |
+ } |
+ |
+ // IBusConfigClient override. |
virtual void SetStringValue(const std::string& section, |
const std::string& key, |
const std::string& value, |
const ErrorCallback& error_callback) OVERRIDE { |
+ if (!proxy_) |
+ return; |
DCHECK(!error_callback.is_null()); |
dbus::MethodCall method_call(ibus::config::kServiceInterface, |
ibus::config::kSetValueMethod); |
@@ -52,6 +81,8 @@ class IBusConfigClientImpl : public IBusConfigClient { |
const std::string& key, |
int value, |
const ErrorCallback& error_callback) OVERRIDE { |
+ if (!proxy_) |
+ return; |
DCHECK(!error_callback.is_null()); |
dbus::MethodCall method_call(ibus::config::kServiceInterface, |
ibus::config::kSetValueMethod); |
@@ -70,6 +101,8 @@ class IBusConfigClientImpl : public IBusConfigClient { |
const std::string& key, |
bool value, |
const ErrorCallback& error_callback) OVERRIDE { |
+ if (!proxy_) |
+ return; |
DCHECK(!error_callback.is_null()); |
dbus::MethodCall method_call(ibus::config::kServiceInterface, |
ibus::config::kSetValueMethod); |
@@ -89,6 +122,8 @@ class IBusConfigClientImpl : public IBusConfigClient { |
const std::string& key, |
const std::vector<std::string>& value, |
const ErrorCallback& error_callback) OVERRIDE { |
+ if (!proxy_) |
+ return; |
DCHECK(!error_callback.is_null()); |
dbus::MethodCall method_call(ibus::config::kServiceInterface, |
ibus::config::kSetValueMethod); |
@@ -111,6 +146,8 @@ class IBusConfigClientImpl : public IBusConfigClient { |
private: |
void CallWithDefaultCallback(dbus::MethodCall* method_call, |
const ErrorCallback& error_callback) { |
+ if (!proxy_) |
+ return; |
proxy_->CallMethodWithErrorCallback( |
method_call, |
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
@@ -136,7 +173,70 @@ class IBusConfigClientImpl : public IBusConfigClient { |
error_callback.Run(); |
} |
+ void OnNameOwnerChanged(const OnIBusConfigReady& on_ready, |
+ dbus::Signal* signal) { |
+ DCHECK(signal); |
+ std::string name; |
+ std::string old_owner; |
+ std::string new_owner; |
+ |
+ dbus::MessageReader reader(signal); |
+ if (!reader.PopString(&name) || |
+ !reader.PopString(&old_owner) || |
+ !reader.PopString(&new_owner)) { |
+ DLOG(ERROR) << "Invalid response of NameOwnerChanged."; |
satorux1
2012/11/28 06:43:12
Include signal->ToString() ?
Seigo Nonaka
2012/11/28 07:00:37
Done.
|
+ return; |
+ } |
+ |
+ if (name != ibus::config::kServiceName) |
+ return; // Not a signal for ibus-config. |
+ |
+ if (!old_owner.empty() || new_owner.empty()) { |
+ DVLOG(1) << "Unexpected name owner change: name=" << name |
+ << ", old_owner=" << old_owner << ", new_owner=" << new_owner; |
+ proxy_ = NULL; |
+ return; |
+ } |
+ |
+ if (proxy_) |
+ return; // Already initialized. |
+ |
+ proxy_ = bus_->GetObjectProxy(ibus::kServiceName, |
+ dbus::ObjectPath( |
+ ibus::config::kServicePath)); |
+ if (!on_ready.is_null()) |
+ on_ready.Run(); |
+ } |
+ |
+ // Handles response of GetNameOwner. |
+ void OnGetNameOwner(const OnIBusConfigReady& on_ready, |
+ dbus::Response* response) { |
+ if (!response) { |
+ DLOG(ERROR) << "Response is NULL."; |
+ return; |
+ } |
+ std::string owner; |
+ dbus::MessageReader reader(response); |
+ |
+ if (!reader.PopString(&owner)) { |
+ DLOG(ERROR) << "Invalid response of GetNameOwner."; |
satorux1
2012/11/28 06:43:12
Include response->ToString() ?
Seigo Nonaka
2012/11/28 07:00:37
Done.
|
+ return; |
+ } |
+ |
+ // If the owner is empty, ibus-config daemon is not ready. So will |
+ // initialize object proxy on NameOwnerChanged signal. |
+ if (owner.empty()) |
+ return; |
+ |
+ proxy_ = bus_->GetObjectProxy(ibus::kServiceName, |
+ dbus::ObjectPath( |
+ ibus::config::kServicePath)); |
+ if (!on_ready.is_null()) |
+ on_ready.Run(); |
+ } |
+ |
dbus::ObjectProxy* proxy_; |
+ dbus::Bus* bus_; |
base::WeakPtrFactory<IBusConfigClientImpl> weak_ptr_factory_; |
DISALLOW_COPY_AND_ASSIGN(IBusConfigClientImpl); |
@@ -147,6 +247,7 @@ class IBusConfigClientStubImpl : public IBusConfigClient { |
public: |
IBusConfigClientStubImpl() {} |
virtual ~IBusConfigClientStubImpl() {} |
+ virtual void AsyncInitialize(const OnIBusConfigReady& on_ready) OVERRIDE {} |
virtual void SetStringValue(const std::string& section, |
const std::string& key, |
const std::string& value, |