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

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

Issue 10159004: Extends DBusThreadManager to connect ibus-bus. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix nits Created 8 years, 8 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 (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 "base/bind.h"
16 #include "base/environment.h"
17 #include "base/files/file_path_watcher.h"
15 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop.h"
20 #include "base/rand_util.h"
16 #include "base/stringprintf.h" 21 #include "base/stringprintf.h"
17 #include "base/string_split.h" 22 #include "base/string_split.h"
18 #include "chrome/browser/chromeos/input_method/input_method_config.h" 23 #include "chrome/browser/chromeos/input_method/input_method_config.h"
19 #include "chrome/browser/chromeos/input_method/input_method_property.h" 24 #include "chrome/browser/chromeos/input_method/input_method_property.h"
20 #include "chrome/browser/chromeos/input_method/input_method_util.h" 25 #include "chrome/browser/chromeos/input_method/input_method_util.h"
26 #include "chromeos/dbus/dbus_thread_manager.h"
27 #include "content/public/browser/browser_thread.h"
21 28
22 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests 29 // TODO(nona): Remove libibus dependency from this file. Then, write unit tests
23 // for all functions in this file. crbug.com/26334 30 // for all functions in this file. crbug.com/26334
24 #if defined(HAVE_IBUS) 31 #if defined(HAVE_IBUS)
25 #include <ibus.h> 32 #include <ibus.h>
26 #endif 33 #endif
27 34
28 namespace { 35 namespace {
29 36
30 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the 37 // Finds a property which has |new_prop.key| from |prop_list|, and replaces the
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 std::stringstream stream; 357 std::stringstream stream;
351 for (int i = 0;; ++i) { 358 for (int i = 0;; ++i) {
352 IBusProperty* prop = ibus_prop_list_get(prop_list, i); 359 IBusProperty* prop = ibus_prop_list_get(prop_list, i);
353 if (!prop) 360 if (!prop)
354 break; 361 break;
355 stream << PrintProp(prop, tree_level); 362 stream << PrintProp(prop, tree_level);
356 } 363 }
357 return stream.str(); 364 return stream.str();
358 } 365 }
359 366
367 // The implementation of FilePathWatcher::Delegate, used in
368 // StartAddressFileWatch function.
369 class IBusAddressFileWatcherDelegate
370 : public base::files::FilePathWatcher::Delegate {
371 public:
372 IBusAddressFileWatcherDelegate(const std::string& ibus_address,
373 base::files::FilePathWatcher* watcher)
374 : ibus_address_(ibus_address),
375 watcher_(watcher) {
376 }
377
378 virtual ~IBusAddressFileWatcherDelegate() {}
379
380 virtual void OnFilePathChanged(const FilePath& file_path) {
381 content::BrowserThread::PostTask(
382 content::BrowserThread::UI,
383 FROM_HERE,
384 base::Bind(&chromeos::DBusThreadManager::MaybeResetIBusBus,
385 base::Unretained(chromeos::DBusThreadManager::Get()),
386 ibus_address_));
387 MessageLoop::current()->DeleteSoon(FROM_HERE, watcher_);
388 }
389
390 private:
391
Yusuke Sato 2012/04/26 00:46:28 nit: remove
Seigo Nonaka 2012/04/26 17:40:59 Done.
392 // The ibus-daemon address.
393 std::string ibus_address_;
Yusuke Sato 2012/04/26 00:46:28 nit: const std::string would be better.
Seigo Nonaka 2012/04/26 17:40:59 Done.
394
395 base::files::FilePathWatcher* watcher_;
Yusuke Sato 2012/04/26 00:46:28 nit: vertical space after this line.
Seigo Nonaka 2012/04/26 17:40:59 Done.
396 DISALLOW_COPY_AND_ASSIGN(IBusAddressFileWatcherDelegate);
397 };
398
399 void StartAddressFileWatch(const std::string& ibus_address) {
400 scoped_ptr<base::Environment> env(base::Environment::Create());
401 std::string address_file_path;
402 env->GetVar("IBUS_ADDRESS_FILE", &address_file_path);
403
404 // The |watcher| instance will be released by |delegate|.
405 base::files::FilePathWatcher* watcher = new base::files::FilePathWatcher();
Yusuke Sato 2012/04/26 00:46:28 nit: you can omit '()'.
Seigo Nonaka 2012/04/26 17:40:59 Done.
406
407 // The |delegate| is owned by watcher.
408 IBusAddressFileWatcherDelegate* delegate = new IBusAddressFileWatcherDelegate(
409 ibus_address, watcher);
410 bool result = watcher->Watch(FilePath(address_file_path), delegate);
411 DCHECK(result);
412 }
360 } // namespace 413 } // namespace
361 414
362 IBusControllerImpl::IBusControllerImpl() 415 IBusControllerImpl::IBusControllerImpl()
363 : ibus_(NULL), 416 : ibus_(NULL),
364 ibus_config_(NULL), 417 ibus_config_(NULL),
365 should_launch_daemon_(false), 418 should_launch_daemon_(false),
366 process_handle_(base::kNullProcessHandle) { 419 process_handle_(base::kNullProcessHandle),
420 weak_ptr_factory_(this) {
Yusuke Sato 2012/04/26 00:46:28 ALLOW_THIS_IN_INITIALIZER_LIST?
Seigo Nonaka 2012/04/26 17:40:59 Done.
367 } 421 }
368 422
369 IBusControllerImpl::~IBusControllerImpl() { 423 IBusControllerImpl::~IBusControllerImpl() {
370 // Disconnect signals so the handler functions will not be called with 424 // Disconnect signals so the handler functions will not be called with
371 // |this| which is already freed. 425 // |this| which is already freed.
372 if (ibus_) { 426 if (ibus_) {
373 g_signal_handlers_disconnect_by_func( 427 g_signal_handlers_disconnect_by_func(
374 ibus_, 428 ibus_,
375 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)), 429 reinterpret_cast<gpointer>(G_CALLBACK(BusConnectedThunk)),
376 this); 430 this);
(...skipping 24 matching lines...) Expand all
401 this); 455 this);
402 } 456 }
403 } 457 }
404 } 458 }
405 459
406 bool IBusControllerImpl::Start() { 460 bool IBusControllerImpl::Start() {
407 MaybeInitializeIBusBus(); 461 MaybeInitializeIBusBus();
408 should_launch_daemon_ = true; 462 should_launch_daemon_ = true;
409 if (IBusConnectionsAreAlive()) 463 if (IBusConnectionsAreAlive())
410 return true; 464 return true;
465
Yusuke Sato 2012/04/26 00:46:28 nit: remove
Seigo Nonaka 2012/04/26 17:40:59 Done.
411 return MaybeLaunchIBusDaemon(); 466 return MaybeLaunchIBusDaemon();
412 } 467 }
413 468
414 void IBusControllerImpl::Reset() { 469 void IBusControllerImpl::Reset() {
415 if (!IBusConnectionsAreAlive()) 470 if (!IBusConnectionsAreAlive())
416 return; 471 return;
417 IBusInputContext* context = 472 IBusInputContext* context =
418 GetInputContext(current_input_context_path_, ibus_); 473 GetInputContext(current_input_context_path_, ibus_);
419 if (!context) 474 if (!context)
420 return; 475 return;
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 // Notify the change. 941 // Notify the change.
887 if (!prop_list.empty()) { 942 if (!prop_list.empty()) {
888 for (size_t i = 0; i < prop_list.size(); ++i) { 943 for (size_t i = 0; i < prop_list.size(); ++i) {
889 FindAndUpdateProperty(prop_list[i], &current_property_list_); 944 FindAndUpdateProperty(prop_list[i], &current_property_list_);
890 } 945 }
891 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); 946 FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged());
892 } 947 }
893 } 948 }
894 949
895 bool IBusControllerImpl::MaybeLaunchIBusDaemon() { 950 bool IBusControllerImpl::MaybeLaunchIBusDaemon() {
896 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
897
898 if (process_handle_ != base::kNullProcessHandle) { 951 if (process_handle_ != base::kNullProcessHandle) {
899 DVLOG(1) << "MaybeLaunchIBusDaemon: ibus-daemon is already running."; 952 DVLOG(1) << "MaybeLaunchIBusDaemon: ibus-daemon is already running.";
900 return false; 953 return false;
901 } 954 }
902 if (!should_launch_daemon_) 955 if (!should_launch_daemon_)
903 return false; 956 return false;
904 957
958 std::string ibus_address = base::StringPrintf(
Yusuke Sato 2012/04/26 00:46:28 looks like this function still has a race conditio
Yusuke Sato 2012/04/26 00:46:28 const
Seigo Nonaka 2012/04/26 17:40:59 Done.
Seigo Nonaka 2012/04/26 17:40:59 I introduce is_initializing_ibus_daemon_ to avoid
959 "unix:abstract=/tmp/ibus-%0lX", base::RandUint64());
960
961 // Set up ibus-daemon address file watcher before launching ibus-daemon,
962 // because if watcher start after ibus-daemon, we may miss the ibus connection
963 // initialization.
964 content::BrowserThread::PostTaskAndReply(
965 content::BrowserThread::FILE,
966 FROM_HERE,
967 base::Bind(&StartAddressFileWatch, ibus_address),
968 base::Bind(&IBusControllerImpl::LaunchIBusDaemon,
969 weak_ptr_factory_.GetWeakPtr(),
970 ibus_address));
971 return true;
972 }
973
974 void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) {
975 static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon";
905 // TODO(zork): Send output to /var/log/ibus.log 976 // TODO(zork): Send output to /var/log/ibus.log
906 const std::string ibus_daemon_command_line = 977 const std::string ibus_daemon_command_line =
907 base::StringPrintf("%s --panel=disable --cache=none --restart --replace", 978 base::StringPrintf("%s --panel=disable --cache=none --restart --replace"
908 kIBusDaemonPath); 979 " --address=%s",
980 kIBusDaemonPath,
981 ibus_address.c_str());
909 if (!LaunchProcess(ibus_daemon_command_line, 982 if (!LaunchProcess(ibus_daemon_command_line,
910 &process_handle_, 983 &process_handle_,
911 reinterpret_cast<GChildWatchFunc>(OnIBusDaemonExit))) { 984 reinterpret_cast<GChildWatchFunc>(OnIBusDaemonExit))) {
912 DVLOG(1) << "Failed to launch " << ibus_daemon_command_line; 985 DVLOG(1) << "Failed to launch " << ibus_daemon_command_line;
913 return false;
914 } 986 }
915 return true;
916 } 987 }
917 988
918 bool IBusControllerImpl::LaunchProcess(const std::string& command_line, 989 bool IBusControllerImpl::LaunchProcess(const std::string& command_line,
919 base::ProcessHandle* process_handle, 990 base::ProcessHandle* process_handle,
920 GChildWatchFunc watch_func) { 991 GChildWatchFunc watch_func) {
921 std::vector<std::string> argv; 992 std::vector<std::string> argv;
922 base::ProcessHandle handle = base::kNullProcessHandle; 993 base::ProcessHandle handle = base::kNullProcessHandle;
923 994
924 base::SplitString(command_line, ' ', &argv); 995 base::SplitString(command_line, ' ', &argv);
925 996
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 1049
979 // static 1050 // static
980 bool IBusControllerImpl::FindAndUpdatePropertyForTesting( 1051 bool IBusControllerImpl::FindAndUpdatePropertyForTesting(
981 const chromeos::input_method::InputMethodProperty& new_prop, 1052 const chromeos::input_method::InputMethodProperty& new_prop,
982 chromeos::input_method::InputMethodPropertyList* prop_list) { 1053 chromeos::input_method::InputMethodPropertyList* prop_list) {
983 return FindAndUpdateProperty(new_prop, prop_list); 1054 return FindAndUpdateProperty(new_prop, prop_list);
984 } 1055 }
985 1056
986 } // namespace input_method 1057 } // namespace input_method
987 } // namespace chromeos 1058 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/input_method/ibus_controller_impl.h ('k') | chromeos/dbus/dbus_thread_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698