Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc

Issue 1528483002: Add chrome.input.ime.activate and chrome.input.ime.deactivate API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file is for non-chromeos (win & linux) functions, such as 5 // This file is for non-chromeos (win & linux) functions, such as
6 // chrome.input.ime.activate, chrome.input.ime.createWindow and 6 // chrome.input.ime.activate, chrome.input.ime.createWindow and
7 // chrome.input.ime.onSelectionChanged. 7 // chrome.input.ime.onSelectionChanged.
8 // TODO(azurewei): May refactor the code structure by using delegate or 8 // TODO(azurewei): May refactor the code structure by using delegate or
9 // redesign the API to remove this platform-specific file in the future. 9 // redesign the API to remove this platform-specific file in the future.
10 10
11 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h" 11 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "chrome/browser/input_method/input_method_engine.h"
15 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
17 #include "ui/base/ime/ime_bridge.h"
18
19 using ui::IMEEngineHandlerInterface;
20 using input_method::InputMethodEngine;
21 using input_method::InputMethodEngineBase;
16 22
17 namespace { 23 namespace {
18 24
25 const char kErrorAPIDisabled[] =
26 "The chrome.input.ime API is not supported on the current platform";
27
19 bool IsInputImeEnabled() { 28 bool IsInputImeEnabled() {
20 return base::CommandLine::ForCurrentProcess()->HasSwitch( 29 return base::CommandLine::ForCurrentProcess()->HasSwitch(
21 switches::kEnableInputImeAPI); 30 switches::kEnableInputImeAPI);
22 } 31
32 } // namespace
23 33
24 class ImeObserverNonChromeOS : public ui::ImeObserver { 34 class ImeObserverNonChromeOS : public ui::ImeObserver {
25 public: 35 public:
26 ImeObserverNonChromeOS(const std::string& extension_id, Profile* profile) 36 ImeObserverNonChromeOS(const std::string& extension_id, Profile* profile)
27 : ImeObserver(extension_id, profile) {} 37 : ImeObserver(extension_id, profile) {}
28 38
29 ~ImeObserverNonChromeOS() override {} 39 ~ImeObserverNonChromeOS() override {}
30 40
31 private: 41 private:
32 // ImeObserver overrides. 42 // ImeObserver overrides.
33 void DispatchEventToExtension( 43 void DispatchEventToExtension(
34 extensions::events::HistogramValue histogram_value, 44 extensions::events::HistogramValue histogram_value,
35 const std::string& event_name, 45 const std::string& event_name,
36 scoped_ptr<base::ListValue> args) override { 46 scoped_ptr<base::ListValue> args) override {
37 if (!IsInputImeEnabled()) { 47 if (!IsInputImeEnabled()) {
38 return; 48 return;
39 } 49 }
40 50
41 scoped_ptr<extensions::Event> event( 51 scoped_ptr<extensions::Event> event(
42 new extensions::Event(histogram_value, event_name, std::move(args))); 52 new extensions::Event(histogram_value, event_name, std::move(args)));
43 event->restrict_to_browser_context = profile_; 53 event->restrict_to_browser_context = profile_;
44 extensions::EventRouter::Get(profile_) 54 extensions::EventRouter::Get(profile_)
45 ->DispatchEventToExtension(extension_id_, std::move(event)); 55 ->DispatchEventToExtension(extension_id_, std::move(event));
46 } 56 }
47 57
48 std::string GetCurrentScreenType() override { 58 std::string GetCurrentScreenType() override { return "normal"; }
49 return "normal";
50 }
51 59
52 DISALLOW_COPY_AND_ASSIGN(ImeObserverNonChromeOS); 60 DISALLOW_COPY_AND_ASSIGN(ImeObserverNonChromeOS);
53 }; 61 };
54 62
55 } // namespace 63 } // namespace
56 64
57 namespace extensions { 65 namespace extensions {
58 66
59 InputImeEventRouter::InputImeEventRouter(Profile* profile) 67 InputImeEventRouter::InputImeEventRouter(Profile* profile)
60 : InputImeEventRouterBase(profile) {} 68 : InputImeEventRouterBase(profile), active_engine_(nullptr) {}
61 69
62 InputImeEventRouter::~InputImeEventRouter() {} 70 InputImeEventRouter::~InputImeEventRouter() {
71 DeleteInputMethodEngine();
72 }
73
74 bool InputImeEventRouter::RegisterImeExtension(
75 const std::string& extension_id) {
76 // Check if the IME extension is already registered.
77 if (std::find(extension_ids_.begin(), extension_ids_.end(), extension_id) !=
78 extension_ids_.end())
79 return false;
80
81 extension_ids_.push_back(extension_id);
82 return true;
83 }
84
85 void InputImeEventRouter::UnregisterImeExtension(
86 const std::string& extension_id) {
87 std::vector<std::string>::iterator it =
88 std::find(extension_ids_.begin(), extension_ids_.end(), extension_id);
89 if (it != extension_ids_.end()) {
90 if (GetActiveEngine(extension_id))
91 DeleteInputMethodEngine();
92 extension_ids_.erase(it);
93 }
94 }
95
96 InputMethodEngine* InputImeEventRouter::GetActiveEngine(
97 const std::string& extension_id) {
98 return (active_engine_ && active_engine_->GetExtensionId() == extension_id)
99 ? active_engine_
100 : nullptr;
101 }
102
103 void InputImeEventRouter::SetActiveEngine(const std::string& extension_id) {
104 if (active_engine_) {
105 if (active_engine_->GetExtensionId() == extension_id)
106 return;
107 DeleteInputMethodEngine();
108 }
109
110 scoped_ptr<input_method::InputMethodEngine> engine(
111 new input_method::InputMethodEngine());
112 scoped_ptr<InputMethodEngineBase::Observer> observer(
113 new ImeObserverNonChromeOS(extension_id, profile()));
114 engine->Initialize(std::move(observer), extension_id.c_str(), profile());
115 engine->Enable("");
116 active_engine_ = engine.release();
117 ui::IMEBridge::Get()->SetCurrentEngineHandler(active_engine_);
118 }
119
120 void InputImeEventRouter::DeleteInputMethodEngine() {
121 if (active_engine_) {
122 delete active_engine_;
123 active_engine_ = nullptr;
124 ui::IMEBridge::Get()->SetCurrentEngineHandler(nullptr);
Devlin 2016/01/15 22:06:02 I'd prefer this to be the first call so that if Se
Azure Wei 2016/01/19 03:46:54 Done.
125 }
126 }
127
128 ExtensionFunction::ResponseAction InputImeActivateFunction::Run() {
129 if (!IsInputImeEnabled())
130 return RespondNow(Error(kErrorAPIDisabled));
131
132 InputImeEventRouter* event_router =
133 GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()));
134 event_router->RegisterImeExtension(extension_id());
135 event_router->SetActiveEngine(extension_id());
Shu Chen 2016/01/18 09:21:59 RegisterImeExtension & SetActiveEngine are always
Azure Wei 2016/01/19 03:46:54 Done.
136 return RespondNow(NoArguments());
137 }
138
139 ExtensionFunction::ResponseAction InputImeDeactivateFunction::Run() {
140 if (!IsInputImeEnabled())
141 return RespondNow(Error(kErrorAPIDisabled));
142
143 InputImeEventRouter* event_router =
144 GetInputImeEventRouter(Profile::FromBrowserContext(browser_context()));
145 event_router->UnregisterImeExtension(extension_id());
146 return RespondNow(NoArguments());
147 }
63 148
64 void InputImeAPI::OnExtensionLoaded(content::BrowserContext* browser_context, 149 void InputImeAPI::OnExtensionLoaded(content::BrowserContext* browser_context,
65 const Extension* extension) {} 150 const Extension* extension) {
151 // No-op if called multiple times.
152 ui::IMEBridge::Initialize();
153 }
66 154
67 void InputImeAPI::OnExtensionUnloaded(content::BrowserContext* browser_context, 155 void InputImeAPI::OnExtensionUnloaded(content::BrowserContext* browser_context,
68 const Extension* extension, 156 const Extension* extension,
69 UnloadedExtensionInfo::Reason reason) {} 157 UnloadedExtensionInfo::Reason reason) {
158 GetInputImeEventRouter(Profile::FromBrowserContext(browser_context))
159 ->UnregisterImeExtension(extension->id());
160 }
70 161
71 void InputImeAPI::OnListenerAdded(const EventListenerInfo& details) {} 162 void InputImeAPI::OnListenerAdded(const EventListenerInfo& details) {}
72 163
73 } // namespace extensions 164 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698