This source file includes following definitions.
- SendProcessKeyEvent
- GetKeyboardHeightRatio
- DefaultKeyboardBoundsFromWindowBounds
- SetAccessibilityKeyboardEnabled
- GetAccessibilityKeyboardEnabled
- SetTouchKeyboardEnabled
- GetTouchKeyboardEnabled
- GetKeyboardLayout
- IsKeyboardEnabled
- IsKeyboardUsabilityExperimentEnabled
- IsInputViewEnabled
- InsertText
- MoveCursor
- SendKeyEvent
- MarkKeyboardLoadStarted
- MarkKeyboardLoadFinished
- GetKeyboardExtensionResources
- SetOverrideContentUrl
- GetOverrideContentUrl
- LogKeyboardControlEvent
#include "ui/keyboard/keyboard_util.h"
#include <string>
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/strings/string16.h"
#include "grit/keyboard_resources.h"
#include "grit/keyboard_resources_map.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/events/event_processor.h"
#include "ui/keyboard/keyboard_switches.h"
#include "url/gurl.h"
namespace {
const char kKeyDown[] ="keydown";
const char kKeyUp[] = "keyup";
void SendProcessKeyEvent(ui::EventType type,
aura::WindowTreeHost* host) {
ui::TranslatedKeyEvent event(type == ui::ET_KEY_PRESSED,
ui::VKEY_PROCESSKEY,
ui::EF_NONE);
ui::EventDispatchDetails details =
host->event_processor()->OnEventFromSource(&event);
CHECK(!details.dispatcher_destroyed);
}
base::LazyInstance<base::Time> g_keyboard_load_time_start =
LAZY_INSTANCE_INITIALIZER;
bool g_accessibility_keyboard_enabled = false;
base::LazyInstance<GURL> g_override_content_url = LAZY_INSTANCE_INITIALIZER;
const float kUsabilityKeyboardHeightRatio = 1.0f;
const float kDefaultKeyboardHeightRatio = 0.41f;
const float kAccessibilityKeyboardHeightRatio = 0.3f;
float GetKeyboardHeightRatio(){
if (keyboard::IsKeyboardUsabilityExperimentEnabled()) {
return kUsabilityKeyboardHeightRatio;
} else if (keyboard::GetAccessibilityKeyboardEnabled()) {
return kAccessibilityKeyboardHeightRatio;
}
return kDefaultKeyboardHeightRatio;
}
bool g_touch_keyboard_enabled = false;
}
namespace keyboard {
gfx::Rect DefaultKeyboardBoundsFromWindowBounds(
const gfx::Rect& window_bounds) {
const float kKeyboardHeightRatio = GetKeyboardHeightRatio();
return gfx::Rect(
window_bounds.x(),
window_bounds.y() + window_bounds.height() * (1 - kKeyboardHeightRatio),
window_bounds.width(),
window_bounds.height() * kKeyboardHeightRatio);
}
void SetAccessibilityKeyboardEnabled(bool enabled) {
g_accessibility_keyboard_enabled = enabled;
}
bool GetAccessibilityKeyboardEnabled() {
return g_accessibility_keyboard_enabled;
}
void SetTouchKeyboardEnabled(bool enabled) {
g_touch_keyboard_enabled = enabled;
}
bool GetTouchKeyboardEnabled() {
return g_touch_keyboard_enabled;
}
std::string GetKeyboardLayout() {
return GetAccessibilityKeyboardEnabled() ? "system-qwerty" : "qwerty";
}
bool IsKeyboardEnabled() {
return g_accessibility_keyboard_enabled ||
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVirtualKeyboard) ||
IsKeyboardUsabilityExperimentEnabled() ||
g_touch_keyboard_enabled;
}
bool IsKeyboardUsabilityExperimentEnabled() {
return CommandLine::ForCurrentProcess()->HasSwitch(
switches::kKeyboardUsabilityExperiment);
}
bool IsInputViewEnabled() {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableInputView))
return true;
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInputView))
return false;
return false;
}
bool InsertText(const base::string16& text, aura::Window* root_window) {
if (!root_window)
return false;
ui::InputMethod* input_method = root_window->GetProperty(
aura::client::kRootWindowInputMethodKey);
if (!input_method)
return false;
ui::TextInputClient* tic = input_method->GetTextInputClient();
if (!tic || tic->GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
return false;
tic->InsertText(text);
return true;
}
bool MoveCursor(int swipe_direction,
int modifier_flags,
aura::WindowTreeHost* host) {
if (!host)
return false;
ui::KeyboardCode codex = ui::VKEY_UNKNOWN;
ui::KeyboardCode codey = ui::VKEY_UNKNOWN;
if (swipe_direction & kCursorMoveRight)
codex = ui::VKEY_RIGHT;
else if (swipe_direction & kCursorMoveLeft)
codex = ui::VKEY_LEFT;
if (swipe_direction & kCursorMoveUp)
codey = ui::VKEY_UP;
else if (swipe_direction & kCursorMoveDown)
codey = ui::VKEY_DOWN;
if (codex != ui::VKEY_UNKNOWN) {
ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codex, modifier_flags, 0);
ui::EventDispatchDetails details =
host->event_processor()->OnEventFromSource(&press_event);
CHECK(!details.dispatcher_destroyed);
ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codex, modifier_flags, 0);
details = host->event_processor()->OnEventFromSource(&release_event);
CHECK(!details.dispatcher_destroyed);
}
if (codey != ui::VKEY_UNKNOWN) {
ui::KeyEvent press_event(ui::ET_KEY_PRESSED, codey, modifier_flags, 0);
ui::EventDispatchDetails details =
host->event_processor()->OnEventFromSource(&press_event);
CHECK(!details.dispatcher_destroyed);
ui::KeyEvent release_event(ui::ET_KEY_RELEASED, codey, modifier_flags, 0);
details = host->event_processor()->OnEventFromSource(&release_event);
CHECK(!details.dispatcher_destroyed);
}
return true;
}
bool SendKeyEvent(const std::string type,
int key_value,
int key_code,
std::string key_name,
int modifiers,
aura::WindowTreeHost* host) {
ui::EventType event_type = ui::ET_UNKNOWN;
if (type == kKeyDown)
event_type = ui::ET_KEY_PRESSED;
else if (type == kKeyUp)
event_type = ui::ET_KEY_RELEASED;
if (event_type == ui::ET_UNKNOWN)
return false;
ui::KeyboardCode code = static_cast<ui::KeyboardCode>(key_code);
if (code == ui::VKEY_UNKNOWN) {
if (event_type == ui::ET_KEY_RELEASED) {
ui::InputMethod* input_method = host->window()->GetProperty(
aura::client::kRootWindowInputMethodKey);
if (!input_method)
return false;
ui::TextInputClient* tic = input_method->GetTextInputClient();
SendProcessKeyEvent(ui::ET_KEY_PRESSED, host);
tic->InsertChar(static_cast<uint16>(key_value), ui::EF_NONE);
SendProcessKeyEvent(ui::ET_KEY_RELEASED, host);
}
} else {
if (event_type == ui::ET_KEY_RELEASED) {
static int keys_seen = 0;
if (code == ui::VKEY_BACK) {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"VirtualKeyboard.KeystrokesBetweenBackspaces",
keys_seen, 1, 1000, 50);
keys_seen = 0;
} else {
++keys_seen;
}
}
ui::KeyEvent event(event_type, code, key_name, modifiers, false);
ui::EventDispatchDetails details =
host->event_processor()->OnEventFromSource(&event);
CHECK(!details.dispatcher_destroyed);
}
return true;
}
const void MarkKeyboardLoadStarted() {
if (!g_keyboard_load_time_start.Get().ToInternalValue())
g_keyboard_load_time_start.Get() = base::Time::Now();
}
const void MarkKeyboardLoadFinished() {
if (!g_keyboard_load_time_start.Get().ToInternalValue())
return;
DCHECK(g_keyboard_load_time_start.Get().ToInternalValue());
static bool logged = false;
if (!logged) {
UMA_HISTOGRAM_TIMES(
"VirtualKeyboard.FirstLoadTime",
base::Time::Now() - g_keyboard_load_time_start.Get());
logged = true;
}
}
const GritResourceMap* GetKeyboardExtensionResources(size_t* size) {
static const GritResourceMap kKeyboardResources[] = {
{"keyboard/layouts/function-key-row.html", IDR_KEYBOARD_FUNCTION_KEY_ROW},
{"keyboard/images/back.svg", IDR_KEYBOARD_IMAGES_BACK},
{"keyboard/images/backspace.svg", IDR_KEYBOARD_IMAGES_BACKSPACE},
{"keyboard/images/brightness-down.svg",
IDR_KEYBOARD_IMAGES_BRIGHTNESS_DOWN},
{"keyboard/images/brightness-up.svg", IDR_KEYBOARD_IMAGES_BRIGHTNESS_UP},
{"keyboard/images/change-window.svg", IDR_KEYBOARD_IMAGES_CHANGE_WINDOW},
{"keyboard/images/down.svg", IDR_KEYBOARD_IMAGES_DOWN},
{"keyboard/images/forward.svg", IDR_KEYBOARD_IMAGES_FORWARD},
{"keyboard/images/fullscreen.svg", IDR_KEYBOARD_IMAGES_FULLSCREEN},
{"keyboard/images/hide-keyboard.svg", IDR_KEYBOARD_IMAGES_HIDE_KEYBOARD},
{"keyboard/images/keyboard.svg", IDR_KEYBOARD_IMAGES_KEYBOARD},
{"keyboard/images/left.svg", IDR_KEYBOARD_IMAGES_LEFT},
{"keyboard/images/microphone.svg", IDR_KEYBOARD_IMAGES_MICROPHONE},
{"keyboard/images/microphone-green.svg",
IDR_KEYBOARD_IMAGES_MICROPHONE_GREEN},
{"keyboard/images/mute.svg", IDR_KEYBOARD_IMAGES_MUTE},
{"keyboard/images/reload.svg", IDR_KEYBOARD_IMAGES_RELOAD},
{"keyboard/images/return.svg", IDR_KEYBOARD_IMAGES_RETURN},
{"keyboard/images/right.svg", IDR_KEYBOARD_IMAGES_RIGHT},
{"keyboard/images/search.svg", IDR_KEYBOARD_IMAGES_SEARCH},
{"keyboard/images/shift.svg", IDR_KEYBOARD_IMAGES_SHIFT},
{"keyboard/images/shift-filled.svg", IDR_KEYBOARD_IMAGES_SHIFT_FILLED},
{"keyboard/images/shutdown.svg", IDR_KEYBOARD_IMAGES_SHUTDOWN},
{"keyboard/images/tab.svg", IDR_KEYBOARD_IMAGES_TAB},
{"keyboard/images/up.svg", IDR_KEYBOARD_IMAGES_UP},
{"keyboard/images/volume-down.svg", IDR_KEYBOARD_IMAGES_VOLUME_DOWN},
{"keyboard/images/volume-up.svg", IDR_KEYBOARD_IMAGES_VOLUME_UP},
{"keyboard/index.html", IDR_KEYBOARD_INDEX},
{"keyboard/keyboard.js", IDR_KEYBOARD_JS},
{"keyboard/layouts/numeric.html", IDR_KEYBOARD_LAYOUTS_NUMERIC},
{"keyboard/layouts/qwerty.html", IDR_KEYBOARD_LAYOUTS_QWERTY},
{"keyboard/layouts/system-qwerty.html", IDR_KEYBOARD_LAYOUTS_SYSTEM_QWERTY},
{"keyboard/layouts/spacebar-row.html", IDR_KEYBOARD_SPACEBAR_ROW},
{"keyboard/manifest.json", IDR_KEYBOARD_MANIFEST},
{"keyboard/main.css", IDR_KEYBOARD_MAIN_CSS},
{"keyboard/polymer_loader.js", IDR_KEYBOARD_POLYMER_LOADER},
{"keyboard/roboto_bold.ttf", IDR_KEYBOARD_ROBOTO_BOLD_TTF},
{"keyboard/sounds/keypress-delete.wav",
IDR_KEYBOARD_SOUNDS_KEYPRESS_DELETE},
{"keyboard/sounds/keypress-return.wav",
IDR_KEYBOARD_SOUNDS_KEYPRESS_RETURN},
{"keyboard/sounds/keypress-spacebar.wav",
IDR_KEYBOARD_SOUNDS_KEYPRESS_SPACEBAR},
{"keyboard/sounds/keypress-standard.wav",
IDR_KEYBOARD_SOUNDS_KEYPRESS_STANDARD},
};
static const size_t kKeyboardResourcesSize = arraysize(kKeyboardResources);
*size = kKeyboardResourcesSize;
return kKeyboardResources;
}
void SetOverrideContentUrl(const GURL& url) {
DCHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_UI);
g_override_content_url.Get() = url;
}
const GURL& GetOverrideContentUrl() {
DCHECK_EQ(base::MessageLoop::current()->type(), base::MessageLoop::TYPE_UI);
return g_override_content_url.Get();
}
void LogKeyboardControlEvent(KeyboardControlEvent event) {
UMA_HISTOGRAM_ENUMERATION(
"VirtualKeyboard.KeyboardControlEvent",
event,
keyboard::KEYBOARD_CONTROL_MAX);
}
}