Commit 28326ecf authored by shuchen's avatar shuchen Committed by Commit bot

Supports multiple profile in Chrome OS IMF.

And avoid dispatching onActivate & onDeactivated events to IME
extensions if the profile is not the active profile.

BUG=485835
TEST=Verified on linux_chromeos & clapper device.

Review URL: https://codereview.chromium.org/1136463005

Cr-Commit-Position: refs/heads/master@{#329808}
parent 229290b5
......@@ -17,6 +17,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/candidate_window.h"
......@@ -162,7 +163,8 @@ InputMethodEngine::InputMethodEngine()
composition_cursor_(0),
candidate_window_(new ui::CandidateWindow()),
window_visible_(false),
sent_key_event_(NULL) {
sent_key_event_(NULL),
profile_(NULL) {
}
InputMethodEngine::~InputMethodEngine() {
......@@ -170,12 +172,14 @@ InputMethodEngine::~InputMethodEngine() {
void InputMethodEngine::Initialize(
scoped_ptr<InputMethodEngineInterface::Observer> observer,
const char* extension_id) {
const char* extension_id,
Profile* profile) {
DCHECK(observer) << "Observer must not be null.";
// TODO(komatsu): It is probably better to set observer out of Initialize.
observer_ = observer.Pass();
extension_id_ = extension_id;
profile_ = profile;
}
const std::string& InputMethodEngine::GetActiveComponentId() const {
......@@ -501,6 +505,8 @@ void InputMethodEngine::HideInputView() {
void InputMethodEngine::SetCompositionBounds(
const std::vector<gfx::Rect>& bounds) {
if (!CheckProfile())
return;
observer_->OnCompositionBoundsChanged(bounds);
}
......@@ -517,6 +523,8 @@ void InputMethodEngine::EnableInputView() {
void InputMethodEngine::FocusIn(
const IMEEngineHandlerInterface::InputContext& input_context) {
if (!CheckProfile())
return;
current_input_type_ = input_context.type;
if (!IsActive() || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE)
......@@ -562,6 +570,8 @@ void InputMethodEngine::FocusIn(
}
void InputMethodEngine::FocusOut() {
if (!CheckProfile())
return;
if (!IsActive() || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE)
return;
......@@ -573,6 +583,8 @@ void InputMethodEngine::FocusOut() {
}
void InputMethodEngine::Enable(const std::string& component_id) {
if (!CheckProfile())
return;
DCHECK(!component_id.empty());
active_component_id_ = component_id;
observer_->OnActivate(component_id);
......@@ -584,15 +596,21 @@ void InputMethodEngine::Enable(const std::string& component_id) {
}
void InputMethodEngine::Disable() {
if (!CheckProfile())
return;
active_component_id_.clear();
observer_->OnDeactivated(active_component_id_);
}
void InputMethodEngine::PropertyActivate(const std::string& property_name) {
if (!CheckProfile())
return;
observer_->OnMenuItemActivated(active_component_id_, property_name);
}
void InputMethodEngine::Reset() {
if (!CheckProfile())
return;
observer_->OnReset(active_component_id_);
}
......@@ -603,6 +621,8 @@ bool InputMethodEngine::IsInterestedInKeyEvent() const {
void InputMethodEngine::ProcessKeyEvent(
const ui::KeyEvent& key_event,
const KeyEventDoneCallback& callback) {
if (!CheckProfile())
return;
KeyEventDoneCallback* handler = new KeyEventDoneCallback();
*handler = callback;
......@@ -624,6 +644,8 @@ void InputMethodEngine::ProcessKeyEvent(
}
void InputMethodEngine::CandidateClicked(uint32 index) {
if (!CheckProfile())
return;
if (index > candidate_ids_.size()) {
return;
}
......@@ -636,12 +658,19 @@ void InputMethodEngine::CandidateClicked(uint32 index) {
void InputMethodEngine::SetSurroundingText(const std::string& text,
uint32 cursor_pos,
uint32 anchor_pos) {
if (!CheckProfile())
return;
observer_->OnSurroundingTextChanged(active_component_id_,
text,
static_cast<int>(cursor_pos),
static_cast<int>(anchor_pos));
}
bool InputMethodEngine::CheckProfile() const {
Profile* active_profile = ProfileManager::GetActiveUserProfile();
return active_profile == profile_ || profile_->IsSameProfile(active_profile);
}
// TODO(uekawa): rename this method to a more reasonable name.
void InputMethodEngine::MenuItemToProperty(
const MenuItem& item,
......
......@@ -39,7 +39,8 @@ class InputMethodEngine : public InputMethodEngineInterface {
~InputMethodEngine() override;
void Initialize(scoped_ptr<InputMethodEngineInterface::Observer> observer,
const char* extension_id);
const char* extension_id,
Profile* profile);
// InputMethodEngineInterface overrides.
const std::string& GetActiveComponentId() const override;
......@@ -96,6 +97,7 @@ class InputMethodEngine : public InputMethodEngineInterface {
bool IsInterestedInKeyEvent() const override;
private:
bool CheckProfile() const;
// Converts MenuItem to InputMethodMenuItem.
void MenuItemToProperty(const MenuItem& item,
ui::ime::InputMethodMenuItem* property);
......@@ -142,6 +144,8 @@ class InputMethodEngine : public InputMethodEngineInterface {
// Used with SendKeyEvents and ProcessKeyEvent to check if the key event
// sent to ProcessKeyEvent is sent by SendKeyEvents.
const ui::KeyEvent* sent_key_event_;
Profile* profile_;
};
} // namespace chromeos
......
......@@ -11,6 +11,7 @@
#include "chrome/browser/chromeos/input_method/input_method_engine.h"
#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
#include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/chromeos/extension_ime_util.h"
#include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
......@@ -136,7 +137,8 @@ class InputMethodEngineTest : public testing::Test {
observer_ = new TestObserver();
scoped_ptr<InputMethodEngineInterface::Observer> observer_ptr(observer_);
engine_->Initialize(observer_ptr.Pass(),
whitelisted ? kTestExtensionId : kTestExtensionId2);
whitelisted ? kTestExtensionId : kTestExtensionId2,
ProfileManager::GetActiveUserProfile());
}
void FocusIn(ui::TextInputType input_type) {
......
......@@ -446,7 +446,7 @@ void InputMethodManagerImpl::StateImpl::AddInputMethodExtension(
DCHECK(engine);
manager_->engine_map_[extension_id] = engine;
manager_->engine_map_[profile][extension_id] = engine;
bool contain = false;
for (size_t i = 0; i < descriptors.size(); i++) {
......@@ -503,10 +503,10 @@ void InputMethodManagerImpl::StateImpl::RemoveInputMethodExtension(
if (IsActive()) {
if (IMEBridge::Get()->GetCurrentEngineHandler() ==
manager_->engine_map_[extension_id]) {
manager_->engine_map_[profile][extension_id]) {
IMEBridge::Get()->SetCurrentEngineHandler(NULL);
}
manager_->engine_map_.erase(extension_id);
manager_->engine_map_[profile].erase(extension_id);
}
// If |current_input_method| is no longer in |active_input_method_ids|,
......@@ -1010,7 +1010,7 @@ void InputMethodManagerImpl::ChangeInputMethodInternal(
extension_ime_util::GetExtensionIDFromInputMethodID(descriptor.id());
const std::string& component_id =
extension_ime_util::GetComponentIDByInputMethodID(descriptor.id());
engine = engine_map_[extension_id];
engine = engine_map_[profile][extension_id];
IMEBridge::Get()->SetCurrentEngineHandler(engine);
......
......@@ -255,7 +255,8 @@ class InputMethodManagerImpl : public InputMethodManager,
// The engine map from extension_id to an engine.
typedef std::map<std::string, InputMethodEngineInterface*> EngineMap;
EngineMap engine_map_;
typedef std::map<Profile*, EngineMap, ProfileCompare> ProfileEngineMap;
ProfileEngineMap engine_map_;
// The map from input method id to the input method stat id.
// The stat id has the format: <category#><first char after prefix><index>
......
......@@ -17,6 +17,7 @@
#include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
#include "chrome/browser/chromeos/input_method/mock_candidate_window_controller.h"
#include "chrome/browser/chromeos/input_method/mock_input_method_engine.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
......@@ -171,7 +172,8 @@ class InputMethodManagerImplTest : public BrowserWithTestWindowTest {
// CreateNewState(NULL) returns state with non-empty current_input_method.
// So SetState() triggers ChangeInputMethod().
manager_->SetState(manager_->CreateNewState(NULL));
manager_->SetState(
manager_->CreateNewState(ProfileManager::GetActiveUserProfile()));
std::vector<std::string> layouts;
layouts.push_back("us");
......
......@@ -34,10 +34,10 @@ struct InputComponentInfo;
class InputImeEventRouter {
public:
static InputImeEventRouter* GetInstance();
explicit InputImeEventRouter(Profile* profile);
~InputImeEventRouter();
bool RegisterImeExtension(
Profile* profile,
const std::string& extension_id,
const std::vector<extensions::InputComponentInfo>& input_components);
void UnregisterAllImes(const std::string& extension_id);
......@@ -58,22 +58,34 @@ class InputImeEventRouter {
chromeos::input_method::KeyEventHandle* key_data);
private:
friend struct DefaultSingletonTraits<InputImeEventRouter>;
typedef std::map<std::string, std::pair<std::string,
chromeos::input_method::KeyEventHandle*> > RequestMap;
InputImeEventRouter();
~InputImeEventRouter();
// The engine map from extension_id to an engine.
std::map<std::string, chromeos::InputMethodEngineInterface*> engine_map_;
unsigned int next_request_id_;
RequestMap request_map_;
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(InputImeEventRouter);
};
class InputImeEventRouterFactory {
public:
static InputImeEventRouterFactory* GetInstance();
InputImeEventRouter* GetRouter(Profile* profile);
private:
friend struct DefaultSingletonTraits<InputImeEventRouterFactory>;
InputImeEventRouterFactory();
~InputImeEventRouterFactory();
std::map<Profile*, InputImeEventRouter*, ProfileCompare> router_map_;
DISALLOW_COPY_AND_ASSIGN(InputImeEventRouterFactory);
};
class InputImeSetCompositionFunction : public SyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("input.ime.setComposition",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment