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

Side by Side Diff: chrome/browser/chromeos/input_method/ibus_controller_impl.cc

Issue 11558017: Decouple input_method from BrowserThread (and content/). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/input_method/ibus_controller_impl.h" 5 #include "chrome/browser/chromeos/input_method/ibus_controller_impl.h"
6 6
7 #include <algorithm> // for std::reverse. 7 #include <algorithm> // for std::reverse.
8 #include <cstdio> 8 #include <cstdio>
9 #include <cstring> // for std::strcmp. 9 #include <cstring> // for std::strcmp.
10 #include <set> 10 #include <set>
11 #include <sstream> 11 #include <sstream>
12 #include <stack> 12 #include <stack>
13 #include <utility> 13 #include <utility>
14 14
15 #include "ash/shell.h" 15 #include "ash/shell.h"
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/environment.h" 17 #include "base/environment.h"
18 #include "base/files/file_path_watcher.h" 18 #include "base/files/file_path_watcher.h"
19 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
20 #include "base/message_loop.h" 20 #include "base/message_loop.h"
21 #include "base/rand_util.h" 21 #include "base/rand_util.h"
22 #include "base/sequenced_task_runner.h"
22 #include "base/string_split.h" 23 #include "base/string_split.h"
23 #include "base/stringprintf.h" 24 #include "base/stringprintf.h"
24 #include "chrome/browser/chromeos/input_method/input_method_config.h" 25 #include "chrome/browser/chromeos/input_method/input_method_config.h"
25 #include "chrome/browser/chromeos/input_method/input_method_property.h" 26 #include "chrome/browser/chromeos/input_method/input_method_property.h"
26 #include "chrome/browser/chromeos/input_method/input_method_util.h" 27 #include "chrome/browser/chromeos/input_method/input_method_util.h"
27 #include "chromeos/dbus/dbus_thread_manager.h" 28 #include "chromeos/dbus/dbus_thread_manager.h"
28 #include "chromeos/dbus/ibus/ibus_client.h" 29 #include "chromeos/dbus/ibus/ibus_client.h"
29 #include "chromeos/dbus/ibus/ibus_config_client.h" 30 #include "chromeos/dbus/ibus/ibus_config_client.h"
30 #include "chromeos/dbus/ibus/ibus_constants.h" 31 #include "chromeos/dbus/ibus/ibus_constants.h"
31 #include "chromeos/dbus/ibus/ibus_input_context_client.h" 32 #include "chromeos/dbus/ibus/ibus_input_context_client.h"
32 #include "chromeos/dbus/ibus/ibus_panel_service.h" 33 #include "chromeos/dbus/ibus/ibus_panel_service.h"
33 #include "chromeos/dbus/ibus/ibus_property.h" 34 #include "chromeos/dbus/ibus/ibus_property.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "ui/aura/client/aura_constants.h" 35 #include "ui/aura/client/aura_constants.h"
36 #include "ui/aura/root_window.h" 36 #include "ui/aura/root_window.h"
37 #include "ui/base/ime/input_method_ibus.h" 37 #include "ui/base/ime/input_method_ibus.h"
38 38
39 namespace { 39 namespace {
40 40
41 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the 41 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the
42 // property with |new_prop|. Returns true if such a property is found. 42 // property with |new_prop|. Returns true if such a property is found.
43 bool FindAndUpdateProperty( 43 bool FindAndUpdateProperty(
44 const chromeos::input_method::InputMethodProperty& new_prop, 44 const chromeos::input_method::InputMethodProperty& new_prop,
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return result; 186 return result;
187 } 187 }
188 188
189 class IBusAddressWatcher { 189 class IBusAddressWatcher {
190 public: 190 public:
191 class IBusAddressFileWatcherDelegate 191 class IBusAddressFileWatcherDelegate
192 : public base::files::FilePathWatcher::Delegate { 192 : public base::files::FilePathWatcher::Delegate {
193 public: 193 public:
194 IBusAddressFileWatcherDelegate( 194 IBusAddressFileWatcherDelegate(
195 const std::string& ibus_address, 195 const std::string& ibus_address,
196 IBusControllerImpl* controller, 196 const base::Callback<void(const std::string&)>& callback,
197 IBusAddressWatcher* watcher) 197 IBusAddressWatcher* watcher)
198 : ibus_address_(ibus_address), 198 : ibus_address_(ibus_address),
199 controller_(controller), 199 callback_(callback),
200 watcher_(watcher) { 200 watcher_(watcher) {
201 DCHECK(watcher); 201 DCHECK(watcher);
202 DCHECK(!ibus_address.empty()); 202 DCHECK(!ibus_address.empty());
203 } 203 }
204 204
205 virtual void OnFilePathChanged(const FilePath& file_path) OVERRIDE { 205 virtual void OnFilePathChanged(const FilePath& file_path) OVERRIDE {
206 if (!watcher_->IsWatching()) 206 if (!watcher_->IsWatching())
207 return; 207 return;
208 bool success = content::BrowserThread::PostTask( 208 callback_.Run(ibus_address_);
209 content::BrowserThread::UI,
210 FROM_HERE,
211 base::Bind(
212 &IBusControllerImpl::IBusDaemonInitializationDone,
213 controller_,
214 ibus_address_));
215 DCHECK(success);
216 watcher_->StopSoon(); 209 watcher_->StopSoon();
217 } 210 }
218 211
219 protected: 212 protected:
220 virtual ~IBusAddressFileWatcherDelegate() {} 213 virtual ~IBusAddressFileWatcherDelegate() {}
221 214
222 private: 215 private:
223 // The ibus-daemon address. 216 // The ibus-daemon address.
224 const std::string ibus_address_; 217 const std::string ibus_address_;
225 IBusControllerImpl* controller_; 218 base::Callback<void(const std::string&)> callback_;
226 IBusAddressWatcher* watcher_; 219 IBusAddressWatcher* watcher_;
227 220
228 DISALLOW_COPY_AND_ASSIGN(IBusAddressFileWatcherDelegate); 221 DISALLOW_COPY_AND_ASSIGN(IBusAddressFileWatcherDelegate);
229 }; 222 };
230 223
231 static void Start(const std::string& ibus_address, 224 static void Start(const std::string& ibus_address,
232 IBusControllerImpl* controller) { 225 const base::Callback<void(const std::string&)>& callback) {
233 IBusAddressWatcher* instance = IBusAddressWatcher::Get(); 226 IBusAddressWatcher* instance = IBusAddressWatcher::Get();
234 scoped_ptr<base::Environment> env(base::Environment::Create()); 227 scoped_ptr<base::Environment> env(base::Environment::Create());
235 std::string address_file_path; 228 std::string address_file_path;
236 // TODO(nona): move reading environment variables to UI thread. 229 // TODO(nona): move reading environment variables to UI thread.
237 env->GetVar("IBUS_ADDRESS_FILE", &address_file_path); 230 env->GetVar("IBUS_ADDRESS_FILE", &address_file_path);
238 DCHECK(!address_file_path.empty()); 231 DCHECK(!address_file_path.empty());
239 232
240 if (instance->IsWatching()) 233 if (instance->IsWatching())
241 instance->StopNow(); 234 instance->StopNow();
242 instance->watcher_ = new base::files::FilePathWatcher; 235 instance->watcher_ = new base::files::FilePathWatcher;
243 236
244 // The |delegate| is owned by watcher. 237 // The |delegate| is owned by watcher.
245 IBusAddressFileWatcherDelegate* delegate = 238 IBusAddressFileWatcherDelegate* delegate =
246 new IBusAddressFileWatcherDelegate(ibus_address, controller, instance); 239 new IBusAddressFileWatcherDelegate(ibus_address, callback, instance);
247 bool result = instance->watcher_->Watch(FilePath(address_file_path), 240 bool result = instance->watcher_->Watch(FilePath(address_file_path),
248 delegate); 241 delegate);
249 DCHECK(result); 242 DCHECK(result);
250 } 243 }
251 244
252 void StopNow() { 245 void StopNow() {
253 delete watcher_; 246 delete watcher_;
254 watcher_ = NULL; 247 watcher_ = NULL;
255 } 248 }
256 249
257 void StopSoon() { 250 void StopSoon() {
258 if (!watcher_) 251 if (!watcher_)
259 return; 252 return;
260 MessageLoop::current()->DeleteSoon(FROM_HERE, watcher_); 253 MessageLoop::current()->DeleteSoon(FROM_HERE, watcher_);
261 watcher_ = NULL; 254 watcher_ = NULL;
262 } 255 }
263 256
264 bool IsWatching() const { 257 bool IsWatching() const {
265 return watcher_ != NULL; 258 return watcher_ != NULL;
266 } 259 }
267 260
268 private: 261 private:
269 static IBusAddressWatcher* Get() { 262 static IBusAddressWatcher* Get() {
270 static IBusAddressWatcher* instance = new IBusAddressWatcher; 263 static IBusAddressWatcher* instance = new IBusAddressWatcher;
271 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
272 return instance; 264 return instance;
273 } 265 }
274 266
275 // Singleton 267 // Singleton
276 IBusAddressWatcher() 268 IBusAddressWatcher()
277 : watcher_(NULL) {} 269 : watcher_(NULL) {}
278 base::files::FilePathWatcher* watcher_; 270 base::files::FilePathWatcher* watcher_;
279 271
280 DISALLOW_COPY_AND_ASSIGN(IBusAddressWatcher); 272 DISALLOW_COPY_AND_ASSIGN(IBusAddressWatcher);
281 }; 273 };
282 274
283 } // namespace 275 } // namespace
284 276
285 IBusControllerImpl::IBusControllerImpl() 277 IBusControllerImpl::IBusControllerImpl(
278 const scoped_refptr<base::SequencedTaskRunner>& default_task_runner,
279 const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner)
286 : process_handle_(base::kNullProcessHandle), 280 : process_handle_(base::kNullProcessHandle),
287 ibus_daemon_status_(IBUS_DAEMON_STOP), 281 ibus_daemon_status_(IBUS_DAEMON_STOP),
288 input_method_(NULL), 282 input_method_(NULL),
283 default_task_runner_(default_task_runner),
284 worker_task_runner_(worker_task_runner),
289 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 285 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
290 } 286 }
291 287
292 IBusControllerImpl::~IBusControllerImpl() { 288 IBusControllerImpl::~IBusControllerImpl() {
293 } 289 }
294 290
295 bool IBusControllerImpl::Start() { 291 bool IBusControllerImpl::Start() {
296 if (IBusConnectionsAreAlive()) 292 if (IBusConnectionsAreAlive())
297 return true; 293 return true;
298 if (ibus_daemon_status_ == IBUS_DAEMON_STOP || 294 if (ibus_daemon_status_ == IBUS_DAEMON_STOP ||
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 } 490 }
495 491
496 ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING; 492 ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING;
497 ibus_daemon_address_ = base::StringPrintf( 493 ibus_daemon_address_ = base::StringPrintf(
498 "unix:abstract=ibus-%d", 494 "unix:abstract=ibus-%d",
499 base::RandInt(0, std::numeric_limits<int>::max())); 495 base::RandInt(0, std::numeric_limits<int>::max()));
500 496
501 // Set up ibus-daemon address file watcher before launching ibus-daemon, 497 // Set up ibus-daemon address file watcher before launching ibus-daemon,
502 // because if watcher starts after ibus-daemon, we may miss the ibus 498 // because if watcher starts after ibus-daemon, we may miss the ibus
503 // connection initialization. 499 // connection initialization.
504 bool success = content::BrowserThread::PostTaskAndReply( 500
505 content::BrowserThread::FILE, 501 // Create a callback to bounce from the worker thread to the default thread.
502 base::Callback<void(const std::string&)> callback(base::Bind(
503 &IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback,
504 weak_ptr_factory_.GetWeakPtr()));
505
506 bool success = worker_task_runner_->PostTaskAndReply(
506 FROM_HERE, 507 FROM_HERE,
507 base::Bind(&IBusAddressWatcher::Start, 508 base::Bind(&IBusAddressWatcher::Start, ibus_daemon_address_, callback),
508 ibus_daemon_address_,
509 base::Unretained(this)),
510 base::Bind(&IBusControllerImpl::LaunchIBusDaemon, 509 base::Bind(&IBusControllerImpl::LaunchIBusDaemon,
511 weak_ptr_factory_.GetWeakPtr(), 510 weak_ptr_factory_.GetWeakPtr(),
512 ibus_daemon_address_)); 511 ibus_daemon_address_));
513 DCHECK(success); 512 DCHECK(success);
514 return true; 513 return true;
515 } 514 }
516 515
517 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) { 516 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) {
518 DCHECK_EQ(base::kNullProcessHandle, process_handle_); 517 DCHECK_EQ(base::kNullProcessHandle, process_handle_);
519 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; 518 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 } 566 }
568 567
569 void IBusControllerImpl::OnIBusConfigClientInitialized() { 568 void IBusControllerImpl::OnIBusConfigClientInitialized() {
570 InputMethodConfigRequests::const_iterator iter = 569 InputMethodConfigRequests::const_iterator iter =
571 current_config_values_.begin(); 570 current_config_values_.begin();
572 for (; iter != current_config_values_.end(); ++iter) { 571 for (; iter != current_config_values_.end(); ++iter) {
573 SetInputMethodConfigInternal(iter->first, iter->second); 572 SetInputMethodConfigInternal(iter->first, iter->second);
574 } 573 }
575 } 574 }
576 575
577 // static 576 void IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback(
577 const std::string& ibus_address) {
578 bool result = default_task_runner_->PostTask(FROM_HERE, base::Bind(
579 &IBusControllerImpl::IBusDaemonInitializationDone,
580 weak_ptr_factory_.GetWeakPtr(),
581 ibus_address));
582 DCHECK(result);
583 }
584
578 void IBusControllerImpl::IBusDaemonInitializationDone( 585 void IBusControllerImpl::IBusDaemonInitializationDone(
579 IBusControllerImpl* controller,
580 const std::string& ibus_address) { 586 const std::string& ibus_address) {
581 if (controller->ibus_daemon_address_ != ibus_address) 587 if (ibus_daemon_address_ != ibus_address)
582 return; 588 return;
583 589
584 if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { 590 if (ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) {
585 // Stop() or OnIBusDaemonExit() has already been called. 591 // Stop() or OnIBusDaemonExit() has already been called.
586 return; 592 return;
587 } 593 }
588 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address); 594 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address);
589 controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING; 595 ibus_daemon_status_ = IBUS_DAEMON_RUNNING;
590 596
591 ui::InputMethodIBus* input_method_ibus = controller->GetInputMethod(); 597 ui::InputMethodIBus* input_method_ibus = GetInputMethod();
592 DCHECK(input_method_ibus); 598 DCHECK(input_method_ibus);
593 input_method_ibus->OnConnected(); 599 input_method_ibus->OnConnected();
594 600
595 DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler( 601 DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler(this);
596 controller);
597 602
598 // Restore previous input method at the beggining of connection. 603 // Restore previous input method at the beggining of connection.
599 if (!controller->current_input_method_id_.empty()) { 604 if (!current_input_method_id_.empty())
600 controller->SendChangeInputMethodRequest( 605 SendChangeInputMethodRequest(current_input_method_id_);
601 controller->current_input_method_id_);
602 }
603 606
604 DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync( 607 DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync(
605 base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized, 608 base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized,
606 controller->weak_ptr_factory_.GetWeakPtr())); 609 weak_ptr_factory_.GetWeakPtr()));
607 610
608 FOR_EACH_OBSERVER(Observer, controller->observers_, OnConnected()); 611 FOR_EACH_OBSERVER(Observer, observers_, OnConnected());
609 612
610 VLOG(1) << "The ibus-daemon initialization is done."; 613 VLOG(1) << "The ibus-daemon initialization is done.";
611 } 614 }
612 615
613 // static 616 // static
614 void IBusControllerImpl::OnIBusDaemonExit(GPid pid, 617 void IBusControllerImpl::OnIBusDaemonExit(GPid pid,
615 gint status, 618 gint status,
616 IBusControllerImpl* controller) { 619 IBusControllerImpl* controller) {
617 if (controller->process_handle_ != base::kNullProcessHandle) { 620 if (controller->process_handle_ != base::kNullProcessHandle) {
618 if (base::GetProcId(controller->process_handle_) == pid) { 621 if (base::GetProcId(controller->process_handle_) == pid) {
(...skipping 30 matching lines...) Expand all
649 652
650 // static 653 // static
651 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( 654 bool IBusControllerImpl::FindAndUpdatePropertyForTesting(
652 const chromeos::input_method::InputMethodProperty& new_prop, 655 const chromeos::input_method::InputMethodProperty& new_prop,
653 chromeos::input_method::InputMethodPropertyList* prop_list) { 656 chromeos::input_method::InputMethodPropertyList* prop_list) {
654 return FindAndUpdateProperty(new_prop, prop_list); 657 return FindAndUpdateProperty(new_prop, prop_list);
655 } 658 }
656 659
657 } // namespace input_method 660 } // namespace input_method
658 } // namespace chromeos 661 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698