blob: 0b86a0c24457a68c08d55534e7ce6c29ad9a8e40 [file] [log] [blame]
// 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 <algorithm>
#include <string>
#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<ExtensionInputUiEventRouter>::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;
}