Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update IME preferences outside the IME status button when Uber Tray i…
…s in use. * browser_state_monitor.cc/h: Added. The class which monitors a notification from the browser to keep track of the browser state (not logged in, logged in, etc.) and notify the current state to the input method manager. The class also updates the appropriate Chrome prefs (~/Local\ State or ~/Preferences) depending on the current browser state. When Uber Tray is disabled via chrome://flags, the class does nothing. In the next CL, I'll remove all preference code from InputMethodButton and make browser_state_monitor.cc work regardless of whether Uber Tray is disabled or not. * preferences.cc: When Uber Tray is enabled, handle prefs::kLanguageCurrentInputMethod and prefs::kLanguagePreviousInputMethod prefs in the class. preferences.cc is the standard place for checking the initial values of Chrome OS specific user prefs. BUG=chromiun-os:28297 TEST=manual (not ready for writing unit tests. It will be done as part of 19655 very soon for R20). Checked test cases in http://code.google.com/p/chromium-os/issues/detail?id=19655#c11. Review URL: https://chromiumcodereview.appspot.com/9852008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128889 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
yusukes@google.com
committed
Mar 26, 2012
1 parent
913b821
commit 146180a
Showing
7 changed files
with
324 additions
and
1 deletion.
There are no files selected for viewing
203 changes: 203 additions & 0 deletions
203
chrome/browser/chromeos/input_method/browser_state_monitor.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
// 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/browser_state_monitor.h" | ||
|
||
#include "ash/ash_switches.h" | ||
#include "base/command_line.h" | ||
#include "chrome/browser/browser_process.h" | ||
#include "chrome/browser/chromeos/input_method/input_method_util.h" | ||
#include "chrome/browser/chromeos/language_preferences.h" | ||
#include "chrome/browser/prefs/pref_service.h" | ||
#include "chrome/browser/profiles/profile_manager.h" | ||
#include "chrome/common/chrome_notification_types.h" | ||
#include "chrome/common/pref_names.h" | ||
#include "content/public/browser/notification_service.h" | ||
|
||
namespace chromeos { | ||
namespace input_method { | ||
namespace { | ||
|
||
PrefService* GetPrefService() { | ||
Profile* profile = ProfileManager::GetDefaultProfile(); | ||
if (profile) | ||
return profile->GetPrefs(); | ||
return NULL; | ||
} | ||
|
||
} // namespace | ||
|
||
BrowserStateMonitor::BrowserStateMonitor(InputMethodManager* manager) | ||
: manager_(manager), | ||
state_(InputMethodManager::STATE_LOGIN_SCREEN), | ||
initialized_(false) { | ||
// On R19, when Uber Tray is disabled, the IME status button will update the | ||
// Preferences. | ||
// TODO(yusukes): Remove all Preferences code from the button on R20. | ||
if (CommandLine::ForCurrentProcess()->HasSwitch( | ||
ash::switches::kDisableAshUberTray)) | ||
return; | ||
|
||
notification_registrar_.Add(this, | ||
chrome::NOTIFICATION_LOGIN_USER_CHANGED, | ||
content::NotificationService::AllSources()); | ||
notification_registrar_.Add(this, | ||
chrome::NOTIFICATION_SESSION_STARTED, | ||
content::NotificationService::AllSources()); | ||
notification_registrar_.Add(this, | ||
chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, | ||
content::NotificationService::AllSources()); | ||
// We should not use APP_EXITING here since logout might be canceled by | ||
// JavaScript after APP_EXITING is sent (crosbug.com/11055). | ||
notification_registrar_.Add(this, | ||
content::NOTIFICATION_APP_TERMINATING, | ||
content::NotificationService::AllSources()); | ||
|
||
// TODO(yusukes): Tell the initial state to the manager. | ||
manager_->AddPreLoginPreferenceObserver(this); | ||
manager_->AddPostLoginPreferenceObserver(this); | ||
} | ||
|
||
BrowserStateMonitor::~BrowserStateMonitor() { | ||
manager_->RemovePostLoginPreferenceObserver(this); | ||
manager_->RemovePreLoginPreferenceObserver(this); | ||
} | ||
|
||
void BrowserStateMonitor::UpdateLocalState( | ||
const std::string& current_input_method) { | ||
if (!InputMethodUtil::IsKeyboardLayout(current_input_method)) { | ||
LOG(ERROR) << "Only keyboard layouts are supported: " | ||
<< current_input_method; | ||
return; | ||
} | ||
|
||
if (!g_browser_process || !g_browser_process->local_state()) | ||
return; | ||
|
||
g_browser_process->local_state()->SetString( | ||
language_prefs::kPreferredKeyboardLayout, | ||
current_input_method); | ||
} | ||
|
||
void BrowserStateMonitor::UpdateUserPreferences( | ||
const std::string& current_input_method) { | ||
InitializePrefMembers(); | ||
const std::string current_input_method_on_pref = | ||
current_input_method_pref_.GetValue(); | ||
if (current_input_method_on_pref == current_input_method) | ||
return; | ||
previous_input_method_pref_.SetValue(current_input_method_on_pref); | ||
current_input_method_pref_.SetValue(current_input_method); | ||
} | ||
|
||
void BrowserStateMonitor::PreferenceUpdateNeeded( | ||
input_method::InputMethodManager* manager, | ||
const input_method::InputMethodDescriptor& previous_input_method, | ||
const input_method::InputMethodDescriptor& current_input_method) { | ||
DCHECK_EQ(manager_, manager); | ||
// Save the new input method id depending on the current browser state. | ||
switch (state_) { | ||
case InputMethodManager::STATE_LOGIN_SCREEN: | ||
UpdateLocalState(current_input_method.id()); | ||
return; | ||
case InputMethodManager::STATE_BROWSER_SCREEN: | ||
UpdateUserPreferences(current_input_method.id()); | ||
return; | ||
case InputMethodManager::STATE_LOGGING_IN: | ||
// Do not update the prefs since Preferences::NotifyPrefChanged() will | ||
// notify the current/previous input method IDs to the manager. | ||
return; | ||
case InputMethodManager::STATE_LOCK_SCREEN: | ||
// We use a special set of input methods on the screen. Do not update. | ||
return; | ||
case InputMethodManager::STATE_TERMINATING: | ||
return; | ||
} | ||
NOTREACHED(); | ||
} | ||
|
||
void BrowserStateMonitor::Observe( | ||
int type, | ||
const content::NotificationSource& source, | ||
const content::NotificationDetails& details) { | ||
switch (type) { | ||
case content::NOTIFICATION_APP_TERMINATING: { | ||
SetState(InputMethodManager::STATE_TERMINATING); | ||
break; | ||
} | ||
case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { | ||
// The user logged in, but the browser window for user session is not yet | ||
// ready. An initial input method hasn't been set to the manager. | ||
// Note that the notification is also sent when Chrome crashes/restarts. | ||
SetState(InputMethodManager::STATE_LOGGING_IN); | ||
break; | ||
} | ||
case chrome::NOTIFICATION_SESSION_STARTED: { | ||
// The user logged in, and the browser window for user session is ready. | ||
// An initial input method has already been set. | ||
// We should NOT call InitializePrefMembers() here since the notification | ||
// is sent in the PreProfileInit phase in case when Chrome crashes and | ||
// restarts. | ||
SetState(InputMethodManager::STATE_BROWSER_SCREEN); | ||
break; | ||
} | ||
case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { | ||
const bool is_screen_locked = *content::Details<bool>(details).ptr(); | ||
SetState(is_screen_locked ? InputMethodManager::STATE_LOCK_SCREEN : | ||
InputMethodManager::STATE_BROWSER_SCREEN); | ||
break; | ||
} | ||
case chrome::NOTIFICATION_PREF_CHANGED: { | ||
break; // just ignore the notification. | ||
} | ||
default: { | ||
NOTREACHED(); | ||
break; | ||
} | ||
} | ||
|
||
// TODO(yusukes): On R20, we should handle Chrome crash/restart correctly. | ||
// Currently, a wrong input method could be selected when Chrome crashes and | ||
// restarts. | ||
// | ||
// Normal login sequence: | ||
// 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. | ||
// 2. Preferences::NotifyPrefChanged() is called. preload_engines (which | ||
// might change the current input method) and current/previous input method | ||
// are sent to the manager. | ||
// 3. chrome::NOTIFICATION_SESSION_STARTED is sent. | ||
// | ||
// Chrome crash/restart (after logging in) sequence: | ||
// 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. | ||
// 2. chrome::NOTIFICATION_SESSION_STARTED is sent. | ||
// 3. Preferences::NotifyPrefChanged() is called. preload_engines (which | ||
// might change the current input method) and current/previous input method | ||
// are sent to the manager. When preload_engines are sent to the manager, | ||
// UpdateUserPreferences() might be accidentally called. | ||
} | ||
|
||
void BrowserStateMonitor::SetState(InputMethodManager::State new_state) { | ||
const InputMethodManager::State old_state = state_; | ||
state_ = new_state; | ||
if (old_state != state_) { | ||
// TODO(yusukes): Tell the new state to the manager. | ||
} | ||
} | ||
|
||
void BrowserStateMonitor::InitializePrefMembers() { | ||
if (initialized_) | ||
return; | ||
|
||
initialized_ = true; | ||
PrefService* pref_service = GetPrefService(); | ||
DCHECK(pref_service); | ||
DCHECK_EQ(InputMethodManager::STATE_BROWSER_SCREEN, state_); | ||
previous_input_method_pref_.Init( | ||
prefs::kLanguagePreviousInputMethod, pref_service, this); | ||
current_input_method_pref_.Init( | ||
prefs::kLanguageCurrentInputMethod, pref_service, this); | ||
} | ||
|
||
} // namespace input_method | ||
} // namespace chromeos |
74 changes: 74 additions & 0 deletions
74
chrome/browser/chromeos/input_method/browser_state_monitor.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// 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_BROWSER_STATE_MONITOR_H_ | ||
#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_BROWSER_STATE_MONITOR_H_ | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#include "chrome/browser/chromeos/input_method/input_method_manager.h" | ||
#include "chrome/browser/prefs/pref_member.h" | ||
#include "content/public/browser/notification_observer.h" | ||
#include "content/public/browser/notification_registrar.h" | ||
#include "content/public/browser/notification_types.h" | ||
|
||
namespace chromeos { | ||
namespace input_method { | ||
|
||
// A class which monitors a notification from the browser to keep track of the | ||
// browser state (not logged in, logged in, etc.) and notify the current state | ||
// to the input method manager. The class also updates the appropriate Chrome | ||
// prefs (~/Local\ State or ~/Preferences) depending on the current browser | ||
// state. | ||
class BrowserStateMonitor | ||
: public content::NotificationObserver, | ||
public input_method::InputMethodManager::PreferenceObserver { | ||
public: | ||
explicit BrowserStateMonitor(InputMethodManager* manager); | ||
virtual ~BrowserStateMonitor(); | ||
|
||
protected: | ||
// Updates ~/Local\ State file. protected: for testing. | ||
virtual void UpdateLocalState(const std::string& current_input_method); | ||
// Updates ~/Preferences file. protected: for testing. | ||
virtual void UpdateUserPreferences(const std::string& current_input_method); | ||
|
||
private: | ||
// InputMethodManager::PreferenceObserver implementation. | ||
// TODO(yusukes): On R20, use input_method::InputMethodManager::Observer and | ||
// remove the PreferenceObserver interface from InputMethodManager. | ||
virtual void PreferenceUpdateNeeded( | ||
input_method::InputMethodManager* manager, | ||
const input_method::InputMethodDescriptor& previous_input_method, | ||
const input_method::InputMethodDescriptor& current_input_method) OVERRIDE; | ||
virtual void FirstObserverIsAdded( | ||
input_method::InputMethodManager* manager) OVERRIDE {} | ||
|
||
// content::NotificationObserver overrides: | ||
virtual void Observe(int type, | ||
const content::NotificationSource& source, | ||
const content::NotificationDetails& details) OVERRIDE; | ||
|
||
void SetState(InputMethodManager::State new_state); | ||
void InitializePrefMembers(); | ||
|
||
InputMethodManager* manager_; | ||
InputMethodManager::State state_; | ||
|
||
// Objects for updating the Chrome prefs. | ||
StringPrefMember previous_input_method_pref_; | ||
StringPrefMember current_input_method_pref_; | ||
bool initialized_; | ||
|
||
// This is used to register this object to some browser notifications. | ||
content::NotificationRegistrar notification_registrar_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(BrowserStateMonitor); | ||
}; | ||
|
||
} // namespace input_method | ||
} // namespace chromeos | ||
|
||
#endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_BROWSER_STATE_MONITOR_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters