Skip to content

Commit

Permalink
Implement IBusClient
Browse files Browse the repository at this point in the history
IBusClient performs dbus communication with following spec.
Target Server: ibus-daemon
Service: org.freedesktop.IBus
ObjectPath: /org/freedesktop/IBus

At this moment, CreateInputContext is implementated with unittest.
According to this CL, IBusClient is compiled and tested by chromeos_unittests
but not actually in used production binary.

TEST=unit_tests,chromeos_unittests,dbus_unittests
BUG=chromium-os:26334


Review URL: https://chromiumcodereview.appspot.com/10342011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136652 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
nona@chromium.org committed May 11, 2012
1 parent 9a1c78f commit ce4f353
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 0 deletions.
6 changes: 6 additions & 0 deletions chromeos/chromeos.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
'dbus/flimflam_profile_client.h',
'dbus/flimflam_service_client.cc',
'dbus/flimflam_service_client.h',
'dbus/ibus/ibus_client.cc',
'dbus/ibus/ibus_client.h',
'dbus/ibus/ibus_constants.h',
'dbus/image_burner_client.cc',
'dbus/image_burner_client.h',
'dbus/introspectable_client.cc',
Expand All @@ -92,6 +95,8 @@
'chromeos',
],
'sources': [
'dbus/ibus/mock_ibus_client.cc',
'dbus/ibus/mock_ibus_client.h',
'dbus/mock_bluetooth_adapter_client.cc',
'dbus/mock_bluetooth_adapter_client.h',
'dbus/mock_bluetooth_device_client.cc',
Expand Down Expand Up @@ -166,6 +171,7 @@
'dbus/flimflam_profile_client_unittest.cc',
'dbus/flimflam_service_client_unittest.cc',
'dbus/gsm_sms_client_unittest.cc',
'dbus/ibus/ibus_client_unittest.cc',
],
'include_dirs': [
'..',
Expand Down
101 changes: 101 additions & 0 deletions chromeos/dbus/ibus/ibus_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/dbus/ibus/ibus_client.h"

#include "base/bind.h"
#include "base/callback.h"
#include "chromeos/dbus/ibus/ibus_constants.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"

namespace chromeos {

namespace {

// The IBusClient implementation.
class IBusClientImpl : public IBusClient {
public:
explicit IBusClientImpl(dbus::Bus* bus)
: proxy_(bus->GetObjectProxy(kIBusServiceName,
dbus::ObjectPath(kIBusServicePath))),
weak_ptr_factory_(this) {
}

virtual ~IBusClientImpl() {}

// IBusClient override.
virtual void CreateInputContext(
const std::string& client_name,
const CreateInputContextCallback& callback) OVERRIDE {
dbus::MethodCall method_call(kIBusServiceInterface,
kIBusBusCreateInputContextMethod);
dbus::MessageWriter writer(&method_call);
writer.AppendString(client_name);
proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&IBusClientImpl::OnCreateInputContext,
weak_ptr_factory_.GetWeakPtr(),
callback));
}

private:
// Handles responses of CreateInputContext method calls.
void OnCreateInputContext(const CreateInputContextCallback& callback,
dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Cannot get input context: " << response->ToString();
return;
}
dbus::MessageReader reader(response);
dbus::ObjectPath object_path;
if (!reader.PopObjectPath(&object_path)) {
// The IBus message structure may be changed.
LOG(ERROR) << "Invalid response: " << response->ToString();
return;
}
callback.Run(object_path);
}

dbus::ObjectProxy* proxy_;
base::WeakPtrFactory<IBusClientImpl> weak_ptr_factory_;

DISALLOW_COPY_AND_ASSIGN(IBusClientImpl);
};

// A stub implementation of IBusClient.
class IBusClientStubImpl : public IBusClient {
public:
IBusClientStubImpl() {}
virtual ~IBusClientStubImpl() {}

virtual void CreateInputContext(
const std::string& client_name,
const CreateInputContextCallback & callback) OVERRIDE {}

private:
DISALLOW_COPY_AND_ASSIGN(IBusClientStubImpl);
};

} // namespace

///////////////////////////////////////////////////////////////////////////////
// IBusClient

IBusClient::IBusClient() {}

IBusClient::~IBusClient() {}

// static
IBusClient* IBusClient::Create(DBusClientImplementationType type,
dbus::Bus* bus) {
if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) {
return new IBusClientImpl(bus);
}
DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
return new IBusClientStubImpl();
}

} // namespace chromeos
57 changes: 57 additions & 0 deletions chromeos/dbus/ibus/ibus_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_DBUS_IBUS_IBUS_CLIENT_H_
#define CHROMEOS_DBUS_IBUS_IBUS_CLIENT_H_
#pragma once

#include <string>

#include "base/basictypes.h"
#include "base/callback.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client_implementation_type.h"
#include "dbus/object_path.h"

namespace dbus {
class Bus;
} // namespace dbus

