Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Unified Diff: chromeos/dbus/ibus/ibus_config_client.cc

Issue 11413165: Makes IBusConfigClient initialize asynchronous. (Closed) Base URL: http://git.chromium.org/chromium/src.git@base
Patch Set: Fix test miss expectation Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromeos/dbus/ibus/ibus_config_client.h ('k') | chromeos/dbus/ibus/ibus_config_client_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..8be2e09e388110c668c5fb8a615a87d68d5d4d2c 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"
@@ -17,23 +19,69 @@ namespace chromeos {
namespace {
+// Called when the |signal| is connected.
+void OnSignalConnected(const std::string& interface,
+ const std::string& signal,
+ bool succeeded) {
+ LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " "
+ << signal << " failed.";
+}
+
+// Called when the GetNameOwner method call is failed.
+void OnGetNameOwnerFail(dbus::ErrorResponse* response) {
+ // Do nothing, because method call sometimes fails due to bootstrap timing of
+ // ibus-memconf.
+}
+
// The IBusConfigClient implementation.
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 InitializeAsync(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));
+
+ // Watch NameOwnerChanged signal which is fired when the ibus-config daemon
+ // request its name ownership.
+ dbus_proxy->ConnectToSignal(
+ ibus::kDBusInterface,
+ ibus::kNameOwnerChangedSignal,
+ base::Bind(&IBusConfigClientImpl::OnNameOwnerChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ on_ready),
+ base::Bind(&OnSignalConnected));
+
+ dbus::MethodCall method_call(ibus::kDBusInterface,
+ ibus::kGetNameOwnerMethod);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString(ibus::config::kServiceName);
+ dbus_proxy->CallMethodWithErrorCallback(
+ &method_call,
+ dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&IBusConfigClientImpl::OnGetNameOwner,
+ weak_ptr_factory_.GetWeakPtr(),
+ on_ready),
+ base::Bind(&OnGetNameOwnerFail));
+ }
+
+ // 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 +100,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 +120,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 +141,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 +165,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 +192,72 @@ 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."
+ << signal->ToString();
+ 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::config::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) {
+ LOG(ERROR) << "Response is NULL.";
+ return;
+ }
+ std::string owner;
+ dbus::MessageReader reader(response);
+
+ if (!reader.PopString(&owner)) {
+ LOG(ERROR) << "Invalid response of GetNameOwner."
+ << response->ToString();
+ 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::config::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 +268,7 @@ class IBusConfigClientStubImpl : public IBusConfigClient {
public:
IBusConfigClientStubImpl() {}
virtual ~IBusConfigClientStubImpl() {}
+ virtual void InitializeAsync(const OnIBusConfigReady& on_ready) OVERRIDE {}
virtual void SetStringValue(const std::string& section,
const std::string& key,
const std::string& value,
« no previous file with comments | « chromeos/dbus/ibus/ibus_config_client.h ('k') | chromeos/dbus/ibus/ibus_config_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698