Commit 27273fd1 authored by Jing Wang's avatar Jing Wang Committed by Commit Bot

Handle Engine failure better.

1. Add an extra error param to GetEngineIfActive, so that we can tell if
it fails because the engine is unavailable or inactive.
2. Add LOGs for engine errors.
3. Add error handling to more functions.
4. Add some helper functions to reduce code duplication.
5. Minor change on constants name for readability.
6. Disable some browser tests, they were actually testing nothing before (because there was no active engine, they actually skipped everything...). Eventually we should rewrite those tests in the new fashion as https://cs.chromium.org/chromium/src/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc

R=keithlee, shend, shuchen

Bug: 1024606
Change-Id: I9902e42a472122c5c1a02c36e70f71b52cdd80d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1933855Reviewed-by: default avatarKeith Lee <keithlee@chromium.org>
Reviewed-by: default avatarShu Chen <shuchen@chromium.org>
Reviewed-by: default avatarDarren Shen <shend@chromium.org>
Commit-Queue: Keith Lee <keithlee@chromium.org>
Commit-Queue: Jing Wang <jiwan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719454}
parent d16e059d
...@@ -80,7 +80,20 @@ namespace { ...@@ -80,7 +80,20 @@ namespace {
const char kXkbPrefix[] = "xkb:"; const char kXkbPrefix[] = "xkb:";
const char kErrorFailToShowInputView[] = const char kErrorFailToShowInputView[] =
"Unable to show the input view window."; "Unable to show the input view window.";
const char kInputImeApiEngineNotAvaliable[] = "Engine is not available"; const char kErrorRouterNotAvailable[] = "The router is not available.";
InputMethodEngineBase* GetEngineIfActive(
content::BrowserContext* browser_context,
const std::string& extension_id,
std::string* error) {
Profile* profile = Profile::FromBrowserContext(browser_context);
extensions::InputImeEventRouter* event_router =
extensions::GetInputImeEventRouter(profile);
CHECK(event_router) << kErrorRouterNotAvailable;
InputMethodEngineBase* engine =
event_router->GetEngineIfActive(extension_id, error);
return engine;
}
} // namespace } // namespace
...@@ -344,77 +357,69 @@ ExtensionFunction::ResponseAction InputMethodPrivateSetSettingFunction::Run() { ...@@ -344,77 +357,69 @@ ExtensionFunction::ResponseAction InputMethodPrivateSetSettingFunction::Run() {
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
InputMethodPrivateSetCompositionRangeFunction::Run() { InputMethodPrivateSetCompositionRangeFunction::Run() {
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()));
InputMethodEngineBase* engine = InputMethodEngineBase* engine =
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr; GetEngineIfActive(browser_context(), extension_id(), &error);
if (engine) { if (!engine)
const auto parent_params = SetCompositionRange::Params::Create(*args_); return RespondNow(Error(error));
const auto& params = parent_params->parameters;
std::vector<InputMethodEngineBase::SegmentInfo> segments; const auto parent_params = SetCompositionRange::Params::Create(*args_);
if (params.segments) { const auto& params = parent_params->parameters;
for (const auto& segments_arg : *params.segments) { std::vector<InputMethodEngineBase::SegmentInfo> segments;
InputMethodEngineBase::SegmentInfo segment_info; if (params.segments) {
segment_info.start = segments_arg.start; for (const auto& segments_arg : *params.segments) {
segment_info.end = segments_arg.end;
switch (segments_arg.style) {
case input_method_private::UNDERLINE_STYLE_UNDERLINE:
segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_DOUBLEUNDERLINE:
segment_info.style =
InputMethodEngineBase::SEGMENT_STYLE_DOUBLE_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_NOUNDERLINE:
segment_info.style =
InputMethodEngineBase::SEGMENT_STYLE_NO_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_NONE:
EXTENSION_FUNCTION_VALIDATE(false);
break;
}
segments.push_back(segment_info);
}
} else {
// Default to a single segment that spans the entire range.
InputMethodEngineBase::SegmentInfo segment_info; InputMethodEngineBase::SegmentInfo segment_info;
segment_info.start = 0; segment_info.start = segments_arg.start;
segment_info.end = params.selection_before + params.selection_after; segment_info.end = segments_arg.end;
segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE; switch (segments_arg.style) {
case input_method_private::UNDERLINE_STYLE_UNDERLINE:
segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_DOUBLEUNDERLINE:
segment_info.style =
InputMethodEngineBase::SEGMENT_STYLE_DOUBLE_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_NOUNDERLINE:
segment_info.style =
InputMethodEngineBase::SEGMENT_STYLE_NO_UNDERLINE;
break;
case input_method_private::UNDERLINE_STYLE_NONE:
EXTENSION_FUNCTION_VALIDATE(false);
break;
}
segments.push_back(segment_info); segments.push_back(segment_info);
} }
std::string error; } else {
if (!engine->SetCompositionRange(params.context_id, params.selection_before, // Default to a single segment that spans the entire range.
params.selection_after, segments, InputMethodEngineBase::SegmentInfo segment_info;
&error)) { segment_info.start = 0;
auto results = std::make_unique<base::ListValue>(); segment_info.end = params.selection_before + params.selection_after;
results->Append(std::make_unique<base::Value>(false)); segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
return RespondNow(ErrorWithArguments(std::move(results), error)); segments.push_back(segment_info);
} }
if (!engine->SetCompositionRange(params.context_id, params.selection_before,
params.selection_after, segments, &error)) {
auto results = std::make_unique<base::ListValue>();
results->Append(std::make_unique<base::Value>(false));
return RespondNow(ErrorWithArguments(std::move(results), error));
} }
return RespondNow(OneArgument(std::make_unique<base::Value>(true))); return RespondNow(OneArgument(std::make_unique<base::Value>(true)));
} }
ExtensionFunction::ResponseAction ExtensionFunction::ResponseAction
InputMethodPrivateSetSelectionRangeFunction::Run() { InputMethodPrivateSetSelectionRangeFunction::Run() {
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()));
InputMethodEngineBase* engine = InputMethodEngineBase* engine =
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr; GetEngineIfActive(browser_context(), extension_id(), &error);
if (!engine)
if (!engine) { return RespondNow(Error(error));
auto results = std::make_unique<base::ListValue>();
results->Append(std::make_unique<base::Value>(false));
return RespondNow(
ErrorWithArguments(std::move(results), kInputImeApiEngineNotAvaliable));
}
std::unique_ptr<SetSelectionRange::Params> parent_params( std::unique_ptr<SetSelectionRange::Params> parent_params(
SetSelectionRange::Params::Create(*args_)); SetSelectionRange::Params::Create(*args_));
const SetSelectionRange::Params::Parameters& params = const SetSelectionRange::Params::Parameters& params =
parent_params->parameters; parent_params->parameters;
std::string error;
if (!engine->SetSelectionRange(params.context_id, *params.selection_start, if (!engine->SetSelectionRange(params.context_id, *params.selection_start,
*params.selection_end, &error)) { *params.selection_end, &error)) {
auto results = std::make_unique<base::ListValue>(); auto results = std::make_unique<base::ListValue>();
......
...@@ -19,9 +19,22 @@ namespace SendKeyEvents = extensions::api::input_ime::SendKeyEvents; ...@@ -19,9 +19,22 @@ namespace SendKeyEvents = extensions::api::input_ime::SendKeyEvents;
using input_method::InputMethodEngineBase; using input_method::InputMethodEngineBase;
namespace { namespace {
const char kInputImeApiErrorEngineNotAvailable[] = "Engine is not available"; const char kErrorRouterNotAvailable[] = "The router is not available.";
const char kInputImeApiErrorSetKeyEventsFail[] = "Could not send key events"; const char kErrorSetKeyEventsFail[] = "Could not send key events";
InputMethodEngineBase* GetEngineIfActive(Profile* profile,
const std::string& extension_id,
std::string* error) {
extensions::InputImeEventRouter* event_router =
extensions::GetInputImeEventRouter(profile);
CHECK(event_router) << kErrorRouterNotAvailable;
InputMethodEngineBase* engine =
event_router->GetEngineIfActive(extension_id, error);
return engine;
}
} // namespace } // namespace
namespace ui { namespace ui {
ImeObserver::ImeObserver(const std::string& extension_id, Profile* profile) ImeObserver::ImeObserver(const std::string& extension_id, Profile* profile)
...@@ -89,13 +102,13 @@ void ImeObserver::OnKeyEvent( ...@@ -89,13 +102,13 @@ void ImeObserver::OnKeyEvent(
return; return;
} }
extensions::InputImeEventRouter* event_router = std::string error;
extensions::GetInputImeEventRouter(profile_); InputMethodEngineBase* engine =
if (!event_router || !event_router->GetEngineIfActive(extension_id_)) GetEngineIfActive(profile_, extension_id_, &error);
if (!engine)
return; return;
const std::string request_id = const std::string request_id =
event_router->GetEngineIfActive(extension_id_) engine->AddPendingKeyEvent(component_id, std::move(callback));
->AddPendingKeyEvent(component_id, std::move(callback));
input_ime::KeyboardEvent key_data_value; input_ime::KeyboardEvent key_data_value;
key_data_value.type = input_ime::ParseKeyboardEventType(event.type); key_data_value.type = input_ime::ParseKeyboardEventType(event.type);
...@@ -303,92 +316,86 @@ void InputImeEventRouterFactory::RemoveProfile(Profile* profile) { ...@@ -303,92 +316,86 @@ void InputImeEventRouterFactory::RemoveProfile(Profile* profile) {
ExtensionFunction::ResponseAction InputImeKeyEventHandledFunction::Run() { ExtensionFunction::ResponseAction InputImeKeyEventHandledFunction::Run() {
std::unique_ptr<KeyEventHandled::Params> params( std::unique_ptr<KeyEventHandled::Params> params(
KeyEventHandled::Params::Create(*args_)); KeyEventHandled::Params::Create(*args_));
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context())); InputMethodEngineBase* engine = GetEngineIfActive(
InputMethodEngineBase* engine = Profile::FromBrowserContext(browser_context()), extension_id(), &error);
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr; if (!engine)
if (engine) { return RespondNow(Error(error));
engine->KeyEventHandled(extension_id(), params->request_id,
params->response); engine->KeyEventHandled(extension_id(), params->request_id, params->response);
}
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
ExtensionFunction::ResponseAction InputImeSetCompositionFunction::Run() { ExtensionFunction::ResponseAction InputImeSetCompositionFunction::Run() {
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context())); InputMethodEngineBase* engine = GetEngineIfActive(
InputMethodEngineBase* engine = Profile::FromBrowserContext(browser_context()), extension_id(), &error);
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr; if (!engine)
if (engine) { return RespondNow(Error(error));
std::unique_ptr<SetComposition::Params> parent_params(
SetComposition::Params::Create(*args_)); std::unique_ptr<SetComposition::Params> parent_params(
const SetComposition::Params::Parameters& params = SetComposition::Params::Create(*args_));
parent_params->parameters; const SetComposition::Params::Parameters& params = parent_params->parameters;
std::vector<InputMethodEngineBase::SegmentInfo> segments; std::vector<InputMethodEngineBase::SegmentInfo> segments;
if (params.segments) { if (params.segments) {
for (const auto& segments_arg : *params.segments) { for (const auto& segments_arg : *params.segments) {
EXTENSION_FUNCTION_VALIDATE(segments_arg.style != EXTENSION_FUNCTION_VALIDATE(segments_arg.style !=
input_ime::UNDERLINE_STYLE_NONE); input_ime::UNDERLINE_STYLE_NONE);
InputMethodEngineBase::SegmentInfo segment_info; InputMethodEngineBase::SegmentInfo segment_info;
segment_info.start = segments_arg.start; segment_info.start = segments_arg.start;
segment_info.end = segments_arg.end; segment_info.end = segments_arg.end;
if (segments_arg.style == input_ime::UNDERLINE_STYLE_UNDERLINE) { if (segments_arg.style == input_ime::UNDERLINE_STYLE_UNDERLINE) {
segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE; segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_UNDERLINE;
} else if (segments_arg.style == } else if (segments_arg.style ==
input_ime::UNDERLINE_STYLE_DOUBLEUNDERLINE) { input_ime::UNDERLINE_STYLE_DOUBLEUNDERLINE) {
segment_info.style = segment_info.style =
InputMethodEngineBase::SEGMENT_STYLE_DOUBLE_UNDERLINE; InputMethodEngineBase::SEGMENT_STYLE_DOUBLE_UNDERLINE;
} else { } else {
segment_info.style = segment_info.style = InputMethodEngineBase::SEGMENT_STYLE_NO_UNDERLINE;
InputMethodEngineBase::SEGMENT_STYLE_NO_UNDERLINE;
}
segments.push_back(segment_info);
} }
} segments.push_back(segment_info);
int selection_start =
params.selection_start ? *params.selection_start : params.cursor;
int selection_end =
params.selection_end ? *params.selection_end : params.cursor;
std::string error;
if (!engine->SetComposition(params.context_id, params.text.c_str(),
selection_start, selection_end, params.cursor,
segments, &error)) {
std::unique_ptr<base::ListValue> results =
std::make_unique<base::ListValue>();
results->Append(std::make_unique<base::Value>(false));
return RespondNow(ErrorWithArguments(std::move(results), error));
} }
} }
int selection_start =
params.selection_start ? *params.selection_start : params.cursor;
int selection_end =
params.selection_end ? *params.selection_end : params.cursor;
if (!engine->SetComposition(params.context_id, params.text.c_str(),
selection_start, selection_end, params.cursor,
segments, &error)) {
std::unique_ptr<base::ListValue> results =
std::make_unique<base::ListValue>();
results->Append(std::make_unique<base::Value>(false));
return RespondNow(ErrorWithArguments(std::move(results), error));
}
return RespondNow(OneArgument(std::make_unique<base::Value>(true))); return RespondNow(OneArgument(std::make_unique<base::Value>(true)));
} }
ExtensionFunction::ResponseAction InputImeCommitTextFunction::Run() { ExtensionFunction::ResponseAction InputImeCommitTextFunction::Run() {
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context())); InputMethodEngineBase* engine = GetEngineIfActive(
InputMethodEngineBase* engine = Profile::FromBrowserContext(browser_context()), extension_id(), &error);
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr; if (!engine)
if (engine) { return RespondNow(Error(error));
std::unique_ptr<CommitText::Params> parent_params(
CommitText::Params::Create(*args_)); std::unique_ptr<CommitText::Params> parent_params(
const CommitText::Params::Parameters& params = parent_params->parameters; CommitText::Params::Create(*args_));
std::string error; const CommitText::Params::Parameters& params = parent_params->parameters;
if (!engine->CommitText(params.context_id, params.text.c_str(), &error)) { if (!engine->CommitText(params.context_id, params.text.c_str(), &error)) {
std::unique_ptr<base::ListValue> results = std::unique_ptr<base::ListValue> results =
std::make_unique<base::ListValue>(); std::make_unique<base::ListValue>();
results->Append(std::make_unique<base::Value>(false)); results->Append(std::make_unique<base::Value>(false));
return RespondNow(ErrorWithArguments(std::move(results), error)); return RespondNow(ErrorWithArguments(std::move(results), error));
}
} }
return RespondNow(OneArgument(std::make_unique<base::Value>(true))); return RespondNow(OneArgument(std::make_unique<base::Value>(true)));
} }
ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() { ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() {
InputImeEventRouter* event_router = std::string error;
GetInputImeEventRouter(Profile::FromBrowserContext(browser_context())); InputMethodEngineBase* engine = GetEngineIfActive(
InputMethodEngineBase* engine = Profile::FromBrowserContext(browser_context()), extension_id(), &error);
event_router ? event_router->GetEngineIfActive(extension_id()) : nullptr;
if (!engine) if (!engine)
return RespondNow(Error(kInputImeApiErrorEngineNotAvailable)); return RespondNow(Error(error));
std::unique_ptr<SendKeyEvents::Params> parent_params( std::unique_ptr<SendKeyEvents::Params> parent_params(
SendKeyEvents::Params::Create(*args_)); SendKeyEvents::Params::Create(*args_));
...@@ -411,7 +418,7 @@ ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() { ...@@ -411,7 +418,7 @@ ExtensionFunction::ResponseAction InputImeSendKeyEventsFunction::Run() {
event.caps_lock = key_event.caps_lock ? *(key_event.caps_lock) : false; event.caps_lock = key_event.caps_lock ? *(key_event.caps_lock) : false;
} }
if (!engine->SendKeyEvents(params.context_id, key_data_out)) if (!engine->SendKeyEvents(params.context_id, key_data_out))
return RespondNow(Error(kInputImeApiErrorSetKeyEventsFail)); return RespondNow(Error(kErrorSetKeyEventsFail));
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
......
...@@ -177,7 +177,8 @@ class InputImeEventRouter : public InputImeEventRouterBase { ...@@ -177,7 +177,8 @@ class InputImeEventRouter : public InputImeEventRouterBase {
chromeos::InputMethodEngine* GetEngine(const std::string& extension_id); chromeos::InputMethodEngine* GetEngine(const std::string& extension_id);
input_method::InputMethodEngineBase* GetEngineIfActive( input_method::InputMethodEngineBase* GetEngineIfActive(
const std::string& extension_id) override; const std::string& extension_id,
std::string* error) override;
std::string GetUnloadedExtensionId() const { std::string GetUnloadedExtensionId() const {
return unloaded_component_extension_id_; return unloaded_component_extension_id_;
......
...@@ -35,7 +35,8 @@ namespace input_ime = extensions::api::input_ime; ...@@ -35,7 +35,8 @@ namespace input_ime = extensions::api::input_ime;
namespace { namespace {
const char kErrorNoActiveEngine[] = "The extension has not been activated."; const char kErrorEngineNotActive[] = "The engine is not active.";
const char kErrorRouterNotAvailable[] = "The router is not available.";
const char kErrorPermissionDenied[] = "User denied permission."; const char kErrorPermissionDenied[] = "User denied permission.";
const char kErrorCouldNotFindActiveBrowser[] = const char kErrorCouldNotFindActiveBrowser[] =
"Cannot find the active browser."; "Cannot find the active browser.";
...@@ -123,13 +124,13 @@ class ImeObserverNonChromeOS : public ui::ImeObserver { ...@@ -123,13 +124,13 @@ class ImeObserverNonChromeOS : public ui::ImeObserver {
namespace extensions { namespace extensions {
InputMethodEngine* GetEngineIfActive(content::BrowserContext* browser_context, InputMethodEngine* GetEngineIfActive(content::BrowserContext* browser_context,
const std::string& extension_id) { const std::string& extension_id,
std::string* error) {
Profile* profile = Profile::FromBrowserContext(browser_context); Profile* profile = Profile::FromBrowserContext(browser_context);
InputImeEventRouter* event_router = GetInputImeEventRouter(profile); InputImeEventRouter* event_router = GetInputImeEventRouter(profile);
InputMethodEngine* engine = CHECK(event_router) << kErrorRouterNotAvailable;
event_router ? static_cast<InputMethodEngine*>( InputMethodEngine* engine = static_cast<InputMethodEngine*>(
event_router->GetEngineIfActive(extension_id)) event_router->GetEngineIfActive(extension_id, error));
: nullptr;
return engine; return engine;
} }
...@@ -175,12 +176,16 @@ InputImeEventRouter::~InputImeEventRouter() { ...@@ -175,12 +176,16 @@ InputImeEventRouter::~InputImeEventRouter() {
} }
InputMethodEngineBase* InputImeEventRouter::GetEngineIfActive( InputMethodEngineBase* InputImeEventRouter::GetEngineIfActive(
const std::string& extension_id) { const std::string& extension_id,
return (ui::IMEBridge::Get()->GetCurrentEngineHandler() && std::string* error) {
active_engine_ && if (ui::IMEBridge::Get()->GetCurrentEngineHandler() && active_engine_ &&
active_engine_->GetExtensionId() == extension_id) active_engine_->GetExtensionId() == extension_id) {
? active_engine_ return active_engine_;
: nullptr; } else {
LOG(WARNING) << kErrorEngineNotActive << " extension id: " << extension_id;
*error = kErrorEngineNotActive;
return nullptr;
}
} }
void InputImeEventRouter::SetActiveEngine(const std::string& extension_id) { void InputImeEventRouter::SetActiveEngine(const std::string& extension_id) {
...@@ -229,7 +234,7 @@ ExtensionFunction::ResponseAction InputImeActivateFunction::Run() { ...@@ -229,7 +234,7 @@ ExtensionFunction::ResponseAction InputImeActivateFunction::Run() {
Profile* profile = Profile::FromBrowserContext(browser_context()); Profile* profile = Profile::FromBrowserContext(browser_context());
InputImeEventRouter* event_router = GetInputImeEventRouter(profile); InputImeEventRouter* event_router = GetInputImeEventRouter(profile);
if (!event_router) if (!event_router)
return RespondNow(Error(kErrorNoActiveEngine)); return RespondNow(Error(kErrorEngineNotActive));
ExtensionPrefs* prefs = ExtensionPrefs::Get(profile); ExtensionPrefs* prefs = ExtensionPrefs::Get(profile);
...@@ -306,7 +311,7 @@ void InputImeActivateFunction::OnPermissionBubbleFinished( ...@@ -306,7 +311,7 @@ void InputImeActivateFunction::OnPermissionBubbleFinished(
Profile* profile = Profile::FromBrowserContext(browser_context()); Profile* profile = Profile::FromBrowserContext(browser_context());
InputImeEventRouter* event_router = GetInputImeEventRouter(profile); InputImeEventRouter* event_router = GetInputImeEventRouter(profile);
if (!event_router) { if (!event_router) {
Respond(Error(kErrorNoActiveEngine)); Respond(Error(kErrorEngineNotActive));
return; return;
} }
event_router->SetActiveEngine(extension_id()); event_router->SetActiveEngine(extension_id());
...@@ -323,8 +328,12 @@ void InputImeActivateFunction::OnPermissionBubbleFinished( ...@@ -323,8 +328,12 @@ void InputImeActivateFunction::OnPermissionBubbleFinished(
} }
ExtensionFunction::ResponseAction InputImeDeactivateFunction::Run() { ExtensionFunction::ResponseAction InputImeDeactivateFunction::Run() {
std::string error;
InputMethodEngine* engine = InputMethodEngine* engine =
GetEngineIfActive(browser_context(), extension_id()); GetEngineIfActive(browser_context(), extension_id(), &error);
if (!engine) {
return RespondNow(Error(error));
}
ui::IMEBridge::Get()->SetCurrentEngineHandler(nullptr); ui::IMEBridge::Get()->SetCurrentEngineHandler(nullptr);
if (engine) if (engine)
engine->CloseImeWindows(); engine->CloseImeWindows();
...@@ -351,12 +360,12 @@ ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() { ...@@ -351,12 +360,12 @@ ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() {
bounds.set_height(options.bounds->height); bounds.set_height(options.bounds->height);
} }
std::string error;
InputMethodEngine* engine = InputMethodEngine* engine =
GetEngineIfActive(browser_context(), extension_id()); GetEngineIfActive(browser_context(), extension_id(), &error);
if (!engine) if (!engine)
return RespondNow(Error(kErrorNoActiveEngine)); return RespondNow(Error(error));
std::string error;
int frame_id = engine->CreateImeWindow( int frame_id = engine->CreateImeWindow(
extension(), render_frame_host(), extension(), render_frame_host(),
options.url.get() ? *options.url : url::kAboutBlankURL, options.url.get() ? *options.url : url::kAboutBlankURL,
...@@ -374,10 +383,11 @@ ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() { ...@@ -374,10 +383,11 @@ ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() {
} }
ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() { ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() {
std::string error;
InputMethodEngine* engine = InputMethodEngine* engine =
GetEngineIfActive(browser_context(), extension_id()); GetEngineIfActive(browser_context(), extension_id(), &error);
if (!engine) if (!engine)
return RespondNow(Error(kErrorNoActiveEngine)); return RespondNow(Error(error));
std::unique_ptr<api::input_ime::ShowWindow::Params> params( std::unique_ptr<api::input_ime::ShowWindow::Params> params(
api::input_ime::ShowWindow::Params::Create(*args_)); api::input_ime::ShowWindow::Params::Create(*args_));
...@@ -387,10 +397,11 @@ ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() { ...@@ -387,10 +397,11 @@ ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() {
} }
ExtensionFunction::ResponseAction InputImeHideWindowFunction::Run() { ExtensionFunction::ResponseAction InputImeHideWindowFunction::Run() {
std::string error;
InputMethodEngine* engine = InputMethodEngine* engine =
GetEngineIfActive(browser_context(), extension_id()); GetEngineIfActive(browser_context(), extension_id(), &error);
if (!engine) if (!engine)
return RespondNow(Error(kErrorNoActiveEngine)); return RespondNow(Error(error));
std::unique_ptr<api::input_ime::HideWindow::Params> params( std::unique_ptr<api::input_ime::HideWindow::Params> params(
api::input_ime::HideWindow::Params::Create(*args_)); api::input_ime::HideWindow::Params::Create(*args_));
......
...@@ -35,7 +35,8 @@ class InputImeEventRouter : public InputImeEventRouterBase { ...@@ -35,7 +35,8 @@ class InputImeEventRouter : public InputImeEventRouterBase {
// Gets the input method engine if the extension is active. // Gets the input method engine if the extension is active.
input_method::InputMethodEngineBase* GetEngineIfActive( input_method::InputMethodEngineBase* GetEngineIfActive(
const std::string& extension_id) override; const std::string& extension_id,
std::string* error) override;
// Actives the extension with new input method engine, and deletes the // Actives the extension with new input method engine, and deletes the
// previous engine if another extension was active. // previous engine if another extension was active.
......
...@@ -23,7 +23,8 @@ class InputImeEventRouterBase { ...@@ -23,7 +23,8 @@ class InputImeEventRouterBase {
// Gets the input method engine if the extension is active. // Gets the input method engine if the extension is active.
virtual input_method::InputMethodEngineBase* GetEngineIfActive( virtual input_method::InputMethodEngineBase* GetEngineIfActive(
const std::string& extension_id) = 0; const std::string& extension_id,
std::string* error) = 0;
Profile* GetProfile() const { return profile_; } Profile* GetProfile() const { return profile_; }
......
...@@ -2,36 +2,36 @@ ...@@ -2,36 +2,36 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
function setCompositionTest() { // Disabled: crbug.com/641425.
chrome.input.ime.setComposition({ // function setCompositionTest() {
"contextID": 1, // chrome.input.ime.setComposition({
"text": "Pie", // "contextID": 1,
"selectionStart": 1, // "text": "Pie",
"selectionEnd": 2, // "selectionStart": 1,
"cursor": 3, // "selectionEnd": 2,
"segments": [{ // "cursor": 3,
"start": 0, // "segments": [{
"end": 1, // "start": 0,
"style": "underline" // "end": 1,
}] // "style": "underline"
}, chrome.test.callbackPass()); // }]
} // }, chrome.test.callbackPass());
// }
function clearCompositionTest() {
chrome.input.ime.clearComposition({
"contextID": 1
}, chrome.test.callbackPass());
}
function commitTextTest() { // Disabled: crbug.com/641425.
chrome.input.ime.commitText({ // function clearCompositionTest() {
"contextID": 2, // chrome.input.ime.clearComposition({
"text": "Seaguls" // "contextID": 1
}, chrome.test.callbackPass()); // }, chrome.test.callbackPass());
} // }
// Disabled: crbug.com/641425.
// function commitTextTest() {
// chrome.input.ime.commitText({
// "contextID": 2,
// "text": "Seaguls"
// }, chrome.test.callbackPass());
// }
// Disabled: crbug.com/641425. // Disabled: crbug.com/641425.
// function setCandidateWindowPropertiesTest() { // function setCandidateWindowPropertiesTest() {
...@@ -48,37 +48,36 @@ function commitTextTest() { ...@@ -48,37 +48,36 @@ function commitTextTest() {
// }, chrome.test.callbackPass()); // }, chrome.test.callbackPass());
// } // }
// Disabled: crbug.com/641425.
// function setCandidatesTest() {
// chrome.input.ime.setCandidates({
// "contextID": 8,
// "candidates": [{
// "candidate": "one",
// "id": 1,
// "label": "first",
// "annotation": "The first one"
// }, {
// "candidate": "two",
// "id": 2,
// "label": "second",
// "annotation": "The second one"
// }, {
// "candidate": "three",
// "id": 3,
// "label": "third",
// "annotation": "The third one"
// }]
// }, chrome.test.callbackPass());
// }
function setCandidatesTest() { // Disabled: crbug.com/641425.
chrome.input.ime.setCandidates({ // function setCursorPositionTest() {
"contextID": 8, // chrome.input.ime.setCursorPosition({
"candidates": [{ // "contextID": 9,
"candidate": "one", // "candidateID": 1
"id": 1, // }, chrome.test.callbackPass());
"label": "first", // }
"annotation": "The first one"
}, {
"candidate": "two",
"id": 2,
"label": "second",
"annotation": "The second one"
}, {
"candidate": "three",
"id": 3,
"label": "third",
"annotation": "The third one"
}]
}, chrome.test.callbackPass());
}
function setCursorPositionTest() {
chrome.input.ime.setCursorPosition({
"contextID": 9,
"candidateID": 1
}, chrome.test.callbackPass());
}
// Disabled: crbug.com/641425. // Disabled: crbug.com/641425.
// function setMenuItemsTest() { // function setMenuItemsTest() {
...@@ -125,12 +124,12 @@ function setCursorPositionTest() { ...@@ -125,12 +124,12 @@ function setCursorPositionTest() {
// } // }
chrome.test.runTests([ chrome.test.runTests([
setCompositionTest, // setCompositionTest,
clearCompositionTest, // clearCompositionTest,
commitTextTest, // commitTextTest,
// setCandidateWindowPropertiesTest, // setCandidateWindowPropertiesTest,
setCandidatesTest, // setCandidatesTest,
setCursorPositionTest, // setCursorPositionTest,
// setMenuItemsTest, // setMenuItemsTest,
// updateMenuItemsTest, // updateMenuItemsTest,
// deleteSurroundingText, // deleteSurroundingText,
......
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