Index: chrome/browser/extensions/extension_input_ui_api.cc |
diff --git a/chrome/browser/extensions/extension_input_ui_api.cc b/chrome/browser/extensions/extension_input_ui_api.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..11f7c14a04a40735be2e6f24b3d5e60b45de5cb7 |
--- /dev/null |
+++ b/chrome/browser/extensions/extension_input_ui_api.cc |
@@ -0,0 +1,351 @@ |
+// Copyright (c) 2011 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 "chrome/browser/extensions/extension_input_ui_api.h" |
+ |
+#include <string> |
+ |
+#include "base/json/json_writer.h" |
+#include "base/logging.h" |
+#include "base/string_util.h" |
+#include "base/values.h" |
+#include "chrome/browser/extensions/extension_event_router.h" |
+#include "chrome/browser/profiles/profile.h" |
+#include "third_party/cros/chromeos_cros_api.h" |
+#include "third_party/cros/chromeos_input_method_ui.h" |
+ |
+namespace events { |
+ |
+const char kOnUpdateAuxiliaryText[] = |
+ "experimental.inputUI.onUpdateAuxiliaryText"; |
+const char kOnUpdateLookupTable[] = "experimental.inputUI.onUpdateLookupTable"; |
+const char kOnSetCursorLocation[] = "experimental.inputUI.onSetCursorLocation"; |
+ |
+} // namespace events |
+ |
+class InputUiController { |
+ public: |
+ explicit InputUiController(ExtensionInputUiEventRouter* router); |
+ ~InputUiController(); |
+ |
+ void CandidateClicked(int index, int button, int flags); |
+ void CursorUp(); |
+ void CursorDown(); |
+ void PageUp(); |
+ void PageDown(); |
+ |
+ private: |
+ // The function is called when |HideAuxiliaryText| signal is received in |
+ // libcros. |ui_controller| is a void pointer to this object. |
+ static void OnHideAuxiliaryText(void* ui_controller); |
+ |
+ // The function is called when |HideLookupTable| signal is received in |
+ // libcros. |ui_controller| is a void pointer to this object. |
+ static void OnHideLookupTable(void* ui_controller); |
+ |
+ // The function is called when |SetCursorLocation| signal is received |
+ // in libcros. |ui_controller| is a void pointer to this object. |
+ static void OnSetCursorLocation(void* ui_controller, |
+ int x, |
+ int y, |
+ int width, |
+ int height); |
+ |
+ // The function is called when |UpdateAuxiliaryText| signal is received |
+ // in libcros. |ui_controller| is a void pointer to this object. |
+ static void OnUpdateAuxiliaryText(void* ui_controller, |
+ const std::string& utf8_text, |
+ bool visible); |
+ |
+ // The function is called when |UpdateLookupTable| signal is received |
+ // in libcros. |ui_controller| is a void pointer to this object. |
+ static void OnUpdateLookupTable(void* ui_controller, |
+ const chromeos::InputMethodLookupTable& lookup_table); |
+ |
+ // This function is called by libcros when ibus connects or disconnects. |
+ // |ui_controller| is a void pointer to this object. |
+ static void OnConnectionChange(void* ui_controller, bool connected); |
+ |
+ ExtensionInputUiEventRouter* router_; |
+ chromeos::InputMethodUiStatusConnection* ui_status_connection_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(InputUiController); |
+}; |
+ |
+InputUiController::InputUiController( |
+ ExtensionInputUiEventRouter* router) : |
+ router_(router), |
+ ui_status_connection_(NULL) { |
+ std::string error; |
+ chromeos::LoadLibcros(NULL, error); |
+ |
+ chromeos::InputMethodUiStatusMonitorFunctions functions; |
+ functions.hide_auxiliary_text = |
+ &InputUiController::OnHideAuxiliaryText; |
+ functions.hide_lookup_table = |
+ &InputUiController::OnHideLookupTable; |
+ functions.set_cursor_location = |
+ &InputUiController::OnSetCursorLocation; |
+ functions.update_auxiliary_text = |
+ &InputUiController::OnUpdateAuxiliaryText; |
+ functions.update_lookup_table = |
+ &InputUiController::OnUpdateLookupTable; |
+ ui_status_connection_ = chromeos::MonitorInputMethodUiStatus(functions, this); |
+ |
+ if (!ui_status_connection_) |
+ LOG(ERROR) << "chromeos::MonitorInputMethodUiStatus() failed!"; |
+} |
+ |
+InputUiController::~InputUiController() { |
+ chromeos::DisconnectInputMethodUiStatus(ui_status_connection_); |
+} |
+ |
+void InputUiController::CandidateClicked( |
+ int index, int button, int flags) { |
+ chromeos::NotifyCandidateClicked(ui_status_connection_, index, button, flags); |
+} |
+ |
+void InputUiController::CursorUp() { |
+ chromeos::NotifyCursorUp(ui_status_connection_); |
+} |
+ |
+void InputUiController::CursorDown() { |
+ chromeos::NotifyCursorDown(ui_status_connection_); |
+} |
+ |
+void InputUiController::PageUp() { |
+ chromeos::NotifyPageUp(ui_status_connection_); |
+} |
+ |
+void InputUiController::PageDown() { |
+ chromeos::NotifyPageDown(ui_status_connection_); |
+} |
+ |
+void InputUiController::OnHideAuxiliaryText( |
+ void* ui_controller) { |
+ InputUiController *self = static_cast<InputUiController*>(ui_controller); |
+ self->router_->OnHideAuxiliaryText(); |
+} |
+ |
+void InputUiController::OnHideLookupTable( |
+ void* ui_controller) { |
+ InputUiController *self = static_cast<InputUiController*>(ui_controller); |
+ self->router_->OnHideLookupTable(); |
+} |
+ |
+void InputUiController::OnSetCursorLocation( |
+ void* ui_controller, |
+ int x, int y, int width, int height) { |
+ InputUiController *self = static_cast<InputUiController*>(ui_controller); |
+ self->router_->OnSetCursorLocation(x, y, width, height); |
+} |
+ |
+void InputUiController::OnUpdateAuxiliaryText( |
+ void* ui_controller, |
+ const std::string& utf8_text, |
+ bool visible) { |
+ InputUiController *self = static_cast<InputUiController*>(ui_controller); |
+ if (!visible) { |
+ self->router_->OnHideAuxiliaryText(); |
+ } else { |
+ self->router_->OnUpdateAuxiliaryText(utf8_text); |
+ } |
+} |
+ |
+void InputUiController::OnUpdateLookupTable( |
+ void* ui_controller, |
+ const chromeos::InputMethodLookupTable& lookup_table) { |
+ InputUiController *self = static_cast<InputUiController*>(ui_controller); |
+ self->router_->OnUpdateLookupTable(lookup_table); |
+} |
+ |
+ExtensionInputUiEventRouter* |
+ExtensionInputUiEventRouter::GetInstance() { |
+ return Singleton<ExtensionInputUiEventRouter>::get(); |
+} |
+ |
+ExtensionInputUiEventRouter::ExtensionInputUiEventRouter() |
+ : profile_(NULL), |
+ ui_controller_(NULL) { |
+} |
+ |
+ExtensionInputUiEventRouter::~ExtensionInputUiEventRouter() { |
+} |
+ |
+void ExtensionInputUiEventRouter::Init() { |
+ if (ui_controller_.get() == NULL) { |
+ ui_controller_.reset(new InputUiController(this)); |
+ } |
+} |
+ |
+void ExtensionInputUiEventRouter::Register( |
+ Profile* profile, const std::string& extension_id) { |
+ profile_ = profile; |
+ extension_id_ = extension_id; |
+} |
+ |
+void ExtensionInputUiEventRouter::CandidateClicked(Profile* profile, |
+ const std::string& extension_id, int index, int button) { |
+ if (profile_ != profile || extension_id_ != extension_id) { |
+ DLOG(WARNING) << "called from unregistered extension"; |
+ } |
+ ui_controller_->CandidateClicked(index, button, 0); |
+} |
+ |
+void ExtensionInputUiEventRouter::CursorUp(Profile* profile, |
+ const std::string& extension_id) { |
+ if (profile_ != profile || extension_id_ != extension_id) { |
+ DLOG(WARNING) << "called from unregistered extension"; |
+ } |
+ ui_controller_->CursorUp(); |
+} |
+ |
+void ExtensionInputUiEventRouter::CursorDown(Profile* profile, |
+ const std::string& extension_id) { |
+ if (profile_ != profile || extension_id_ != extension_id) { |
+ DLOG(WARNING) << "called from unregistered extension"; |
+ } |
+ ui_controller_->CursorDown(); |
+} |
+ |
+void ExtensionInputUiEventRouter::PageUp(Profile* profile, |
+ const std::string& extension_id) { |
+ if (profile_ != profile || extension_id_ != extension_id) { |
+ DLOG(WARNING) << "called from unregistered extension"; |
+ } |
+ ui_controller_->PageUp(); |
+} |
+ |
+void ExtensionInputUiEventRouter::PageDown(Profile* profile, |
+ const std::string& extension_id) { |
+ if (profile_ != profile || extension_id_ != extension_id) { |
+ DLOG(WARNING) << "called from unregistered extension"; |
+ } |
+ ui_controller_->PageDown(); |
+} |
+ |
+void ExtensionInputUiEventRouter::OnHideAuxiliaryText() { |
+ OnUpdateAuxiliaryText(""); |
+} |
+ |
+void ExtensionInputUiEventRouter::OnHideLookupTable() { |
+ if (profile_ == NULL || extension_id_.empty()) |
+ return; |
+ |
+ DictionaryValue* dict = new DictionaryValue(); |
+ dict->SetBoolean("visible", false); |
+ |
+ ListValue *candidates = new ListValue(); |
+ dict->Set("candidates", candidates); |
+ |
+ ListValue args; |
+ args.Append(dict); |
+ |
+ std::string json_args; |
+ base::JSONWriter::Write(&args, false, &json_args); |
+ profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
+ extension_id_, events::kOnUpdateLookupTable, json_args, profile_, GURL()); |
+} |
+ |
+void ExtensionInputUiEventRouter::OnSetCursorLocation( |
+ int x, int y, int width, int height) { |
+ |
+ if (profile_ == NULL || extension_id_.empty()) |
+ return; |
+ |
+ ListValue args; |
+ args.Append(Value::CreateIntegerValue(x)); |
+ args.Append(Value::CreateIntegerValue(y)); |
+ args.Append(Value::CreateIntegerValue(width)); |
+ args.Append(Value::CreateIntegerValue(height)); |
+ |
+ std::string json_args; |
+ base::JSONWriter::Write(&args, false, &json_args); |
+ profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
+ extension_id_, events::kOnSetCursorLocation, json_args, profile_, GURL()); |
+} |
+ |
+void ExtensionInputUiEventRouter::OnUpdateAuxiliaryText( |
+ const std::string& utf8_text) { |
+ if (profile_ == NULL || extension_id_.empty()) |
+ return; |
+ |
+ ListValue args; |
+ args.Append(Value::CreateStringValue(utf8_text)); |
+ |
+ std::string json_args; |
+ base::JSONWriter::Write(&args, false, &json_args); |
+ profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
+ extension_id_, events::kOnUpdateAuxiliaryText, json_args, profile_, GURL()); |
+} |
+ |
+void ExtensionInputUiEventRouter::OnUpdateLookupTable( |
+ const chromeos::InputMethodLookupTable& lookup_table) { |
+ if (profile_ == NULL || extension_id_.empty()) |
+ return; |
+ |
+ DictionaryValue* dict = new DictionaryValue(); |
+ dict->SetBoolean("visible", lookup_table.visible); |
+ |
+ if (lookup_table.visible) { |
+ } |
+ |
+ ListValue *candidates = new ListValue(); |
+ for (size_t i = 0; i < lookup_table.candidates.size(); i++) { |
+ candidates->Append(Value::CreateStringValue(lookup_table.candidates[i])); |
+ } |
+ |
+ dict->Set("candidates", candidates); |
+ |
+ ListValue args; |
+ args.Append(dict); |
+ |
+ std::string json_args; |
+ base::JSONWriter::Write(&args, false, &json_args); |
+ profile_->GetExtensionEventRouter()->DispatchEventToExtension( |
+ extension_id_, events::kOnUpdateLookupTable, json_args, profile_, GURL()); |
+} |
+ |
+bool RegisterInputUiFunction::RunImpl() { |
+ ExtensionInputUiEventRouter::GetInstance()->Register( |
+ profile(), extension_id()); |
+ return true; |
+} |
+ |
+bool CandidateClickedInputUiFunction::RunImpl() { |
+ int index = 0; |
+ int button = 0; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &index)); |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &button)); |
+ |
+ ExtensionInputUiEventRouter::GetInstance()->CandidateClicked( |
+ profile(), extension_id(), index, button); |
+ |
+ return true; |
+} |
+ |
+bool CursorUpInputUiFunction::RunImpl() { |
+ ExtensionInputUiEventRouter::GetInstance()->CursorUp( |
+ profile(), extension_id()); |
+ return true; |
+} |
+ |
+bool CursorDownInputUiFunction::RunImpl() { |
+ ExtensionInputUiEventRouter::GetInstance()->CursorDown( |
+ profile(), extension_id()); |
+ return true; |
+} |
+ |
+bool PageUpInputUiFunction::RunImpl() { |
+ ExtensionInputUiEventRouter::GetInstance()->PageUp( |
+ profile(), extension_id()); |
+ return true; |
+} |
+ |
+bool PageDownInputUiFunction::RunImpl() { |
+ ExtensionInputUiEventRouter::GetInstance()->PageDown( |
+ profile(), extension_id()); |
+ return true; |
+} |
+ |