// 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 #include #include "base/json/json_writer.h" #include "base/logging.h" #include "base/string_util.h" #include "base/values.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/profiles/profile.h" #include "third_party/cros/chromeos_cros_api.h" namespace events { const char kOnUpdateAuxiliaryText[] = "experimental.inputUI.onUpdateAuxiliaryText"; const char kOnUpdateLookupTable[] = "experimental.inputUI.onUpdateLookupTable"; const char kOnSetCursorLocation[] = "experimental.inputUI.onSetCursorLocation"; } // namespace events ExtensionInputUiEventRouter* ExtensionInputUiEventRouter::GetInstance() { return Singleton::get(); } ExtensionInputUiEventRouter::ExtensionInputUiEventRouter() : profile_(NULL), ibus_ui_controller_(NULL) { } ExtensionInputUiEventRouter::~ExtensionInputUiEventRouter() { } void ExtensionInputUiEventRouter::Init() { if (ibus_ui_controller_.get() == NULL) { ibus_ui_controller_.reset( chromeos::input_method::IBusUiController::Create()); // The observer should be added before Connect() so we can capture the // initial connection change. ibus_ui_controller_->AddObserver(this); ibus_ui_controller_->Connect(); } } 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"; } ibus_ui_controller_->NotifyCandidateClicked(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"; } ibus_ui_controller_->NotifyCursorUp(); } void ExtensionInputUiEventRouter::CursorDown(Profile* profile, const std::string& extension_id) { if (profile_ != profile || extension_id_ != extension_id) { DLOG(WARNING) << "called from unregistered extension"; } ibus_ui_controller_->NotifyCursorDown(); } void ExtensionInputUiEventRouter::PageUp(Profile* profile, const std::string& extension_id) { if (profile_ != profile || extension_id_ != extension_id) { DLOG(WARNING) << "called from unregistered extension"; } ibus_ui_controller_->NotifyPageUp(); } void ExtensionInputUiEventRouter::PageDown(Profile* profile, const std::string& extension_id) { if (profile_ != profile || extension_id_ != extension_id) { DLOG(WARNING) << "called from unregistered extension"; } ibus_ui_controller_->NotifyPageDown(); } void ExtensionInputUiEventRouter::OnHideAuxiliaryText() { OnUpdateAuxiliaryText("", false); } 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::OnHidePreeditText() { } 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, bool visible) { if (profile_ == NULL || extension_id_.empty()) return; ListValue args; args.Append(Value::CreateStringValue(visible ? 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::input_method::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(); size_t page = lookup_table.cursor_absolute_index / lookup_table.page_size; size_t begin = page * lookup_table.page_size; size_t end = std::min(begin + lookup_table.page_size, lookup_table.candidates.size()); for (size_t i = begin; i < end; 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()); } void ExtensionInputUiEventRouter::OnUpdatePreeditText( const std::string& utf8_text, unsigned int cursor, bool visible) { } void ExtensionInputUiEventRouter::OnConnectionChange(bool connected) { } 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; }