| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" | 5 #include "chrome/browser/chromeos/input_method/browser_state_monitor.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/chromeos/input_method/input_method_delegate.h" | 8 #include "chrome/browser/chromeos/input_method/input_method_delegate.h" |
| 9 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 9 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
| 10 #include "chrome/common/chrome_notification_types.h" | 10 #include "chrome/common/chrome_notification_types.h" |
| 11 #include "content/public/browser/notification_service.h" | 11 #include "content/public/browser/notification_service.h" |
| 12 | 12 |
| 13 namespace chromeos { | 13 namespace chromeos { |
| 14 namespace input_method { | 14 namespace input_method { |
| 15 | 15 |
| 16 BrowserStateMonitor::BrowserStateMonitor(InputMethodManager* manager, | 16 BrowserStateMonitor::BrowserStateMonitor( |
| 17 InputMethodDelegate* delegate) | 17 const base::Callback<void(InputMethodManager::State)>& observer) |
| 18 : manager_(manager), | 18 : observer_(observer), |
| 19 delegate_(delegate), | |
| 20 state_(InputMethodManager::STATE_LOGIN_SCREEN) { | 19 state_(InputMethodManager::STATE_LOGIN_SCREEN) { |
| 21 notification_registrar_.Add(this, | 20 notification_registrar_.Add(this, |
| 22 chrome::NOTIFICATION_LOGIN_USER_CHANGED, | 21 chrome::NOTIFICATION_LOGIN_USER_CHANGED, |
| 23 content::NotificationService::AllSources()); | 22 content::NotificationService::AllSources()); |
| 24 notification_registrar_.Add(this, | 23 notification_registrar_.Add(this, |
| 25 chrome::NOTIFICATION_SESSION_STARTED, | 24 chrome::NOTIFICATION_SESSION_STARTED, |
| 26 content::NotificationService::AllSources()); | 25 content::NotificationService::AllSources()); |
| 27 notification_registrar_.Add(this, | 26 notification_registrar_.Add(this, |
| 28 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, | 27 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, |
| 29 content::NotificationService::AllSources()); | 28 content::NotificationService::AllSources()); |
| 30 // We should not use ALL_BROWSERS_CLOSING here since logout might be cancelled | 29 // We should not use ALL_BROWSERS_CLOSING here since logout might be cancelled |
| 31 // by JavaScript after ALL_BROWSERS_CLOSING is sent (crosbug.com/11055). | 30 // by JavaScript after ALL_BROWSERS_CLOSING is sent (crosbug.com/11055). |
| 32 notification_registrar_.Add(this, | 31 notification_registrar_.Add(this, |
| 33 chrome::NOTIFICATION_APP_TERMINATING, | 32 chrome::NOTIFICATION_APP_TERMINATING, |
| 34 content::NotificationService::AllSources()); | 33 content::NotificationService::AllSources()); |
| 35 | 34 |
| 36 manager_->SetState(state_); | 35 if (!observer_.is_null()) |
| 37 manager_->AddObserver(this); | 36 observer_.Run(state_); |
| 38 } | 37 } |
| 39 | 38 |
| 40 BrowserStateMonitor::~BrowserStateMonitor() { | 39 BrowserStateMonitor::~BrowserStateMonitor() { |
| 41 manager_->RemoveObserver(this); | |
| 42 } | 40 } |
| 43 | 41 |
| 44 void BrowserStateMonitor::InputMethodChanged(InputMethodManager* manager, | |
| 45 bool show_message) { | |
| 46 DCHECK_EQ(manager_, manager); | |
| 47 const std::string current_input_method = | |
| 48 manager->GetCurrentInputMethod().id(); | |
| 49 // Save the new input method id depending on the current browser state. | |
| 50 switch (state_) { | |
| 51 case InputMethodManager::STATE_LOGIN_SCREEN: | |
| 52 if (!InputMethodUtil::IsKeyboardLayout(current_input_method)) { | |
| 53 DVLOG(1) << "Only keyboard layouts are supported: " | |
| 54 << current_input_method; | |
| 55 return; | |
| 56 } | |
| 57 delegate_->SetSystemInputMethod(current_input_method); | |
| 58 return; | |
| 59 case InputMethodManager::STATE_BROWSER_SCREEN: | |
| 60 delegate_->SetUserInputMethod(current_input_method); | |
| 61 return; | |
| 62 case InputMethodManager::STATE_LOCK_SCREEN: | |
| 63 // We use a special set of input methods on the screen. Do not update. | |
| 64 return; | |
| 65 case InputMethodManager::STATE_TERMINATING: | |
| 66 return; | |
| 67 } | |
| 68 NOTREACHED(); | |
| 69 } | |
| 70 | |
| 71 void BrowserStateMonitor::InputMethodPropertyChanged( | |
| 72 InputMethodManager* manager) {} | |
| 73 | |
| 74 void BrowserStateMonitor::Observe( | 42 void BrowserStateMonitor::Observe( |
| 75 int type, | 43 int type, |
| 76 const content::NotificationSource& source, | 44 const content::NotificationSource& source, |
| 77 const content::NotificationDetails& details) { | 45 const content::NotificationDetails& details) { |
| 46 const InputMethodManager::State old_state = state_; |
| 78 switch (type) { | 47 switch (type) { |
| 79 case chrome::NOTIFICATION_APP_TERMINATING: { | 48 case chrome::NOTIFICATION_APP_TERMINATING: { |
| 80 SetState(InputMethodManager::STATE_TERMINATING); | 49 state_ = InputMethodManager::STATE_TERMINATING; |
| 81 break; | 50 break; |
| 82 } | 51 } |
| 83 case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { | 52 case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { |
| 84 // The user logged in, but the browser window for user session is not yet | 53 // The user logged in, but the browser window for user session is not yet |
| 85 // ready. An initial input method hasn't been set to the manager. | 54 // ready. An initial input method hasn't been set to the manager. |
| 86 // Note that the notification is also sent when Chrome crashes/restarts | 55 // Note that the notification is also sent when Chrome crashes/restarts |
| 87 // as of writing, but it might be changed in the future (therefore we need | 56 // as of writing, but it might be changed in the future (therefore we need |
| 88 // to listen to NOTIFICATION_SESSION_STARTED as well.) | 57 // to listen to NOTIFICATION_SESSION_STARTED as well.) |
| 89 DVLOG(1) << "Received chrome::NOTIFICATION_LOGIN_USER_CHANGED"; | 58 DVLOG(1) << "Received chrome::NOTIFICATION_LOGIN_USER_CHANGED"; |
| 90 SetState(InputMethodManager::STATE_BROWSER_SCREEN); | 59 state_ = InputMethodManager::STATE_BROWSER_SCREEN; |
| 91 break; | 60 break; |
| 92 } | 61 } |
| 93 case chrome::NOTIFICATION_SESSION_STARTED: { | 62 case chrome::NOTIFICATION_SESSION_STARTED: { |
| 94 // The user logged in, and the browser window for user session is ready. | 63 // The user logged in, and the browser window for user session is ready. |
| 95 // An initial input method has already been set. | 64 // An initial input method has already been set. |
| 96 // We should NOT call InitializePrefMembers() here since the notification | 65 // We should NOT call InitializePrefMembers() here since the notification |
| 97 // is sent in the PreProfileInit phase in case when Chrome crashes and | 66 // is sent in the PreProfileInit phase in case when Chrome crashes and |
| 98 // restarts. | 67 // restarts. |
| 99 DVLOG(1) << "Received chrome::NOTIFICATION_SESSION_STARTED"; | 68 DVLOG(1) << "Received chrome::NOTIFICATION_SESSION_STARTED"; |
| 100 SetState(InputMethodManager::STATE_BROWSER_SCREEN); | 69 state_ = InputMethodManager::STATE_BROWSER_SCREEN; |
| 101 break; | 70 break; |
| 102 } | 71 } |
| 103 case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { | 72 case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { |
| 104 const bool is_screen_locked = *content::Details<bool>(details).ptr(); | 73 const bool is_screen_locked = *content::Details<bool>(details).ptr(); |
| 105 SetState(is_screen_locked ? InputMethodManager::STATE_LOCK_SCREEN : | 74 state_ = is_screen_locked ? InputMethodManager::STATE_LOCK_SCREEN : |
| 106 InputMethodManager::STATE_BROWSER_SCREEN); | 75 InputMethodManager::STATE_BROWSER_SCREEN; |
| 107 break; | 76 break; |
| 108 } | 77 } |
| 109 default: { | 78 default: { |
| 110 NOTREACHED(); | 79 NOTREACHED(); |
| 111 break; | 80 break; |
| 112 } | 81 } |
| 113 } | 82 } |
| 83 |
| 84 if (old_state != state_ && !observer_.is_null()) |
| 85 observer_.Run(state_); |
| 86 |
| 114 // Note: browser notifications are sent in the following order. | 87 // Note: browser notifications are sent in the following order. |
| 115 // | 88 // |
| 116 // Normal login: | 89 // Normal login: |
| 117 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. | 90 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. |
| 118 // 2. Preferences::NotifyPrefChanged() is called. preload_engines (which | 91 // 2. Preferences::NotifyPrefChanged() is called. preload_engines (which |
| 119 // might change the current input method) and current/previous input method | 92 // might change the current input method) and current/previous input method |
| 120 // are sent to the manager. | 93 // are sent to the manager. |
| 121 // 3. chrome::NOTIFICATION_SESSION_STARTED is sent. | 94 // 3. chrome::NOTIFICATION_SESSION_STARTED is sent. |
| 122 // | 95 // |
| 123 // Chrome crash/restart (after logging in): | 96 // Chrome crash/restart (after logging in): |
| 124 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED might be sent. | 97 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED might be sent. |
| 125 // 2. chrome::NOTIFICATION_SESSION_STARTED is sent. | 98 // 2. chrome::NOTIFICATION_SESSION_STARTED is sent. |
| 126 // 3. Preferences::NotifyPrefChanged() is called. The same things as above | 99 // 3. Preferences::NotifyPrefChanged() is called. The same things as above |
| 127 // happen. | 100 // happen. |
| 128 // | 101 // |
| 129 // We have to be careful not to overwrite both local and user prefs when | 102 // We have to be careful not to overwrite both local and user prefs when |
| 130 // preloaded engine is set. Note that it does not work to do nothing in | 103 // preloaded engine is set. Note that it does not work to do nothing in |
| 131 // InputMethodChanged() between chrome::NOTIFICATION_LOGIN_USER_CHANGED and | 104 // InputMethodChanged() between chrome::NOTIFICATION_LOGIN_USER_CHANGED and |
| 132 // chrome::NOTIFICATION_SESSION_STARTED because SESSION_STARTED is sent very | 105 // chrome::NOTIFICATION_SESSION_STARTED because SESSION_STARTED is sent very |
| 133 // early on Chrome crash/restart. | 106 // early on Chrome crash/restart. |
| 134 } | 107 } |
| 135 | 108 |
| 136 void BrowserStateMonitor::SetState(InputMethodManager::State new_state) { | |
| 137 const InputMethodManager::State old_state = state_; | |
| 138 state_ = new_state; | |
| 139 if (old_state != state_) | |
| 140 manager_->SetState(state_); | |
| 141 } | |
| 142 | |
| 143 } // namespace input_method | 109 } // namespace input_method |
| 144 } // namespace chromeos | 110 } // namespace chromeos |
| OLD | NEW |