Commit e834abd8 authored by Leo Zhang's avatar Leo Zhang Committed by Commit Bot

More Impl and fix testing for IME service.

Add more logic and make the service testing really works.

Tested locally by enabling build flags (enable_cros_ime_service and
enable_cros_ime_decoder), then pass the testings
chromeos/services:chromeos_services_unittests

Bug: 837156
Change-Id: I05f557f808c210e788630ce4749b5c261ed19b44
Reviewed-on: https://chromium-review.googlesource.com/1146537
Commit-Queue: Leo Zhang <googleo@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577386}
parent 414c5c87
...@@ -45,9 +45,9 @@ source_set("unit_tests") { ...@@ -45,9 +45,9 @@ source_set("unit_tests") {
":lib", ":lib",
"//base", "//base",
"//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings",
"//services/identity/public/mojom",
"//services/service_manager/public/cpp", "//services/service_manager/public/cpp",
"//services/service_manager/public/cpp:service_test_support", "//services/service_manager/public/cpp:service_test_support",
"//testing/gmock",
] ]
sources = [ sources = [
"ime_service_unittest.cc", "ime_service_unittest.cc",
......
...@@ -43,15 +43,26 @@ DecoderEngine::DecoderEngine( ...@@ -43,15 +43,26 @@ DecoderEngine::DecoderEngine(
DecoderEngine::~DecoderEngine() {} DecoderEngine::~DecoderEngine() {}
void DecoderEngine::BindRequest(const std::string& ime_spec, bool DecoderEngine::BindRequest(const std::string& ime_spec,
mojom::InputChannelRequest request, mojom::InputChannelRequest request,
mojom::InputChannelPtr client, mojom::InputChannelPtr client,
const std::vector<uint8_t>& extra) { const std::vector<uint8_t>& extra) {
// TODO(https://crbug.com/837156): Build a ClientWrapper with the clientPtr, if (!IsImeSupported(ime_spec))
// inside we ensure the clientPtr will run in the correct SequencedTaskRunner, return false;
// then pass the wrapper to the native library instead of the clientPtr. // TODO(https://crbug.com/837156): Notify the input logic loaded from the
// shared library about the change by forwarding the information received.
// Moreover, in order to make safe calls on the clientPtr inside the input
// logic with multiple threads, we will send a wrapper of the clientPtr,
// where we make sure it runs in the correct SequencedTaskRunner.
channel_bindings_.AddBinding(this, std::move(request)); channel_bindings_.AddBinding(this, std::move(request));
// TODO(https://crbug.com/837156): Registry connection error handler. // TODO(https://crbug.com/837156): Registry connection error handler.
return true;
}
bool DecoderEngine::IsImeSupported(const std::string& ime_spec) {
// TODO(https://crbug.com/837156): Check the capability of the loaded shared
// library first.
return InputEngine::IsImeSupported(ime_spec);
} }
void DecoderEngine::ProcessMessage(const std::vector<uint8_t>& message, void DecoderEngine::ProcessMessage(const std::vector<uint8_t>& message,
......
...@@ -28,10 +28,11 @@ class DecoderEngine : public InputEngine { ...@@ -28,10 +28,11 @@ class DecoderEngine : public InputEngine {
~DecoderEngine() override; ~DecoderEngine() override;
// InputEngine overrides: // InputEngine overrides:
void BindRequest(const std::string& ime_spec, bool BindRequest(const std::string& ime_spec,
mojom::InputChannelRequest request, mojom::InputChannelRequest request,
mojom::InputChannelPtr client, mojom::InputChannelPtr client,
const std::vector<uint8_t>& extra) override; const std::vector<uint8_t>& extra) override;
bool IsImeSupported(const std::string& ime_spec) override;
void ProcessMessage(const std::vector<uint8_t>& message, void ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) override; ProcessMessageCallback callback) override;
......
...@@ -50,8 +50,9 @@ void ImeService::ConnectToImeEngine( ...@@ -50,8 +50,9 @@ void ImeService::ConnectToImeEngine(
const std::vector<uint8_t>& extra, const std::vector<uint8_t>& extra,
ConnectToImeEngineCallback callback) { ConnectToImeEngineCallback callback) {
DCHECK(input_engine_); DCHECK(input_engine_);
input_engine_->BindRequest(ime_spec, std::move(to_engine_request), bool bound = input_engine_->BindRequest(
std::move(from_engine), extra); ime_spec, std::move(to_engine_request), std::move(from_engine), extra);
std::move(callback).Run(bound);
} }
void ImeService::BindInputEngineManagerRequest( void ImeService::BindInputEngineManagerRequest(
......
...@@ -23,7 +23,7 @@ class ImeService : public service_manager::Service, ...@@ -23,7 +23,7 @@ class ImeService : public service_manager::Service,
~ImeService() override; ~ImeService() override;
private: private:
// service_manager::Service: // service_manager::Service overrides:
void OnStart() override; void OnStart() override;
void OnBindInterface(const service_manager::BindSourceInfo& source_info, void OnBindInterface(const service_manager::BindSourceInfo& source_info,
const std::string& interface_name, const std::string& interface_name,
......
...@@ -4,81 +4,144 @@ ...@@ -4,81 +4,144 @@
#include "base/bind.h" #include "base/bind.h"
#include "chromeos/services/ime/ime_service.h"
#include "chromeos/services/ime/public/mojom/constants.mojom.h" #include "chromeos/services/ime/public/mojom/constants.mojom.h"
#include "chromeos/services/ime/public/mojom/input_engine.mojom.h" #include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/service_context.h" #include "services/service_manager/public/cpp/service_context.h"
#include "services/service_manager/public/cpp/service_test.h" #include "services/service_manager/public/cpp/service_test.h"
#include "services/service_manager/public/mojom/service_factory.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
using testing::_;
namespace chromeos { namespace chromeos {
namespace ime { namespace ime {
namespace { namespace {
const char kTestServiceName[] = "ime_unittests"; const char kTestServiceName[] = "ime_unittests";
const char kInvalidImeSpec[] = "ime_spec_never_support";
const std::vector<uint8_t> extra{0x66, 0x77, 0x88}; const std::vector<uint8_t> extra{0x66, 0x77, 0x88};
void RunCallback(bool* success, bool result) { void ConnectCallback(bool* success, bool result) {
*success = result; *success = result;
} }
class ImeServiceTest : public service_manager::test::ServiceTest { class TestClientChannel : mojom::InputChannel {
public: public:
ImeServiceTest() : service_manager::test::ServiceTest(kTestServiceName) {} TestClientChannel() : binding_(this) {}
~ImeServiceTest() override {}
void SetUp() override { mojom::InputChannelPtr CreateInterfacePtrAndBind() {
ServiceTest::SetUp(); mojom::InputChannelPtr ptr;
// TODO(https://crbug.com/837156): Start or bind other services used. binding_.Bind(mojo::MakeRequest(&ptr));
// Eg. connector()->StartService(kServiceName) or return ptr;
// connector()->BindInterface(kServiceName, &ptr);
} }
// mojom::InputChannel implementation.
MOCK_METHOD2(ProcessText, void(const std::string&, ProcessTextCallback));
MOCK_METHOD2(ProcessMessage,
void(const std::vector<uint8_t>& message,
ProcessMessageCallback));
private: private:
DISALLOW_COPY_AND_ASSIGN(ImeServiceTest); mojo::Binding<mojom::InputChannel> binding_;
DISALLOW_COPY_AND_ASSIGN(TestClientChannel);
}; };
class FakeClient : mojom::InputChannel { class ImeServiceTestClient : public service_manager::test::ServiceTestClient,
public service_manager::mojom::ServiceFactory {
public: public:
FakeClient() : binding_(this) {} ImeServiceTestClient(service_manager::test::ServiceTest* test)
: service_manager::test::ServiceTestClient(test) {
registry_.AddInterface<service_manager::mojom::ServiceFactory>(
base::BindRepeating(&ImeServiceTestClient::Create,
base::Unretained(this)));
}
mojom::InputChannelPtr CreateInterfacePtrAndBind() { protected:
mojom::InputChannelPtr ptr; void OnBindInterface(const service_manager::BindSourceInfo& source_info,
binding_.Bind(mojo::MakeRequest(&ptr)); const std::string& interface_name,
return ptr; mojo::ScopedMessagePipeHandle interface_pipe) override {
registry_.BindInterface(interface_name, std::move(interface_pipe));
} }
private: // service_manager::mojom::ServiceFactory
// mojom::InputEngineClient: void CreateService(
void ProcessText(const std::string& message, service_manager::mojom::ServiceRequest request,
ProcessTextCallback callback) override{}; const std::string& name,
void ProcessMessage(const std::vector<uint8_t>& message, service_manager::mojom::PIDReceiverPtr pid_receiver) override {
ProcessMessageCallback callback) override{}; if (name == mojom::kServiceName) {
service_context_.reset(new service_manager::ServiceContext(
CreateImeService(), std::move(request)));
}
}
mojo::Binding<mojom::InputChannel> binding_; void Create(service_manager::mojom::ServiceFactoryRequest request) {
service_factory_bindings_.AddBinding(this, std::move(request));
}
private:
service_manager::BinderRegistry registry_;
mojo::BindingSet<service_manager::mojom::ServiceFactory>
service_factory_bindings_;
DISALLOW_COPY_AND_ASSIGN(FakeClient); std::unique_ptr<service_manager::ServiceContext> service_context_;
DISALLOW_COPY_AND_ASSIGN(ImeServiceTestClient);
}; };
} // namespace class ImeServiceTest : public service_manager::test::ServiceTest {
public:
ImeServiceTest() : service_manager::test::ServiceTest(kTestServiceName) {}
~ImeServiceTest() override {}
// Tests activating an IME and set its delegate. MOCK_METHOD1(SentTextCallback, void(const std::string&));
TEST_F(ImeServiceTest, ConnectImeEngine) { MOCK_METHOD1(SentMessageCallback, void(const std::vector<uint8_t>&));
connector()->StartService(mojom::kServiceName);
mojom::InputEngineManagerPtr manager; protected:
connector()->BindInterface(mojom::kServiceName, &manager); void SetUp() override {
ServiceTest::SetUp();
connector()->BindInterface(mojom::kServiceName,
mojo::MakeRequest(&ime_manager_));
bool success = false; // TODO(https://crbug.com/837156): Start or bind other services used.
FakeClient client; // Eg. connector()->StartService(mojom::kSomeServiceName);
}
// service_manager::test::ServiceTest
std::unique_ptr<service_manager::Service> CreateService() override {
return std::make_unique<ImeServiceTestClient>(this);
}
void TearDown() override {
ime_manager_.reset();
ServiceTest::TearDown();
}
mojom::InputEngineManagerPtr ime_manager_;
private:
DISALLOW_COPY_AND_ASSIGN(ImeServiceTest);
};
} // namespace
// Tests that the service is instantiated and it will return false when
// activating an IME engine with an invalid IME spec.
TEST_F(ImeServiceTest, ConnectInvalidImeEngine) {
bool success = true;
TestClientChannel test_channel;
mojom::InputChannelPtr to_engine_ptr; mojom::InputChannelPtr to_engine_ptr;
manager->ConnectToImeEngine("FakeIME", mojo::MakeRequest(&to_engine_ptr), ime_manager_->ConnectToImeEngine(
client.CreateInterfacePtrAndBind(), extra, kInvalidImeSpec, mojo::MakeRequest(&to_engine_ptr),
base::BindOnce(&RunCallback, &success)); test_channel.CreateInterfacePtrAndBind(), extra,
base::BindOnce(&ConnectCallback, &success));
ime_manager_.FlushForTesting();
EXPECT_FALSE(success);
} }
} // namespace ime } // namespace ime
......
...@@ -14,14 +14,23 @@ InputEngine::InputEngine() {} ...@@ -14,14 +14,23 @@ InputEngine::InputEngine() {}
InputEngine::~InputEngine() {} InputEngine::~InputEngine() {}
void InputEngine::BindRequest(const std::string& ime_spec, bool InputEngine::BindRequest(const std::string& ime_spec,
mojom::InputChannelRequest request, mojom::InputChannelRequest request,
mojom::InputChannelPtr client, mojom::InputChannelPtr client,
const std::vector<uint8_t>& extra) { const std::vector<uint8_t>& extra) {
if (!IsImeSupported(ime_spec))
return false;
channel_bindings_.AddBinding(this, std::move(request), ime_spec); channel_bindings_.AddBinding(this, std::move(request), ime_spec);
return true;
// TODO(https://crbug.com/837156): Registry connection error handler. // TODO(https://crbug.com/837156): Registry connection error handler.
} }
bool InputEngine::IsImeSupported(const std::string& ime_spec) {
// TODO(https://crbug.com/837156): Add all supported IME tpyes.
return false;
}
void InputEngine::ProcessText(const std::string& message, void InputEngine::ProcessText(const std::string& message,
ProcessTextCallback callback) { ProcessTextCallback callback) {
auto& ime_spec = channel_bindings_.dispatch_context(); auto& ime_spec = channel_bindings_.dispatch_context();
...@@ -31,7 +40,7 @@ void InputEngine::ProcessText(const std::string& message, ...@@ -31,7 +40,7 @@ void InputEngine::ProcessText(const std::string& message,
void InputEngine::ProcessMessage(const std::vector<uint8_t>& message, void InputEngine::ProcessMessage(const std::vector<uint8_t>& message,
ProcessMessageCallback callback) { ProcessMessageCallback callback) {
NOTREACHED() << "No defined protobuf message in this implementation"; NOTIMPLEMENTED(); // Protobuf message is not used in the basic engine.
} }
const std::string& InputEngine::Process(const std::string& message, const std::string& InputEngine::Process(const std::string& message,
......
...@@ -17,12 +17,16 @@ class InputEngine : public mojom::InputChannel { ...@@ -17,12 +17,16 @@ class InputEngine : public mojom::InputChannel {
InputEngine(); InputEngine();
~InputEngine() override; ~InputEngine() override;
// Binds the mojom::InputChannel interface to this object. // Binds the mojom::InputChannel interface to this object and returns true if
virtual void BindRequest(const std::string& ime_spec, // the given ime_spec is supported by the engine.
virtual bool BindRequest(const std::string& ime_spec,
mojom::InputChannelRequest request, mojom::InputChannelRequest request,
mojom::InputChannelPtr client, mojom::InputChannelPtr client,
const std::vector<uint8_t>& extra); const std::vector<uint8_t>& extra);
// Returns whether the given ime_spec is supported by this engine.
virtual bool IsImeSupported(const std::string& ime_spec);
// mojom::MessageChannel overrides: // mojom::MessageChannel overrides:
void ProcessText(const std::string& message, void ProcessText(const std::string& message,
ProcessTextCallback callback) override; ProcessTextCallback callback) override;
......
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
"interface_provider_specs": { "interface_provider_specs": {
"service_manager:connector": { "service_manager:connector": {
"provides": { "provides": {
"input_engine" : [ "chromeos.ime.mojom.InputEngine" ] "input_engine" : [
"chromeos.ime.mojom.InputEngineManager",
"chromeos.ime.mojom.InputChannel"
]
}, },
"requires": { "requires": {
"service_manager": [ "service_manager:all_users" ] "service_manager": [ "service_manager:all_users" ]
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
module chromeos.ime.mojom; module chromeos.ime.mojom;
const string kServiceName = "ime_service"; const string kServiceName = "ime";
...@@ -3,6 +3,11 @@ ...@@ -3,6 +3,11 @@
"display_name": "IME Unittests", "display_name": "IME Unittests",
"interface_provider_specs": { "interface_provider_specs": {
"service_manager:connector": { "service_manager:connector": {
"provides": {
"service_manager:service_factory": [
"service_manager.mojom.ServiceFactory"
]
},
"requires": { "requires": {
"ime": [ "input_engine" ] "ime": [ "input_engine" ]
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment