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

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: Fix build failure. 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 } 501 }
506 502
507 ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING; 503 ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING;
508 ibus_daemon_address_ = base::StringPrintf( 504 ibus_daemon_address_ = base::StringPrintf(
509 "unix:abstract=ibus-%d", 505 "unix:abstract=ibus-%d",
510 base::RandInt(0, std::numeric_limits<int>::max())); 506 base::RandInt(0, std::numeric_limits<int>::max()));
511 507
512 // Set up ibus-daemon address file watcher before launching ibus-daemon, 508 // Set up ibus-daemon address file watcher before launching ibus-daemon,
513 // because if watcher starts after ibus-daemon, we may miss the ibus 509 // because if watcher starts after ibus-daemon, we may miss the ibus
514 // connection initialization. 510 // connection initialization.
515 bool success = content::BrowserThread::PostTaskAndReply( 511
516 content::BrowserThread::FILE, 512 // Create a callback to bounce from the worker thread to the default thread.
513 base::Callback<void(const std::string&)> callback(base::Bind(
514 &IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback,
515 weak_ptr_factory_.GetWeakPtr()));
516
517 bool success = worker_task_runner_->PostTaskAndReply(
517 FROM_HERE, 518 FROM_HERE,
518 base::Bind(&IBusAddressWatcher::Start, 519 base::Bind(&IBusAddressWatcher::Start, ibus_daemon_address_, callback),
519 ibus_daemon_address_,
520 base::Unretained(this)),
521 base::Bind(&IBusControllerImpl::LaunchIBusDaemon, 520 base::Bind(&IBusControllerImpl::LaunchIBusDaemon,
522 weak_ptr_factory_.GetWeakPtr(), 521 weak_ptr_factory_.GetWeakPtr(),
523 ibus_daemon_address_)); 522 ibus_daemon_address_));
524 DCHECK(success); 523 DCHECK(success);
525 return true; 524 return true;
526 } 525 }
527 526
528 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) { 527 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) {
529 DCHECK_EQ(base::kNullProcessHandle, process_handle_); 528 DCHECK_EQ(base::kNullProcessHandle, process_handle_);
530 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; 529 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 } 577 }
579 578
580 void IBusControllerImpl::OnIBusConfigClientInitialized() { 579 void IBusControllerImpl::OnIBusConfigClientInitialized() {
581 InputMethodConfigRequests::const_iterator iter = 580 InputMethodConfigRequests::const_iterator iter =
582 current_config_values_.begin(); 581 current_config_values_.begin();
583 for (; iter != current_config_values_.end(); ++iter) { 582 for (; iter != current_config_values_.end(); ++iter) {
584 SetInputMethodConfigInternal(iter->first, iter->second); 583 SetInputMethodConfigInternal(iter->first, iter->second);
585 } 584 }
586 } 585 }
587 586
588 // static 587 void IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback(
588 const std::string& ibus_address) {
589 bool result = default_task_runner_->PostTask(FROM_HERE, base::Bind(
590 &IBusControllerImpl::IBusDaemonInitializationDone,
591 weak_ptr_factory_.GetWeakPtr(),
592 ibus_address));
593 DCHECK(result);
594 }
595
589 void IBusControllerImpl::IBusDaemonInitializationDone( 596 void IBusControllerImpl::IBusDaemonInitializationDone(
590 IBusControllerImpl* controller,
591 const std::string& ibus_address) { 597 const std::string& ibus_address) {
592 if (controller->ibus_daemon_address_ != ibus_address) 598 if (ibus_daemon_address_ != ibus_address)
593 return; 599 return;
594 600
595 if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { 601 if (ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) {
596 // Stop() or OnIBusDaemonExit() has already been called. 602 // Stop() or OnIBusDaemonExit() has already been called.
597 return; 603 return;
598 } 604 }
599 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address); 605 chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address);
600 controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING; 606 ibus_daemon_status_ = IBUS_DAEMON_RUNNING;
601 607
602 ui::InputMethodIBus* input_method_ibus = controller->GetInputMethod(); 608 ui::InputMethodIBus* input_method_ibus = GetInputMethod();
603 DCHECK(input_method_ibus); 609 DCHECK(input_method_ibus);
604 input_method_ibus->OnConnected(); 610 input_method_ibus->OnConnected();
605 611
606 DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler( 612 DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler(this);
607 controller);
608 613
609 // Restore previous input method at the beggining of connection. 614 // Restore previous input method at the beggining of connection.
610 if (!controller->current_input_method_id_.empty()) { 615 if (!current_input_method_id_.empty())
611 controller->SendChangeInputMethodRequest( 616 SendChangeInputMethodRequest(current_input_method_id_);
612 controller->current_input_method_id_);
613 }
614 617
615 DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync( 618 DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync(
616 base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized, 619 base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized,
617 controller->weak_ptr_factory_.GetWeakPtr())); 620 weak_ptr_factory_.GetWeakPtr()));
618 621
619 FOR_EACH_OBSERVER(Observer, controller->observers_, OnConnected()); 622 FOR_EACH_OBSERVER(Observer, observers_, OnConnected());
620 623
621 VLOG(1) << "The ibus-daemon initialization is done."; 624 VLOG(1) << "The ibus-daemon initialization is done.";
622 } 625 }
623 626
624 // static 627 // static
625 void IBusControllerImpl::OnIBusDaemonExit(GPid pid, 628 void IBusControllerImpl::OnIBusDaemonExit(GPid pid,
626 gint status, 629 gint status,
627 IBusControllerImpl* controller) { 630 IBusControllerImpl* controller) {
628 if (controller->process_handle_ != base::kNullProcessHandle) { 631 if (controller->process_handle_ != base::kNullProcessHandle) {
629 if (base::GetProcId(controller->process_handle_) == pid) { 632 if (base::GetProcId(controller->process_handle_) == pid) {
(...skipping 30 matching lines...) Expand all
660 663
661 // static 664 // static
662 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( 665 bool IBusControllerImpl::FindAndUpdatePropertyForTesting(
663 const chromeos::input_method::InputMethodProperty& new_prop, 666 const chromeos::input_method::InputMethodProperty& new_prop,
664 chromeos::input_method::InputMethodPropertyList* prop_list) { 667 chromeos::input_method::InputMethodPropertyList* prop_list) {
665 return FindAndUpdateProperty(new_prop, prop_list); 668 return FindAndUpdateProperty(new_prop, prop_list);
666 } 669 }
667 670
668 } // namespace input_method 671 } // namespace input_method
669 } // namespace chromeos 672 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698