namespace chromeos {

class IBusInputContextClient;

// A class to make the actual DBus calls for IBusBus service.
// This class only makes calls, result/error handling should be done by
// callbacks.
class CHROMEOS_EXPORT IBusClient {
public:
typedef base::Callback<void(const dbus::ObjectPath&)>
CreateInputContextCallback;

virtual ~IBusClient();

// Requests the ibus-daemon to create new input context. If succeeded,
// |callback| will be called with an ObjectPath which is used in input context
// handling.
virtual void CreateInputContext(
const std::string& client_name,
const CreateInputContextCallback& callback) = 0;

// Factory function, creates a new instance and returns ownership.
// For normal usage, access the singleton via DBusThreadManager::Get().
static CHROMEOS_EXPORT IBusClient* Create(DBusClientImplementationType type,
dbus::Bus* bus);

protected:
// Create() should be used instead.
IBusClient();

private:
DISALLOW_COPY_AND_ASSIGN(IBusClient);
};

} // namespace chromeos

#endif // CHROMEOS_DBUS_IBUS_IBUS_CLIENT_H_
108 changes: 108 additions & 0 deletions chromeos/dbus/ibus/ibus_client_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/dbus/ibus/ibus_client.h"

#include "base/bind.h"
#include "base/message_loop.h"
#include "base/values.h"
#include "chromeos/dbus/ibus/ibus_constants.h"
#include "dbus/message.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h"
#include "dbus/values_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Invoke;
using testing::Return;
using testing::_;

namespace chromeos {

namespace {
const char kClientName[] = "chrome";
} // namespace

class MockCreateInputContextCallback {
public:
MOCK_METHOD1(Run, void(const dbus::ObjectPath& object_path));
};

class IBusClientTest : public testing::Test {
public:
IBusClientTest() : response_(NULL) {}

// Handles CreateInputContext method call.
void OnCreateInputContext(
dbus::MethodCall* method_call,
int timeout_ms,
const dbus::ObjectProxy::ResponseCallback& callback) {
dbus::MessageReader reader(method_call);
std::string client_name;
EXPECT_TRUE(reader.PopString(&client_name));
EXPECT_EQ(kClientName, client_name);
EXPECT_FALSE(reader.HasMoreData());

message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
}

protected:
virtual void SetUp() OVERRIDE {
dbus::Bus::Options options;
mock_bus_ = new dbus::MockBus(options);
mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(),
kIBusServiceName,
dbus::ObjectPath(kIBusServicePath));
EXPECT_CALL(*mock_bus_, GetObjectProxy(kIBusServiceName,
dbus::ObjectPath(kIBusServicePath)))
.WillOnce(Return(mock_proxy_.get()));

EXPECT_CALL(*mock_bus_, ShutdownAndBlock());
client_.reset(IBusClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION,
mock_bus_));
}

virtual void TearDown() OVERRIDE {
mock_bus_->ShutdownAndBlock();
}

// The IBus client to be tested.
scoped_ptr<IBusClient> client_;

// A message loop to emulate asynchronous behavior.
MessageLoop message_loop_;
scoped_refptr<dbus::MockBus> mock_bus_;
scoped_refptr<dbus::MockObjectProxy> mock_proxy_;

// Response returned by mock methods.
dbus::Response* response_;
};

TEST_F(IBusClientTest, CreateInputContextTest) {
// Set expectations
const dbus::ObjectPath kInputContextObjectPath =
dbus::ObjectPath("some.object.path");
EXPECT_CALL(*mock_proxy_, CallMethod(_, _, _))
.WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext));
MockCreateInputContextCallback callback;
EXPECT_CALL(callback, Run(kInputContextObjectPath));

// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
writer.AppendObjectPath(kInputContextObjectPath);
response_ = response.get();

// Call CreateInputContext
client_->CreateInputContext(kClientName,
base::Bind(&MockCreateInputContextCallback::Run,
base::Unretained(&callback)));

// Run the message loop.
message_loop_.RunAllPending();
}

} // namespace chromeos
18 changes: 18 additions & 0 deletions chromeos/dbus/ibus/ibus_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_DBUS_IBUS_IBUS_CONST_H_
#define CHROMEOS_DBUS_IBUS_IBUS_CONST_H_

namespace chromeos {

const char kIBusServiceName[] = "org.freedesktop.IBus";
const char kIBusServicePath[] = "/org/freedesktop/IBus";
const char kIBusServiceInterface[] = "org.freedesktop.IBus";

const char kIBusBusCreateInputContextMethod[] = "CreateInputContext";

} // namespace chromeos

#endif // CHROMEOS_DBUS_IBUS_IBUS_CONST_H_
13 changes: 13 additions & 0 deletions chromeos/dbus/ibus/mock_ibus_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/dbus/ibus/mock_ibus_client.h"

namespace chromeos {

MockIBusClient::MockIBusClient() {}

MockIBusClient::~MockIBusClient() {}

} // namespace chromeos
27 changes: 27 additions & 0 deletions chromeos/dbus/ibus/mock_ibus_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_DBUS_IBUS_MOCK_IBUS_CLIENT_H_
#define CHROMEOS_DBUS_IBUS_MOCK_IBUS_CLIENT_H_
#pragma once

#include <string>
#include "chromeos/dbus/ibus/ibus_client.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace chromeos {

class MockIBusClient : public IBusClient {
public:
MockIBusClient();
virtual ~MockIBusClient();

MOCK_METHOD2(CreateInputContext,
void(const std::string& client_name,
const CreateInputContextCallback& callback));
};

} // namespace chromeos

#endif // CHROMEOS_DBUS_IBUS_MOCK_IBUS_CLIENT_H_

0 comments on commit ce4f353

Please sign in to comment.