diff options
author | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-04 07:34:22 +0000 |
---|---|---|
committer | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-04 07:34:22 +0000 |
commit | 54f2994ea0adf85bc3441648245184249576fd1d (patch) | |
tree | a6385fe3715bfd2a459be145b63aef0667622a2b /chrome/browser/chromeos | |
parent | eadbaaf32f299ba14e6b792e4851322c287d4a4a (diff) | |
download | chromium_src-54f2994ea0adf85bc3441648245184249576fd1d.zip chromium_src-54f2994ea0adf85bc3441648245184249576fd1d.tar.gz chromium_src-54f2994ea0adf85bc3441648245184249576fd1d.tar.bz2 |
Use IBusDaemonController instead of IBusController.
I introduced IBusDaemonController(https://codereview.chromium.org/12045007/)
which launches ibus-daemon process and watch it's availability.
Before this patch, IBusController is responsible for this functionality.
BUG=None
TEST=try bots.
Review URL: https://chromiumcodereview.appspot.com/12317143
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@185842 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos')
15 files changed, 108 insertions, 365 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index adf7e88..50ee3ed 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -98,6 +98,7 @@ #include "chromeos/network/network_event_log.h" #include "chromeos/network/network_state_handler.h" #include "chromeos/power/power_state_override.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/common/main_function_params.h" #include "grit/platform_locale_settings.h" @@ -268,7 +269,11 @@ class DBusServices { CrosDBusService::Initialize(); // This function and SystemKeyEventListener use InputMethodManager. - chromeos::input_method::Initialize(); + chromeos::input_method::Initialize( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI), + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::FILE)); disks::DiskMountManager::Initialize(); cryptohome::AsyncMethodCaller::Initialize(); diff --git a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc index 00beb01..eb408b2 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc +++ b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.cc @@ -44,16 +44,14 @@ IBusPanelService* GetIBusPanelService() { } // namespace bool CandidateWindowControllerImpl::Init(IBusController* controller) { - if (controller) - controller->AddObserver(this); + IBusDaemonController::GetInstance()->AddObserver(this); // Create the candidate window view. CreateView(); return true; } void CandidateWindowControllerImpl::Shutdown(IBusController* controller) { - if (controller) - controller->RemoveObserver(this); + IBusDaemonController::GetInstance()->RemoveObserver(this); } void CandidateWindowControllerImpl::CreateView() { @@ -326,9 +324,6 @@ void CandidateWindowControllerImpl::RemoveObserver( observers_.RemoveObserver(observer); } -void CandidateWindowControllerImpl::PropertyChanged() { -} - void CandidateWindowControllerImpl::OnConnected() { DBusThreadManager::Get()->GetIBusPanelService()->SetUpCandidateWindowHandler( this); diff --git a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.h b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.h index d79b096..96ddf9c 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_controller_impl.h +++ b/chrome/browser/chromeos/input_method/candidate_window_controller_impl.h @@ -13,6 +13,7 @@ #include "chrome/browser/chromeos/input_method/ibus_controller.h" #include "chrome/browser/chromeos/input_method/infolist_window_view.h" #include "chromeos/dbus/ibus/ibus_panel_service.h" +#include "chromeos/ime/ibus_daemon_controller.h" namespace views { class Widget; @@ -31,7 +32,7 @@ class CandidateWindowControllerImpl : public CandidateWindowController, public CandidateWindowView::Observer, public IBusPanelCandidateWindowHandlerInterface, - public IBusController::Observer { + public IBusDaemonController::Observer { public: CandidateWindowControllerImpl(); virtual ~CandidateWindowControllerImpl(); @@ -94,8 +95,7 @@ class CandidateWindowControllerImpl virtual void UpdatePreeditText(const std::string& utf8_text, unsigned int cursor, bool visible) OVERRIDE; - // IBusController::Observer override - virtual void PropertyChanged() OVERRIDE; + // IBusDaemonController::Observer override virtual void OnConnected() OVERRIDE; virtual void OnDisconnected() OVERRIDE; diff --git a/chrome/browser/chromeos/input_method/ibus_controller.h b/chrome/browser/chromeos/input_method/ibus_controller.h index 7fe9e80..58f3679 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller.h +++ b/chrome/browser/chromeos/input_method/ibus_controller.h @@ -24,8 +24,6 @@ class IBusController { public: virtual ~Observer() {} virtual void PropertyChanged() = 0; - virtual void OnConnected() = 0; - virtual void OnDisconnected() = 0; // TODO(yusukes): Add functions for IPC error handling. }; @@ -37,16 +35,6 @@ class IBusController { virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; - // Starts the system input method framework. No-op if it's already started. - virtual bool Start() = 0; - - // Resets the system input method framework. A composition text is discarded, - // and a candidate window is closed. - virtual void Reset() = 0; - - // Stops the system input method framework. - virtual bool Stop() = 0; - // Sets a configuration of an input method engine. Returns true if the // configuration is successfully set. For example, when you set // "engine/Mozc/history_learning_level", |section| should be "engine/Mozc", diff --git a/chrome/browser/chromeos/input_method/ibus_controller_base_unittest.cc b/chrome/browser/chromeos/input_method/ibus_controller_base_unittest.cc index aa237b4..d51cc83 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_base_unittest.cc +++ b/chrome/browser/chromeos/input_method/ibus_controller_base_unittest.cc @@ -25,14 +25,6 @@ class TestIBusController : public IBusControllerBase { } // IBusController overrides: - virtual bool Start() OVERRIDE { - return true; - } - virtual void Reset() OVERRIDE { - } - virtual bool Stop() OVERRIDE { - return true; - } virtual bool ChangeInputMethod(const std::string& id) OVERRIDE { return true; } @@ -73,8 +65,6 @@ class TestObserver : public IBusController::Observer { public: // IBusController::Observer overrides: virtual void PropertyChanged() OVERRIDE {} - virtual void OnConnected() OVERRIDE {} - virtual void OnDisconnected() OVERRIDE {} }; class IBusControllerBaseTest : public testing::Test { diff --git a/chrome/browser/chromeos/input_method/ibus_controller_impl.cc b/chrome/browser/chromeos/input_method/ibus_controller_impl.cc index 7210104..b2b4244 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_impl.cc +++ b/chrome/browser/chromeos/input_method/ibus_controller_impl.cc @@ -186,101 +186,18 @@ bool FlattenPropertyList(const IBusPropertyList& ibus_prop_list, return result; } -base::FilePathWatcher* g_file_path_watcher = NULL; - -// Called when the ibus-daemon address file is modified. -void OnFilePathChanged(const base::Closure& closure, - const base::FilePath& file_path, - bool failed) { - if (failed) - return; // Can't recover, do nothing. - if (!g_file_path_watcher) - return; // Already discarded watch task. - - content::BrowserThread::PostTask(content::BrowserThread::UI, - FROM_HERE, - closure); - - MessageLoop::current()->DeleteSoon(FROM_HERE, g_file_path_watcher); - g_file_path_watcher = NULL; -} - -// Start watching |address_file_path|. If the target file is changed, |callback| -// is called on UI thread. This function should be called on FILE thread. -void StartWatch(const std::string& address_file_path, - const base::Callback<void()>& callback) { - // Before start watching, discard on-going watching task. - delete g_file_path_watcher; - g_file_path_watcher = new base::FilePathWatcher; - bool result = g_file_path_watcher->Watch( - base::FilePath::FromUTF8Unsafe(address_file_path), - false, // do not watch child directory. - base::Bind(&OnFilePathChanged, callback)); - DCHECK(result); -} - } // namespace IBusControllerImpl::IBusControllerImpl() - : process_handle_(base::kNullProcessHandle), - ibus_daemon_status_(IBUS_DAEMON_STOP), - input_method_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { + : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { + IBusDaemonController::GetInstance()->AddObserver(this); } IBusControllerImpl::~IBusControllerImpl() { -} - -bool IBusControllerImpl::Start() { - if (IBusConnectionsAreAlive()) - return true; - if (ibus_daemon_status_ == IBUS_DAEMON_STOP || - ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN) { - return StartIBusDaemon(); - } - return true; -} - -void IBusControllerImpl::Reset() { - if (!IBusConnectionsAreAlive()) - return; - IBusInputContextClient* client - = DBusThreadManager::Get()->GetIBusInputContextClient(); - // We don't need to call Reset if there is no on-going input context, because - // the input context will be reset at initialization. - if (client && client->IsObjectProxyReady()) - client->Reset(); -} - -bool IBusControllerImpl::Stop() { - if (ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN || - ibus_daemon_status_ == IBUS_DAEMON_STOP) { - return true; - } - - ibus_daemon_status_ = IBUS_DAEMON_SHUTTING_DOWN; - // TODO(nona): Shutdown ibus-bus connection. - if (IBusConnectionsAreAlive()) { - // Ask IBus to exit *asynchronously*. - IBusClient* client = DBusThreadManager::Get()->GetIBusClient(); - if (client) - client->Exit(IBusClient::SHUT_DOWN_IBUS_DAEMON, - base::Bind(&base::DoNothing)); - } else { - base::KillProcess(process_handle_, -1, false /* wait */); - DVLOG(1) << "Killing ibus-daemon. PID=" - << base::GetProcId(process_handle_); - } - process_handle_ = base::kNullProcessHandle; - return true; + IBusDaemonController::GetInstance()->RemoveObserver(this); } bool IBusControllerImpl::ChangeInputMethod(const std::string& id) { - if (ibus_daemon_status_ == IBUS_DAEMON_SHUTTING_DOWN || - ibus_daemon_status_ == IBUS_DAEMON_STOP) { - return false; - } - // Sanity checks. DCHECK(!InputMethodUtil::IsKeyboardLayout(id)); if (!whitelist_.InputMethodIdIsWhitelisted(id) && @@ -353,7 +270,8 @@ bool IBusControllerImpl::ActivateInputMethodProperty(const std::string& key) { } bool IBusControllerImpl::IBusConnectionsAreAlive() { - return ibus_daemon_status_ == IBUS_DAEMON_RUNNING; + return DBusThreadManager::Get() && + DBusThreadManager::Get()->GetIBusBus() != NULL; } void IBusControllerImpl::SendChangeInputMethodRequest(const std::string& id) { @@ -418,7 +336,7 @@ void IBusControllerImpl::RegisterProperties( current_property_list_.clear(); if (!FlattenPropertyList(ibus_prop_list, ¤t_property_list_)) current_property_list_.clear(); // Clear properties on errors. - FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); + FOR_EACH_OBSERVER(IBusController::Observer, observers_, PropertyChanged()); } void IBusControllerImpl::UpdateProperty(const IBusProperty& ibus_prop) { @@ -434,87 +352,8 @@ void IBusControllerImpl::UpdateProperty(const IBusProperty& ibus_prop) { for (size_t i = 0; i < prop_list.size(); ++i) { FindAndUpdateProperty(prop_list[i], ¤t_property_list_); } - FOR_EACH_OBSERVER(Observer, observers_, PropertyChanged()); - } -} - -bool IBusControllerImpl::StartIBusDaemon() { - if (ibus_daemon_status_ == IBUS_DAEMON_INITIALIZING || - ibus_daemon_status_ == IBUS_DAEMON_RUNNING) { - DVLOG(1) << "MaybeLaunchIBusDaemon: ibus-daemon is already running."; - return false; + FOR_EACH_OBSERVER(IBusController::Observer, observers_, PropertyChanged()); } - - ibus_daemon_status_ = IBUS_DAEMON_INITIALIZING; - ibus_daemon_address_ = base::StringPrintf( - "unix:abstract=ibus-%d", - base::RandInt(0, std::numeric_limits<int>::max())); - - scoped_ptr<base::Environment> env(base::Environment::Create()); - std::string address_file_path; - env->GetVar("IBUS_ADDRESS_FILE", &address_file_path); - DCHECK(!address_file_path.empty()); - - // Set up ibus-daemon address file watcher before launching ibus-daemon, - // because if watcher starts after ibus-daemon, we may miss the ibus - // connection initialization. - bool success = content::BrowserThread::PostTaskAndReply( - content::BrowserThread::FILE, - FROM_HERE, - base::Bind(&StartWatch, - address_file_path, - base::Bind(&IBusControllerImpl::IBusDaemonInitializationDone, - weak_ptr_factory_.GetWeakPtr(), - ibus_daemon_address_)), - base::Bind(&IBusControllerImpl::LaunchIBusDaemon, - weak_ptr_factory_.GetWeakPtr(), - ibus_daemon_address_)); - DCHECK(success); - return true; -} - -void IBusControllerImpl::LaunchIBusDaemon(const std::string& ibus_address) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_EQ(base::kNullProcessHandle, process_handle_); - static const char kIBusDaemonPath[] = "/usr/bin/ibus-daemon"; - // TODO(zork): Send output to /var/log/ibus.log - const std::string ibus_daemon_command_line = - base::StringPrintf("%s --panel=disable --cache=none --restart --replace" - " --address=%s", - kIBusDaemonPath, - ibus_address.c_str()); - if (!LaunchProcess(ibus_daemon_command_line, &process_handle_)) { - DVLOG(1) << "Failed to launch " << ibus_daemon_command_line; - } -} - -bool IBusControllerImpl::LaunchProcess(const std::string& command_line, - base::ProcessHandle* process_handle) { - std::vector<std::string> argv; - base::ProcessHandle handle = base::kNullProcessHandle; - - base::SplitString(command_line, ' ', &argv); - - if (!base::LaunchProcess(argv, base::LaunchOptions(), &handle)) { - DVLOG(1) << "Could not launch: " << command_line; - return false; - } - - *process_handle = handle; - - return true; -} - -ui::InputMethodIBus* IBusControllerImpl::GetInputMethod() { - return input_method_ ? input_method_ : - static_cast<ui::InputMethodIBus*>( - ash::Shell::GetPrimaryRootWindow()->GetProperty( - aura::client::kRootWindowInputMethodKey)); -} - -void IBusControllerImpl::set_input_method_for_testing( - ui::InputMethodIBus* input_method) { - input_method_ = input_method; } void IBusControllerImpl::OnIBusConfigClientInitialized() { @@ -526,26 +365,8 @@ void IBusControllerImpl::OnIBusConfigClientInitialized() { } } -void IBusControllerImpl::IBusDaemonInitializationDone( - const std::string& ibus_address) { +void IBusControllerImpl::OnConnected() { DCHECK(thread_checker_.CalledOnValidThread()); - if (ibus_daemon_address_ != ibus_address) - return; - - if (ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { - // Stop() or OnIBusDaemonExit() has already been called. - return; - } - chromeos::DBusThreadManager::Get()->InitIBusBus( - ibus_address, - base::Bind(&IBusControllerImpl::OnIBusDaemonDisconnected, - weak_ptr_factory_.GetWeakPtr(), - base::GetProcId(process_handle_))); - ibus_daemon_status_ = IBUS_DAEMON_RUNNING; - - ui::InputMethodIBus* input_method_ibus = GetInputMethod(); - DCHECK(input_method_ibus); - input_method_ibus->OnConnected(); DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler(this); @@ -556,47 +377,10 @@ void IBusControllerImpl::IBusDaemonInitializationDone( DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync( base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized, weak_ptr_factory_.GetWeakPtr())); - - FOR_EACH_OBSERVER(Observer, observers_, OnConnected()); - - VLOG(1) << "The ibus-daemon initialization is done."; } -void IBusControllerImpl::OnIBusDaemonDisconnected(base::ProcessId pid) { - if (!chromeos::DBusThreadManager::Get()) - return; // Expected disconnection at shutting down. do nothing. - - if (process_handle_ != base::kNullProcessHandle) { - if (base::GetProcId(process_handle_) == pid) { - // ibus-daemon crashed. - // TODO(nona): Shutdown ibus-bus connection. - process_handle_ = base::kNullProcessHandle; - } else { - // This condition is as follows. - // 1. Called Stop (process_handle_ becomes null) - // 2. Called LaunchProcess (process_handle_ becomes new instance) - // 3. Callbacked OnIBusDaemonExit for old instance and reach here. - // In this case, we should not reset process_handle_ as null, and do not - // re-launch ibus-daemon. - return; - } - } - - const IBusDaemonStatus on_exit_state = ibus_daemon_status_; - ibus_daemon_status_ = IBUS_DAEMON_STOP; - ui::InputMethodIBus* input_method_ibus = GetInputMethod(); - DCHECK(input_method_ibus); - input_method_ibus->OnDisconnected(); - - FOR_EACH_OBSERVER(Observer, observers_, OnDisconnected()); - - if (on_exit_state == IBUS_DAEMON_SHUTTING_DOWN) { - // Normal exitting, so do nothing. - return; - } - - LOG(ERROR) << "The ibus-daemon crashed. Re-launching..."; - StartIBusDaemon(); +void IBusControllerImpl::OnDisconnected() { + DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler(NULL); } // static diff --git a/chrome/browser/chromeos/input_method/ibus_controller_impl.h b/chrome/browser/chromeos/input_method/ibus_controller_impl.h index 75652c1..b27ecb8 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_impl.h +++ b/chrome/browser/chromeos/input_method/ibus_controller_impl.h @@ -13,6 +13,7 @@ #include "chrome/browser/chromeos/input_method/ibus_controller_base.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" #include "chromeos/dbus/ibus/ibus_panel_service.h" +#include "chromeos/ime/ibus_daemon_controller.h" namespace ui { class InputMethodIBus; @@ -27,15 +28,13 @@ typedef std::vector<InputMethodProperty> InputMethodPropertyList; // The IBusController implementation. class IBusControllerImpl : public IBusControllerBase, - public IBusPanelPropertyHandlerInterface { + public IBusPanelPropertyHandlerInterface, + public IBusDaemonController::Observer { public: IBusControllerImpl(); virtual ~IBusControllerImpl(); // IBusController overrides: - virtual bool Start() OVERRIDE; - virtual void Reset() OVERRIDE; - virtual bool Stop() OVERRIDE; virtual bool ChangeInputMethod(const std::string& id) OVERRIDE; virtual bool ActivateInputMethodProperty(const std::string& key) OVERRIDE; @@ -45,15 +44,10 @@ class IBusControllerImpl : public IBusControllerBase, const InputMethodProperty& new_prop, InputMethodPropertyList* prop_list); - void IBusDaemonInitializationDone(const std::string& ibus_address); - private: - enum IBusDaemonStatus{ - IBUS_DAEMON_INITIALIZING, - IBUS_DAEMON_RUNNING, - IBUS_DAEMON_SHUTTING_DOWN, - IBUS_DAEMON_STOP, - }; + // IBusDaemonController overrides: + virtual void OnConnected() OVERRIDE; + virtual void OnDisconnected() OVERRIDE; // IBusControllerBase overrides: virtual bool SetInputMethodConfigInternal( @@ -71,40 +65,9 @@ class IBusControllerImpl : public IBusControllerBase, // Just calls ibus_bus_set_global_engine_async() with the |id|. void SendChangeInputMethodRequest(const std::string& id); - // Adds address file watcher in FILE thread and then calls LaunchIBusDaemon. - bool StartIBusDaemon(); - - // Starts ibus-daemon. - void LaunchIBusDaemon(const std::string& ibus_address); - - // Launches an input method procsess specified by the given command - // line. On success, returns true and stores the process handle in - // |process_handle|. Otherwise, returns false, and the contents of - // |process_handle| is untouched. - bool LaunchProcess(const std::string& command_line, - base::ProcessHandle* process_handle); - - // Returns pointer to InputMethod object. - ui::InputMethodIBus* GetInputMethod(); - - // Injects an alternative ui::InputMethod for testing. - // The injected object must be released by caller. - void set_input_method_for_testing(ui::InputMethodIBus* input_method); - // Called when the IBusConfigClient is initialized. void OnIBusConfigClientInitialized(); - // Called when the input method process is shut down. - void OnIBusDaemonDisconnected(base::ProcessId pid); - - // The current ibus_daemon address. This value is assigned at the launching - // ibus-daemon and used in bus connection initialization. - std::string ibus_daemon_address_; - - // The process handle of the IBus daemon. kNullProcessHandle if it's not - // running. - base::ProcessHandle process_handle_; - // Current input context path. std::string current_input_context_path_; @@ -115,12 +78,6 @@ class IBusControllerImpl : public IBusControllerBase, // An object which knows all valid input methods and layout IDs. InputMethodWhitelist whitelist_; - // Represents ibus-daemon's status. - IBusDaemonStatus ibus_daemon_status_; - - // The pointer to global input method. We can inject this value for testing. - ui::InputMethodIBus* input_method_; - // IBusControllerImpl should be used only on UI thread. base::ThreadChecker thread_checker_; diff --git a/chrome/browser/chromeos/input_method/input_method_configuration.cc b/chrome/browser/chromeos/input_method/input_method_configuration.cc index dc3b2c5..6d527b0 100644 --- a/chrome/browser/chromeos/input_method/input_method_configuration.cc +++ b/chrome/browser/chromeos/input_method/input_method_configuration.cc @@ -30,9 +30,12 @@ void OnSessionStateChange(InputMethodManagerImpl* input_method_manager_impl, input_method_manager_impl->SetState(new_state); } -void Initialize() { +void Initialize( + const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& file_task_runner) { DCHECK(!g_input_method_manager); + IBusDaemonController::Initialize(ui_task_runner, file_task_runner); if (!base::chromeos::IsRunningOnChromeOS()) { // IBusBridge is for ChromeOS on desktop Linux not for ChromeOS Devices or // production at this moment. @@ -73,6 +76,7 @@ void Shutdown() { // TODO(nona): Remove this condition when ibus-daemon is gone. IBusBridge::Shutdown(); } + IBusDaemonController::Shutdown(); DVLOG(1) << "InputMethodManager shutdown"; } diff --git a/chrome/browser/chromeos/input_method/input_method_configuration.h b/chrome/browser/chromeos/input_method/input_method_configuration.h index d1fc12c..6d56ce2 100644 --- a/chrome/browser/chromeos/input_method/input_method_configuration.h +++ b/chrome/browser/chromeos/input_method/input_method_configuration.h @@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_CONFIGURATION_H_ #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_INPUT_METHOD_CONFIGURATION_H_ +#include "base/sequenced_task_runner.h" + namespace chromeos { namespace input_method { @@ -13,7 +15,9 @@ class InputMethodManager; // Initializes the InputMethodManager. Must be called before any calls to // GetInstance(). We explicitly initialize and shut down the global instance, // rather than making it a Singleton, to ensure clean startup and shutdown. -void Initialize(); +void Initialize( + const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& file_task_runner); // Similar to Initialize(), but can inject an alternative // InputMethodManager such as MockInputMethodManager for testing. diff --git a/chrome/browser/chromeos/input_method/input_method_configuration_unittest.cc b/chrome/browser/chromeos/input_method/input_method_configuration_unittest.cc index 3f6d33f..857027e 100644 --- a/chrome/browser/chromeos/input_method/input_method_configuration_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_configuration_unittest.cc @@ -4,19 +4,34 @@ #include "chrome/browser/chromeos/input_method/input_method_configuration.h" #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" +#include "content/public/browser/browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ime/text_input_test_support.h" namespace chromeos { namespace input_method { -TEST(InputMethodConfigurationTest, TestInitialize) { - Initialize(); +class InputMethodConfigurationTest : public testing::Test { + public: + void SetUp() { + } + + void TearDown() { + } +}; + +TEST_F(InputMethodConfigurationTest, TestInitialize) { + Initialize( + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI), + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::FILE)); InputMethodManager* manager = GetInputMethodManager(); EXPECT_TRUE(manager); Shutdown(); } -TEST(InputMethodConfigurationTest, TestInitializeForTesting) { +TEST_F(InputMethodConfigurationTest, TestInitializeForTesting) { InitializeForTesting(new MockInputMethodManager); InputMethodManager* manager = GetInputMethodManager(); EXPECT_TRUE(manager); diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc index 5c8f1e1..f481999 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc @@ -38,11 +38,13 @@ InputMethodManagerImpl::InputMethodManagerImpl( : delegate_(delegate.Pass()), state_(STATE_LOGIN_SCREEN), util_(delegate_.get(), GetSupportedInputMethods()) { + IBusDaemonController::GetInstance()->AddObserver(this); } InputMethodManagerImpl::~InputMethodManagerImpl() { if (ibus_controller_.get()) ibus_controller_->RemoveObserver(this); + IBusDaemonController::GetInstance()->RemoveObserver(this); if (candidate_window_controller_.get()) { candidate_window_controller_->RemoveObserver(this); candidate_window_controller_->Shutdown(ibus_controller_.get()); @@ -83,7 +85,7 @@ void InputMethodManagerImpl::SetState(State new_state) { OnScreenLocked(); break; case STATE_TERMINATING: { - ibus_controller_->Stop(); + IBusDaemonController::GetInstance()->Stop(); if (candidate_window_controller_.get()) { candidate_window_controller_->Shutdown(ibus_controller_.get()); candidate_window_controller_.reset(); @@ -207,7 +209,7 @@ bool InputMethodManagerImpl::EnableInputMethods( // is implemented. } else { MaybeInitializeCandidateWindowController(); - ibus_controller_->Start(); + IBusDaemonController::GetInstance()->Start(); } // If |current_input_method| is no longer in |active_input_method_ids_|, @@ -266,7 +268,9 @@ void InputMethodManagerImpl::ChangeInputMethodInternal( const std::string current_input_method_id = current_input_method_.id(); if (current_input_method_id.empty() || InputMethodUtil::IsKeyboardLayout(current_input_method_id)) { - ibus_controller_->Reset(); + if (DBusThreadManager::Get() && + DBusThreadManager::Get()->GetIBusInputContextClient()) + DBusThreadManager::Get()->GetIBusInputContextClient()->Reset(); } else { ibus_controller_->ChangeInputMethod(current_input_method_id); } @@ -342,7 +346,7 @@ void InputMethodManagerImpl::AddInputMethodExtension( // Ensure that the input method daemon is running. MaybeInitializeCandidateWindowController(); - ibus_controller_->Start(); + IBusDaemonController::GetInstance()->Start(); } extra_input_method_instances_[id] = @@ -423,7 +427,7 @@ void InputMethodManagerImpl::SetFilteredExtensionImes( if (active_imes_changed) { MaybeInitializeCandidateWindowController(); - ibus_controller_->Start(); + IBusDaemonController::GetInstance()->Start(); // If |current_input_method| is no longer in |active_input_method_ids_|, // switch to the first one in |active_input_method_ids_|. diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index 0a5715b..00b67a0 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h @@ -16,6 +16,7 @@ #include "chrome/browser/chromeos/input_method/input_method_manager.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" +#include "chromeos/ime/ibus_daemon_controller.h" namespace chromeos { class InputMethodEngineIBus; @@ -26,7 +27,8 @@ class XKeyboard; // The implementation of InputMethodManager. class InputMethodManagerImpl : public InputMethodManager, public CandidateWindowController::Observer, - public IBusController::Observer { + public IBusController::Observer, + public IBusDaemonController::Observer { public: // Constructs an InputMethodManager instance. The client is responsible for // calling |SetState| in response to relevant changes in browser state. @@ -94,6 +96,8 @@ class InputMethodManagerImpl : public InputMethodManager, private: // IBusController overrides: virtual void PropertyChanged() OVERRIDE; + + // IBusDaemonController overrides: virtual void OnConnected() OVERRIDE; virtual void OnDisconnected() OVERRIDE; diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc index 338c18f..7718a56 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc @@ -15,6 +15,10 @@ #include "chrome/browser/chromeos/input_method/mock_ibus_controller.h" #include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" #include "chrome/browser/chromeos/input_method/mock_xkeyboard.h" +#include "chromeos/dbus/ibus/mock_ibus_client.h" +#include "chromeos/dbus/ibus/mock_ibus_input_context_client.h" +#include "chromeos/dbus/mock_dbus_thread_manager_without_gmock.h" +#include "chromeos/ime/mock_ibus_daemon_controller.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/accelerators/accelerator.h" #include "ui/base/ime/text_input_test_support.h" @@ -38,7 +42,16 @@ class InputMethodManagerImplTest : public testing::Test { virtual ~InputMethodManagerImplTest() {} virtual void SetUp() OVERRIDE { - ui::TextInputTestSupport::Initialize(); + mock_ibus_daemon_controller_ = new chromeos::MockIBusDaemonController(); + chromeos::IBusDaemonController::InitializeForTesting( + mock_ibus_daemon_controller_); + mock_dbus_thread_manager_ = + new chromeos::MockDBusThreadManagerWithoutGMock(); + chromeos::DBusThreadManager::InitializeForTesting( + mock_dbus_thread_manager_); + mock_ibus_client_ = mock_dbus_thread_manager_->mock_ibus_client(); + mock_ibus_input_context_client_ = + mock_dbus_thread_manager_->mock_ibus_input_context_client(); delegate_ = new MockInputMethodDelegate(); manager_.reset(new InputMethodManagerImpl( scoped_ptr<InputMethodDelegate>(delegate_))); @@ -57,7 +70,8 @@ class InputMethodManagerImplTest : public testing::Test { candidate_window_controller_ = NULL; xkeyboard_ = NULL; manager_.reset(); - ui::TextInputTestSupport::Shutdown(); + chromeos::DBusThreadManager::Shutdown(); + chromeos::IBusDaemonController::Shutdown(); } protected: @@ -65,6 +79,10 @@ class InputMethodManagerImplTest : public testing::Test { MockInputMethodDelegate* delegate_; MockIBusController* controller_; MockCandidateWindowController* candidate_window_controller_; + MockIBusDaemonController* mock_ibus_daemon_controller_; + MockIBusInputContextClient* mock_ibus_input_context_client_; + MockIBusClient* mock_ibus_client_; + MockDBusThreadManagerWithoutGMock* mock_dbus_thread_manager_; MockXKeyboard* xkeyboard_; MessageLoop message_loop_; @@ -214,13 +232,13 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayouts) { std::find(methods->begin(), methods->end(), *id_to_find)); } // For http://crbug.com/19655#c11 - (2) - EXPECT_EQ(0, controller_->start_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->start_count()); // For http://crbug.com/19655#c11 - (5) // The hardware keyboard layout "xkb:us::eng" is always active, hence 2U. manager_->EnableLayouts("ja", ""); // Japanese EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); - EXPECT_EQ(0, controller_->start_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->start_count()); } TEST_F(InputMethodManagerImplTest, TestEnableLayoutsNonUsHardwareKeyboard) { @@ -287,7 +305,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) { EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); // Since all the IDs added avobe are keyboard layouts, Start() should not be // called. - EXPECT_EQ(0, controller_->start_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->start_count()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); @@ -341,7 +359,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) { ids.push_back("xkb:us:dvorak:eng"); ids.push_back("mozc"); EXPECT_TRUE(manager_->EnableInputMethods(ids)); - EXPECT_EQ(1, controller_->start_count_); + EXPECT_EQ(1, mock_ibus_daemon_controller_->start_count()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); @@ -358,11 +376,11 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) { EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // Currently, to work around a crash issue at crosbug.com/27051, // controller_->Stop(); is NOT called when all IMEs are disabled. - EXPECT_EQ(0, controller_->stop_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->stop_count()); // However, IME should always be stopped on shutdown. manager_->SetState(InputMethodManager::STATE_TERMINATING); - EXPECT_EQ(1, controller_->stop_count_); + EXPECT_EQ(1, mock_ibus_daemon_controller_->stop_count()); manager_->RemoveObserver(&observer); } @@ -375,7 +393,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme2) { ids.push_back("xkb:us:dvorak:eng"); ids.push_back("mozc"); EXPECT_TRUE(manager_->EnableInputMethods(ids)); - EXPECT_EQ(1, controller_->start_count_); + EXPECT_EQ(1, mock_ibus_daemon_controller_->start_count()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); @@ -398,7 +416,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableImes) { ids.push_back("mozc-chewing"); ids.push_back("mozc-dv"); EXPECT_TRUE(manager_->EnableInputMethods(ids)); - EXPECT_EQ(1, controller_->start_count_); + EXPECT_EQ(1, mock_ibus_daemon_controller_->start_count()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); @@ -490,7 +508,7 @@ TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndImeThenLock) { EXPECT_EQ("us(dvorak)", xkeyboard_->last_layout_); // controller_->Stop() should never be called when the screen is locked even // after crosbug.com/27051 is fixed. - EXPECT_EQ(0, controller_->stop_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->stop_count()); manager_->SwitchToNextInputMethod(); EXPECT_EQ("xkb:us::eng", // The hardware keyboard layout. manager_->GetCurrentInputMethod().id()); @@ -864,7 +882,7 @@ TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) { ids.push_back("xkb:us:dvorak:eng"); EXPECT_TRUE(manager_->EnableInputMethods(ids)); EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); - EXPECT_EQ(0, controller_->start_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->start_count()); EXPECT_EQ(1, observer.input_method_changed_count_); EXPECT_EQ(ids[0], manager_->GetCurrentInputMethod().id()); @@ -880,7 +898,9 @@ TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) { "en-US", NULL); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); - EXPECT_EQ(1, controller_->start_count_); // should be started. + + // should be started. + EXPECT_EQ(1, mock_ibus_daemon_controller_->start_count()); { scoped_ptr<InputMethodDescriptors> methods( manager_->GetActiveInputMethods()); @@ -914,7 +934,7 @@ TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) { EXPECT_EQ(1U, manager_->GetNumActiveInputMethods()); // Currently, to work around a crash issue at crosbug.com/27051, // controller_->Stop(); is NOT called when all (extension) IMEs are disabled. - EXPECT_EQ(0, controller_->stop_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->stop_count()); manager_->RemoveObserver(&observer); } @@ -956,7 +976,7 @@ TEST_F(InputMethodManagerImplTest, TestAddExtensionInputThenLockScreen) { EXPECT_EQ("xkb:us::eng", manager_->GetCurrentInputMethod().id()); EXPECT_EQ("us", xkeyboard_->last_layout_); - EXPECT_EQ(0, controller_->stop_count_); + EXPECT_EQ(0, mock_ibus_daemon_controller_->stop_count()); // Unlock the screen. manager_->SetState(InputMethodManager::STATE_BROWSER_SCREEN); @@ -983,15 +1003,15 @@ TEST_F(InputMethodManagerImplTest, TestReset) { ids.push_back("mozc"); EXPECT_TRUE(manager_->EnableInputMethods(ids)); EXPECT_EQ(2U, manager_->GetNumActiveInputMethods()); - EXPECT_EQ(1, controller_->reset_count_); + EXPECT_EQ(1, mock_ibus_input_context_client_->reset_call_count()); manager_->ChangeInputMethod("mozc"); EXPECT_EQ(1, controller_->change_input_method_count_); EXPECT_EQ("mozc", controller_->change_input_method_id_); - EXPECT_EQ(1, controller_->reset_count_); + EXPECT_EQ(1, mock_ibus_input_context_client_->reset_call_count()); manager_->ChangeInputMethod("xkb:us::eng"); EXPECT_EQ(2, controller_->change_input_method_count_); EXPECT_EQ("mozc", controller_->change_input_method_id_); - EXPECT_EQ(1, controller_->reset_count_); + EXPECT_EQ(1, mock_ibus_input_context_client_->reset_call_count()); } } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/mock_ibus_controller.cc b/chrome/browser/chromeos/input_method/mock_ibus_controller.cc index a94b7af..f47c260 100644 --- a/chrome/browser/chromeos/input_method/mock_ibus_controller.cc +++ b/chrome/browser/chromeos/input_method/mock_ibus_controller.cc @@ -11,12 +11,7 @@ namespace chromeos { namespace input_method { MockIBusController::MockIBusController() - : start_count_(0), - start_return_(true), - reset_count_(0), - stop_count_(0), - stop_return_(true), - change_input_method_count_(0), + : change_input_method_count_(0), change_input_method_return_(true), activate_input_method_property_count_(0), activate_input_method_property_return_(true), @@ -27,20 +22,6 @@ MockIBusController::MockIBusController() MockIBusController::~MockIBusController() { } -bool MockIBusController::Start() { - ++start_count_; - return start_return_; -} - -void MockIBusController::Reset() { - ++reset_count_; -} - -bool MockIBusController::Stop() { - ++stop_count_; - return stop_return_; -} - bool MockIBusController::ChangeInputMethod(const std::string& id) { ++change_input_method_count_; diff --git a/chrome/browser/chromeos/input_method/mock_ibus_controller.h b/chrome/browser/chromeos/input_method/mock_ibus_controller.h index cf63e4f..1890138 100644 --- a/chrome/browser/chromeos/input_method/mock_ibus_controller.h +++ b/chrome/browser/chromeos/input_method/mock_ibus_controller.h @@ -20,17 +20,9 @@ class MockIBusController : public IBusControllerBase { virtual ~MockIBusController(); // IBusController overrides: - virtual bool Start() OVERRIDE; - virtual void Reset() OVERRIDE; - virtual bool Stop() OVERRIDE; virtual bool ChangeInputMethod(const std::string& id) OVERRIDE; virtual bool ActivateInputMethodProperty(const std::string& key) OVERRIDE; - int start_count_; - bool start_return_; - int reset_count_; - int stop_count_; - bool stop_return_; int change_input_method_count_; std::string change_input_method_id_; bool change_input_method_return_; |