diff options
author | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-17 16:47:31 +0000 |
---|---|---|
committer | erikwright@chromium.org <erikwright@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-17 16:47:31 +0000 |
commit | 687d05516248e3afa1dfc6a2ecae2332382490ac (patch) | |
tree | 79ae3335a84f5ae28d784f9e6cf8cfd08679e7f8 /chrome | |
parent | f51414ac332c5b34aaf405f24e9b9add335ea040 (diff) | |
download | chromium_src-687d05516248e3afa1dfc6a2ecae2332382490ac.zip chromium_src-687d05516248e3afa1dfc6a2ecae2332382490ac.tar.gz chromium_src-687d05516248e3afa1dfc6a2ecae2332382490ac.tar.bz2 |
Decouple input_method from BrowserThread (and content/).
BUG=164375
Review URL: https://chromiumcodereview.appspot.com/11558017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173477 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
21 files changed, 265 insertions, 91 deletions
diff --git a/chrome/browser/chromeos/input_method/DEPS b/chrome/browser/chromeos/input_method/DEPS index 0294033..052dd54 100644 --- a/chrome/browser/chromeos/input_method/DEPS +++ b/chrome/browser/chromeos/input_method/DEPS @@ -22,10 +22,4 @@ specific_include_rules = { # from chrome/browser. "!chrome/browser/chromeos/language_preferences.h" ], - 'ibus_controller_impl\.cc|xkeyboard\.cc': [ - "!content/public/browser/browser_thread.h", - ], - 'xkeyboard_unittest\.cc': [ - "!content/public/test/test_browser_thread.h", - ], } diff --git a/chrome/browser/chromeos/input_method/ibus_controller.cc b/chrome/browser/chromeos/input_method/ibus_controller.cc index 7307512..7c5a9af 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller.cc +++ b/chrome/browser/chromeos/input_method/ibus_controller.cc @@ -17,9 +17,11 @@ IBusController::~IBusController() { } // static -IBusController* IBusController::Create() { +IBusController* IBusController::Create( + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner) { #if defined(HAVE_IBUS) - return new IBusControllerImpl; + return new IBusControllerImpl(default_task_runner, worker_task_runner); #else return new MockIBusController; #endif diff --git a/chrome/browser/chromeos/input_method/ibus_controller.h b/chrome/browser/chromeos/input_method/ibus_controller.h index 7fe9e80..e0bb507 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller.h +++ b/chrome/browser/chromeos/input_method/ibus_controller.h @@ -9,6 +9,12 @@ #include <utility> #include <vector> +#include "base/memory/ref_counted.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base + namespace chromeos { namespace input_method { @@ -30,7 +36,9 @@ class IBusController { }; // Creates an instance of the class. - static IBusController* Create(); + static IBusController* Create( + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner); virtual ~IBusController(); diff --git a/chrome/browser/chromeos/input_method/ibus_controller_impl.cc b/chrome/browser/chromeos/input_method/ibus_controller_impl.cc index 5600809..2e5a629 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_impl.cc +++ b/chrome/browser/chromeos/input_method/ibus_controller_impl.cc @@ -19,6 +19,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/rand_util.h" +#include "base/sequenced_task_runner.h" #include "base/string_split.h" #include "base/stringprintf.h" #include "chrome/browser/chromeos/input_method/input_method_config.h" @@ -31,7 +32,6 @@ #include "chromeos/dbus/ibus/ibus_input_context_client.h" #include "chromeos/dbus/ibus/ibus_panel_service.h" #include "chromeos/dbus/ibus/ibus_property.h" -#include "content/public/browser/browser_thread.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/root_window.h" #include "ui/base/ime/input_method_ibus.h" @@ -193,10 +193,10 @@ class IBusAddressWatcher { public: IBusAddressFileWatcherDelegate( const std::string& ibus_address, - IBusControllerImpl* controller, + const base::Callback<void(const std::string&)>& callback, IBusAddressWatcher* watcher) : ibus_address_(ibus_address), - controller_(controller), + callback_(callback), watcher_(watcher) { DCHECK(watcher); DCHECK(!ibus_address.empty()); @@ -205,14 +205,7 @@ class IBusAddressWatcher { virtual void OnFilePathChanged(const FilePath& file_path) OVERRIDE { if (!watcher_->IsWatching()) return; - bool success = content::BrowserThread::PostTask( - content::BrowserThread::UI, - FROM_HERE, - base::Bind( - &IBusControllerImpl::IBusDaemonInitializationDone, - controller_, - ibus_address_)); - DCHECK(success); + callback_.Run(ibus_address_); watcher_->StopSoon(); } @@ -222,14 +215,14 @@ class IBusAddressWatcher { private: // The ibus-daemon address. const std::string ibus_address_; - IBusControllerImpl* controller_; + base::Callback<void(const std::string&)> callback_; IBusAddressWatcher* watcher_; DISALLOW_COPY_AND_ASSIGN(IBusAddressFileWatcherDelegate); }; static void Start(const std::string& ibus_address, - IBusControllerImpl* controller) { + const base::Callback<void(const std::string&)>& callback) { IBusAddressWatcher* instance = IBusAddressWatcher::Get(); scoped_ptr<base::Environment> env(base::Environment::Create()); std::string address_file_path; @@ -243,7 +236,7 @@ class IBusAddressWatcher { // The |delegate| is owned by watcher. IBusAddressFileWatcherDelegate* delegate = - new IBusAddressFileWatcherDelegate(ibus_address, controller, instance); + new IBusAddressFileWatcherDelegate(ibus_address, callback, instance); bool result = instance->watcher_->Watch(FilePath(address_file_path), delegate); DCHECK(result); @@ -268,7 +261,6 @@ class IBusAddressWatcher { private: static IBusAddressWatcher* Get() { static IBusAddressWatcher* instance = new IBusAddressWatcher; - DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); return instance; } @@ -282,10 +274,14 @@ class IBusAddressWatcher { } // namespace -IBusControllerImpl::IBusControllerImpl() +IBusControllerImpl::IBusControllerImpl( + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner) : process_handle_(base::kNullProcessHandle), ibus_daemon_status_(IBUS_DAEMON_STOP), input_method_(NULL), + default_task_runner_(default_task_runner), + worker_task_runner_(worker_task_runner), ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { } @@ -501,12 +497,15 @@ bool IBusControllerImpl::StartIBusDaemon() { // 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, + + // Create a callback to bounce from the worker thread to the default thread. + base::Callback<void(const std::string&)> callback(base::Bind( + &IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback, + weak_ptr_factory_.GetWeakPtr())); + + bool success = worker_task_runner_->PostTaskAndReply( FROM_HERE, - base::Bind(&IBusAddressWatcher::Start, - ibus_daemon_address_, - base::Unretained(this)), + base::Bind(&IBusAddressWatcher::Start, ibus_daemon_address_, callback), base::Bind(&IBusControllerImpl::LaunchIBusDaemon, weak_ptr_factory_.GetWeakPtr(), ibus_daemon_address_)); @@ -574,38 +573,42 @@ void IBusControllerImpl::OnIBusConfigClientInitialized() { } } -// static +void IBusControllerImpl::IBusDaemonInitializationDoneWorkerCallback( + const std::string& ibus_address) { + bool result = default_task_runner_->PostTask(FROM_HERE, base::Bind( + &IBusControllerImpl::IBusDaemonInitializationDone, + weak_ptr_factory_.GetWeakPtr(), + ibus_address)); + DCHECK(result); +} + void IBusControllerImpl::IBusDaemonInitializationDone( - IBusControllerImpl* controller, const std::string& ibus_address) { - if (controller->ibus_daemon_address_ != ibus_address) + if (ibus_daemon_address_ != ibus_address) return; - if (controller->ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { + if (ibus_daemon_status_ != IBUS_DAEMON_INITIALIZING) { // Stop() or OnIBusDaemonExit() has already been called. return; } chromeos::DBusThreadManager::Get()->InitIBusBus(ibus_address); - controller->ibus_daemon_status_ = IBUS_DAEMON_RUNNING; + ibus_daemon_status_ = IBUS_DAEMON_RUNNING; - ui::InputMethodIBus* input_method_ibus = controller->GetInputMethod(); + ui::InputMethodIBus* input_method_ibus = GetInputMethod(); DCHECK(input_method_ibus); input_method_ibus->OnConnected(); - DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler( - controller); + DBusThreadManager::Get()->GetIBusPanelService()->SetUpPropertyHandler(this); // Restore previous input method at the beggining of connection. - if (!controller->current_input_method_id_.empty()) { - controller->SendChangeInputMethodRequest( - controller->current_input_method_id_); - } + if (!current_input_method_id_.empty()) + SendChangeInputMethodRequest(current_input_method_id_); DBusThreadManager::Get()->GetIBusConfigClient()->InitializeAsync( base::Bind(&IBusControllerImpl::OnIBusConfigClientInitialized, - controller->weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr())); - FOR_EACH_OBSERVER(Observer, controller->observers_, OnConnected()); + FOR_EACH_OBSERVER(Observer, observers_, OnConnected()); VLOG(1) << "The ibus-daemon initialization is done."; } diff --git a/chrome/browser/chromeos/input_method/ibus_controller_impl.h b/chrome/browser/chromeos/input_method/ibus_controller_impl.h index eb59d2b..ecadaf2 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_impl.h +++ b/chrome/browser/chromeos/input_method/ibus_controller_impl.h @@ -10,11 +10,16 @@ #include <string> #include <vector> +#include "base/memory/ref_counted.h" #include "base/process_util.h" #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" +namespace base { +class SequencedTaskRunner; +} // namespace base + namespace ui { class InputMethodIBus; } // namespace ui @@ -30,7 +35,12 @@ typedef std::vector<InputMethodProperty> InputMethodPropertyList; class IBusControllerImpl : public IBusControllerBase, public ibus::IBusPanelPropertyHandlerInterface { public: - IBusControllerImpl(); + // Creates an IBusController. All public methods must be invoked in the + // context of |default_task_runner|. |worker_task_runner| will be used to + // execute potentially blocking file tasks. + IBusControllerImpl( + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner, + const scoped_refptr<base::SequencedTaskRunner>& worker_task_runner); virtual ~IBusControllerImpl(); // IBusController overrides: @@ -46,9 +56,6 @@ class IBusControllerImpl : public IBusControllerBase, const InputMethodProperty& new_prop, InputMethodPropertyList* prop_list); - static void IBusDaemonInitializationDone(IBusControllerImpl* controller, - const std::string& ibus_address); - private: enum IBusDaemonStatus{ IBUS_DAEMON_INITIALIZING, @@ -95,6 +102,13 @@ class IBusControllerImpl : public IBusControllerBase, // The injected object must be released by caller. void set_input_method_for_testing(ui::InputMethodIBus* input_method); + // Receives a notification on a worker thread and posts a call to + // IBusDaemonInitializationDone on the default task runner. + void IBusDaemonInitializationDoneWorkerCallback( + const std::string& ibus_address); + + void IBusDaemonInitializationDone(const std::string& ibus_address); + // Called when the IBusConfigClient is initialized. void OnIBusConfigClientInitialized(); @@ -127,6 +141,9 @@ class IBusControllerImpl : public IBusControllerBase, // The pointer to global input method. We can inject this value for testing. ui::InputMethodIBus* input_method_; + scoped_refptr<base::SequencedTaskRunner> default_task_runner_; + scoped_refptr<base::SequencedTaskRunner> worker_task_runner_; + // Used for making callbacks for PostTask. base::WeakPtrFactory<IBusControllerImpl> weak_ptr_factory_; diff --git a/chrome/browser/chromeos/input_method/ibus_controller_unittest.cc b/chrome/browser/chromeos/input_method/ibus_controller_unittest.cc index 1da1e1a..c01ec8c 100644 --- a/chrome/browser/chromeos/input_method/ibus_controller_unittest.cc +++ b/chrome/browser/chromeos/input_method/ibus_controller_unittest.cc @@ -3,15 +3,22 @@ // found in the LICENSE file. #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/chromeos/input_method/ibus_controller.h" +#include "chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { namespace input_method { TEST(IBusControllerTest, TestCreate) { - scoped_ptr<IBusController> controller(IBusController::Create()); + scoped_refptr<MockSequencedTaskRunner> default_task_runner( + new MockSequencedTaskRunner); + scoped_refptr<MockSequencedTaskRunner> worker_task_runner( + new MockSequencedTaskRunner); + scoped_ptr<IBusController> controller(IBusController::Create( + default_task_runner, worker_task_runner)); EXPECT_TRUE(controller.get()); } diff --git a/chrome/browser/chromeos/input_method/input_method_delegate.h b/chrome/browser/chromeos/input_method/input_method_delegate.h index ed07173..174fb63 100644 --- a/chrome/browser/chromeos/input_method/input_method_delegate.h +++ b/chrome/browser/chromeos/input_method/input_method_delegate.h @@ -8,6 +8,11 @@ #include <string> #include "base/basictypes.h" +#include "base/memory/ref_counted.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base namespace chromeos { namespace input_method { @@ -23,6 +28,14 @@ class InputMethodDelegate { virtual std::string GetHardwareKeyboardLayout() const = 0; // Retrieves the currently active UI locale. virtual std::string GetActiveLocale() const = 0; + // Retrieves the default task runner. The public input_method API should only + // be accessed in the context of this task runner. + virtual scoped_refptr<base::SequencedTaskRunner> + GetDefaultTaskRunner() const = 0; + // Retrieves a task runner that may be used for possibly blocking tasks such + // as file IO. + virtual scoped_refptr<base::SequencedTaskRunner> + GetWorkerTaskRunner() const = 0; private: DISALLOW_COPY_AND_ASSIGN(InputMethodDelegate); diff --git a/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc index a69cdc4..0451277 100644 --- a/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.cc @@ -5,9 +5,11 @@ #include "chrome/browser/chromeos/input_method/input_method_delegate_impl.h" #include "base/logging.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/pref_names.h" +#include "content/public/browser/browser_thread.h" namespace chromeos { namespace input_method { @@ -33,5 +35,19 @@ std::string InputMethodDelegateImpl::GetActiveLocale() const { return std::string(); } +scoped_refptr<base::SequencedTaskRunner> +InputMethodDelegateImpl::GetDefaultTaskRunner() const { + return content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::UI); +} + +scoped_refptr<base::SequencedTaskRunner> +InputMethodDelegateImpl::GetWorkerTaskRunner() const { + scoped_refptr<base::SequencedWorkerPool> worker_pool( + content::BrowserThread::GetBlockingPool()); + + return worker_pool->GetSequencedTaskRunner(worker_pool->GetSequenceToken()); +} + } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/input_method_delegate_impl.h b/chrome/browser/chromeos/input_method/input_method_delegate_impl.h index b327b61..ab40c70 100644 --- a/chrome/browser/chromeos/input_method/input_method_delegate_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_delegate_impl.h @@ -23,6 +23,10 @@ class InputMethodDelegateImpl : public InputMethodDelegate { // InputMethodDelegate implementation. virtual std::string GetHardwareKeyboardLayout() const OVERRIDE; virtual std::string GetActiveLocale() const OVERRIDE; + virtual scoped_refptr<base::SequencedTaskRunner> + GetDefaultTaskRunner() const OVERRIDE; + virtual scoped_refptr<base::SequencedTaskRunner> + GetWorkerTaskRunner() const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(InputMethodDelegateImpl); 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 2f9a67c..e4c26ec 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "base/sequenced_task_runner.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" @@ -579,8 +580,9 @@ void InputMethodManagerImpl::OnDisconnected() { void InputMethodManagerImpl::Init() { DCHECK(!ibus_controller_.get()); - ibus_controller_.reset(IBusController::Create()); - xkeyboard_.reset(XKeyboard::Create(util_)); + ibus_controller_.reset(IBusController::Create( + delegate_->GetDefaultTaskRunner(), delegate_->GetWorkerTaskRunner())); + xkeyboard_.reset(XKeyboard::Create(util_, delegate_->GetDefaultTaskRunner())); ibus_controller_->AddObserver(this); } diff --git a/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc b/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc index 7114fbe..e9969e1 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc +++ b/chrome/browser/chromeos/input_method/mock_input_method_delegate.cc @@ -4,6 +4,9 @@ #include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" +#include "base/logging.h" +#include "base/sequenced_task_runner.h" + namespace chromeos { namespace input_method { @@ -22,5 +25,17 @@ std::string MockInputMethodDelegate::GetActiveLocale() const { return active_locale_; } +scoped_refptr<base::SequencedTaskRunner> +MockInputMethodDelegate::GetDefaultTaskRunner() const { + NOTREACHED(); + return NULL; +} + +scoped_refptr<base::SequencedTaskRunner> +MockInputMethodDelegate::GetWorkerTaskRunner() const { + NOTREACHED(); + return NULL; +} + } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/mock_input_method_delegate.h b/chrome/browser/chromeos/input_method/mock_input_method_delegate.h index 58f0703..11e9bcd 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_delegate.h +++ b/chrome/browser/chromeos/input_method/mock_input_method_delegate.h @@ -20,6 +20,10 @@ class MockInputMethodDelegate : public InputMethodDelegate { // InputMethodDelegate implementation: virtual std::string GetHardwareKeyboardLayout() const OVERRIDE; virtual std::string GetActiveLocale() const OVERRIDE; + virtual scoped_refptr<base::SequencedTaskRunner> + GetDefaultTaskRunner() const OVERRIDE; + virtual scoped_refptr<base::SequencedTaskRunner> + GetWorkerTaskRunner() const OVERRIDE; void set_hardware_keyboard_layout(const std::string& value) { hardware_keyboard_layout_ = value; diff --git a/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.cc b/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.cc new file mode 100644 index 0000000..6763566 --- /dev/null +++ b/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h" + +#include "base/logging.h" + +MockSequencedTaskRunner::MockSequencedTaskRunner() { +} + +MockSequencedTaskRunner::~MockSequencedTaskRunner() { +} + +bool MockSequencedTaskRunner::PostDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + NOTREACHED(); + return false; +} + +bool MockSequencedTaskRunner::RunsTasksOnCurrentThread() const { + return true; +} + +bool MockSequencedTaskRunner::PostNonNestableDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + NOTREACHED(); + return false; +} diff --git a/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h b/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h new file mode 100644 index 0000000..823551f --- /dev/null +++ b/chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_SEQUENCED_TASK_RUNNER_H_ +#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_SEQUENCED_TASK_RUNNER_H_ + +#include "base/sequenced_task_runner.h" + +class MockSequencedTaskRunner : public base::SequencedTaskRunner { + public: + MockSequencedTaskRunner(); + virtual ~MockSequencedTaskRunner(); + + // base::SequencedTaskRunner implementation. + virtual bool PostDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) OVERRIDE; + virtual bool RunsTasksOnCurrentThread() const OVERRIDE; + virtual bool PostNonNestableDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) OVERRIDE; + +}; + +#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_MOCK_SEQUENCED_TASK_RUNNER_H_ diff --git a/chrome/browser/chromeos/input_method/mock_xkeyboard.cc b/chrome/browser/chromeos/input_method/mock_xkeyboard.cc index 6c5d59f..78a8c63 100644 --- a/chrome/browser/chromeos/input_method/mock_xkeyboard.cc +++ b/chrome/browser/chromeos/input_method/mock_xkeyboard.cc @@ -63,5 +63,15 @@ void MockXKeyboard::GetLockedModifiers(bool* out_caps_lock_enabled, *out_num_lock_enabled = num_lock_is_enabled_; } +bool MockXKeyboard::SetAutoRepeatEnabled(bool enabled) { + auto_repeat_enabled_ = enabled; + return true; +} + +bool MockXKeyboard::SetAutoRepeatRate(const AutoRepeatRate& rate) { + auto_repeat_rate_ = rate; + return true; +} + } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/mock_xkeyboard.h b/chrome/browser/chromeos/input_method/mock_xkeyboard.h index e797979..467da1f 100644 --- a/chrome/browser/chromeos/input_method/mock_xkeyboard.h +++ b/chrome/browser/chromeos/input_method/mock_xkeyboard.h @@ -33,11 +33,16 @@ class MockXKeyboard : public XKeyboard { virtual unsigned int GetNumLockMask() OVERRIDE; virtual void GetLockedModifiers(bool* out_caps_lock_enabled, bool* out_num_lock_enabled) OVERRIDE; + virtual bool SetAutoRepeatEnabled(bool enabled) OVERRIDE; + virtual bool SetAutoRepeatRate(const AutoRepeatRate& rate) OVERRIDE; int set_current_keyboard_layout_by_name_count_; std::string last_layout_; bool caps_lock_is_enabled_; bool num_lock_is_enabled_; + bool auto_repeat_enabled_; + AutoRepeatRate auto_repeat_rate_; + // TODO(yusukes): Add more variables for counting the numbers of the API calls private: diff --git a/chrome/browser/chromeos/input_method/xkeyboard.cc b/chrome/browser/chromeos/input_method/xkeyboard.cc index 511e2b6..fe7ac99 100644 --- a/chrome/browser/chromeos/input_method/xkeyboard.cc +++ b/chrome/browser/chromeos/input_method/xkeyboard.cc @@ -14,10 +14,10 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/process_util.h" +#include "base/sequenced_task_runner.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" -#include "content/public/browser/browser_thread.h" #include "ui/base/x/x11_util.h" // These includes conflict with base/tracked_objects.h so must come last. @@ -25,8 +25,6 @@ #include <X11/Xlib.h> #include <glib.h> -using content::BrowserThread; - namespace chromeos { namespace input_method { namespace { @@ -62,7 +60,9 @@ bool CheckLayoutName(const std::string& layout_name) { class XKeyboardImpl : public XKeyboard { public: - explicit XKeyboardImpl(const InputMethodUtil& util); + explicit XKeyboardImpl( + const InputMethodUtil& util, + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner); virtual ~XKeyboardImpl() {} // Overridden from XKeyboard: @@ -80,6 +80,8 @@ class XKeyboardImpl : public XKeyboard { virtual unsigned int GetNumLockMask() OVERRIDE; virtual void GetLockedModifiers(bool* out_caps_lock_enabled, bool* out_num_lock_enabled) OVERRIDE; + virtual bool SetAutoRepeatEnabled(bool enabled) OVERRIDE; + virtual bool SetAutoRepeatRate(const AutoRepeatRate& rate) OVERRIDE; private: // This function is used by SetLayout() and RemapModifierKeys(). Calls @@ -110,11 +112,16 @@ class XKeyboardImpl : public XKeyboard { // A queue for executing setxkbmap one by one. std::queue<std::string> execute_queue_; + scoped_refptr<base::SequencedTaskRunner> default_task_runner_; + DISALLOW_COPY_AND_ASSIGN(XKeyboardImpl); }; -XKeyboardImpl::XKeyboardImpl(const InputMethodUtil& util) - : is_running_on_chrome_os_(base::chromeos::IsRunningOnChromeOS()) { +XKeyboardImpl::XKeyboardImpl( + const InputMethodUtil& util, + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner) + : is_running_on_chrome_os_(base::chromeos::IsRunningOnChromeOS()), + default_task_runner_(default_task_runner) { num_lock_mask_ = GetNumLockMask(); // web_input_event_aurax11.cc seems to assume that Mod2Mask is always assigned @@ -317,14 +324,14 @@ bool XKeyboardImpl::CurrentlyOnUIThread() const { // TODO(yusukes): Stop special-casing browser_tests and remove this function. if (!is_running_on_chrome_os_) return true; - return BrowserThread::CurrentlyOn(BrowserThread::UI); + return default_task_runner_->RunsTasksOnCurrentThread(); } // static void XKeyboardImpl::OnSetLayoutFinish(pid_t pid, int status, XKeyboardImpl* self) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + CHECK(self->default_task_runner_->RunsTasksOnCurrentThread()); DVLOG(1) << "OnSetLayoutFinish: pid=" << pid; if (self->execute_queue_.empty()) { DVLOG(1) << "OnSetLayoutFinish: execute_queue_ is empty. " @@ -335,11 +342,8 @@ void XKeyboardImpl::OnSetLayoutFinish(pid_t pid, self->MaybeExecuteSetLayoutCommand(); } -} // namespace - -// static -bool XKeyboard::SetAutoRepeatEnabled(bool enabled) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +bool XKeyboardImpl::SetAutoRepeatEnabled(bool enabled) { + CHECK(default_task_runner_->RunsTasksOnCurrentThread()); if (enabled) XAutoRepeatOn(ui::GetXDisplay()); else @@ -348,9 +352,8 @@ bool XKeyboard::SetAutoRepeatEnabled(bool enabled) { return true; } -// static -bool XKeyboard::SetAutoRepeatRate(const AutoRepeatRate& rate) { - CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +bool XKeyboardImpl::SetAutoRepeatRate(const AutoRepeatRate& rate) { + CHECK(default_task_runner_->RunsTasksOnCurrentThread()); DVLOG(1) << "Set auto-repeat rate to: " << rate.initial_delay_in_ms << " ms delay, " << rate.repeat_interval_in_ms << " ms interval"; @@ -363,6 +366,8 @@ bool XKeyboard::SetAutoRepeatRate(const AutoRepeatRate& rate) { return true; } +} // namespace + // static bool XKeyboard::GetAutoRepeatEnabledForTesting() { XKeyboardState state = {}; @@ -383,8 +388,10 @@ bool XKeyboard::CheckLayoutNameForTesting(const std::string& layout_name) { } // static -XKeyboard* XKeyboard::Create(const InputMethodUtil& util) { - return new XKeyboardImpl(util); +XKeyboard* XKeyboard::Create( + const InputMethodUtil& util, + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner) { + return new XKeyboardImpl(util, default_task_runner); } } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/xkeyboard.h b/chrome/browser/chromeos/input_method/xkeyboard.h index ab16015..dff46c9 100644 --- a/chrome/browser/chromeos/input_method/xkeyboard.h +++ b/chrome/browser/chromeos/input_method/xkeyboard.h @@ -9,6 +9,11 @@ #include <vector> #include "base/basictypes.h" +#include "base/memory/ref_counted.h" + +namespace base { +class SequencedTaskRunner; +} // namespace base namespace chromeos { namespace input_method { @@ -99,29 +104,31 @@ class XKeyboard { // Turns on and off the auto-repeat of the keyboard. Returns true on success. // Do not call the function from non-UI threads. - // TODO(yusukes): Make this function non-static so we can mock it. - static bool SetAutoRepeatEnabled(bool enabled); + virtual bool SetAutoRepeatEnabled(bool enabled) = 0; // Sets the auto-repeat rate of the keyboard, initial delay in ms, and repeat // interval in ms. Returns true on success. Do not call the function from // non-UI threads. - // TODO(yusukes): Make this function non-static so we can mock it. - static bool SetAutoRepeatRate(const AutoRepeatRate& rate); + virtual bool SetAutoRepeatRate(const AutoRepeatRate& rate) = 0; - // Returns true if auto repeat is enabled. This function is protected: for - // testability. + // Returns true if auto repeat is enabled. static bool GetAutoRepeatEnabledForTesting(); // On success, set current auto repeat rate on |out_rate| and returns true. - // Returns false otherwise. This function is protected: for testability. + // Returns false otherwise. static bool GetAutoRepeatRateForTesting(AutoRepeatRate* out_rate); // Returns false if |layout_name| contains a bad character. static bool CheckLayoutNameForTesting(const std::string& layout_name); + // Creates an instance of XKeyboard. |default_task_runner| is used to verify + // thread-safe usage (all methods must be invoked in the context of + // default_task_runner). // Note: At this moment, classes other than InputMethodManager should not // instantiate the XKeyboard class. - static XKeyboard* Create(const InputMethodUtil& util); + static XKeyboard* Create( + const InputMethodUtil& util, + const scoped_refptr<base::SequencedTaskRunner>& default_task_runner); }; } // namespace input_method diff --git a/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc b/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc index ab3cc3a..250830a 100644 --- a/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc +++ b/chrome/browser/chromeos/input_method/xkeyboard_unittest.cc @@ -14,14 +14,12 @@ #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_whitelist.h" #include "chrome/browser/chromeos/input_method/mock_input_method_delegate.h" -#include "content/public/test/test_browser_thread.h" +#include "chrome/browser/chromeos/input_method/mock_sequenced_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/x/x11_util.h" #include <X11/Xlib.h> -using content::BrowserThread; - namespace chromeos { namespace input_method { @@ -31,11 +29,11 @@ class XKeyboardTest : public testing::Test { public: XKeyboardTest() : util_(&delegate_, whitelist_.GetSupportedInputMethods()), - ui_thread_(BrowserThread::UI, &message_loop_) { + mock_task_runner_(new MockSequencedTaskRunner) { } virtual void SetUp() { - xkey_.reset(XKeyboard::Create(util_)); + xkey_.reset(XKeyboard::Create(util_, mock_task_runner_)); } virtual void TearDown() { @@ -45,10 +43,8 @@ class XKeyboardTest : public testing::Test { MockInputMethodDelegate delegate_; InputMethodWhitelist whitelist_; InputMethodUtil util_; + scoped_refptr<MockSequencedTaskRunner> mock_task_runner_; scoped_ptr<XKeyboard> xkey_; - - MessageLoopForUI message_loop_; - content::TestBrowserThread ui_thread_; }; // Returns true if X display is available. @@ -189,10 +185,10 @@ TEST_F(XKeyboardTest, TestSetAutoRepeatEnabled) { return; } const bool state = XKeyboard::GetAutoRepeatEnabledForTesting(); - XKeyboard::SetAutoRepeatEnabled(!state); + xkey_->SetAutoRepeatEnabled(!state); EXPECT_EQ(!state, XKeyboard::GetAutoRepeatEnabledForTesting()); // Restore the initial state. - XKeyboard::SetAutoRepeatEnabled(state); + xkey_->SetAutoRepeatEnabled(state); EXPECT_EQ(state, XKeyboard::GetAutoRepeatEnabledForTesting()); } @@ -207,13 +203,13 @@ TEST_F(XKeyboardTest, TestSetAutoRepeatRate) { AutoRepeatRate tmp(rate); ++tmp.initial_delay_in_ms; ++tmp.repeat_interval_in_ms; - EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(tmp)); + EXPECT_TRUE(xkey_->SetAutoRepeatRate(tmp)); EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); EXPECT_EQ(rate.initial_delay_in_ms + 1, tmp.initial_delay_in_ms); EXPECT_EQ(rate.repeat_interval_in_ms + 1, tmp.repeat_interval_in_ms); // Restore the initial state. - EXPECT_TRUE(XKeyboard::SetAutoRepeatRate(rate)); + EXPECT_TRUE(xkey_->SetAutoRepeatRate(rate)); EXPECT_TRUE(XKeyboard::GetAutoRepeatRateForTesting(&tmp)); EXPECT_EQ(rate.initial_delay_in_ms, tmp.initial_delay_in_ms); EXPECT_EQ(rate.repeat_interval_in_ms, tmp.repeat_interval_in_ms); diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index d8f4ec3..3e1e02f 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc @@ -526,7 +526,8 @@ void Preferences::NotifyPrefChanged(const std::string* pref_name) { if (!pref_name || *pref_name == prefs::kLanguageXkbAutoRepeatEnabled) { const bool enabled = xkb_auto_repeat_enabled_.GetValue(); - input_method::XKeyboard::SetAutoRepeatEnabled(enabled); + input_method::GetInputMethodManager()->GetXKeyboard()-> + SetAutoRepeatEnabled(enabled); } if (!pref_name || ((*pref_name == prefs::kLanguageXkbAutoRepeatDelay) || (*pref_name == prefs::kLanguageXkbAutoRepeatInterval))) { @@ -771,7 +772,8 @@ void Preferences::UpdateAutoRepeatRate() { rate.repeat_interval_in_ms = xkb_auto_repeat_interval_pref_.GetValue(); DCHECK(rate.initial_delay_in_ms > 0); DCHECK(rate.repeat_interval_in_ms > 0); - input_method::XKeyboard::SetAutoRepeatRate(rate); + input_method::GetInputMethodManager()->GetXKeyboard()-> + SetAutoRepeatRate(rate); } } // namespace chromeos diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index fee1d75..c62afda 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -84,6 +84,8 @@ 'browser/chromeos/input_method/mock_input_method_delegate.h', 'browser/chromeos/input_method/mock_input_method_manager.cc', 'browser/chromeos/input_method/mock_input_method_manager.h', + 'browser/chromeos/input_method/mock_sequenced_task_runner.cc', + 'browser/chromeos/input_method/mock_sequenced_task_runner.h', 'browser/chromeos/input_method/mock_xkeyboard.cc', 'browser/chromeos/input_method/mock_xkeyboard.h', 'browser/chromeos/login/mock_login_status_consumer.cc', |