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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/input_method/browser_state_monitor.h" 6 7#include "base/logging.h" 8#include "chrome/browser/chrome_notification_types.h" 9#include "chrome/browser/chromeos/input_method/input_method_util.h" 10#include "chromeos/ime/input_method_delegate.h" 11#include "content/public/browser/notification_service.h" 12 13namespace chromeos { 14namespace input_method { 15 16BrowserStateMonitor::BrowserStateMonitor( 17 const base::Callback<void(InputMethodManager::UISessionState)>& observer) 18 : observer_(observer), ui_session_(InputMethodManager::STATE_LOGIN_SCREEN) { 19 notification_registrar_.Add(this, 20 chrome::NOTIFICATION_LOGIN_USER_CHANGED, 21 content::NotificationService::AllSources()); 22 notification_registrar_.Add(this, 23 chrome::NOTIFICATION_SESSION_STARTED, 24 content::NotificationService::AllSources()); 25 notification_registrar_.Add(this, 26 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, 27 content::NotificationService::AllSources()); 28 // We should not use ALL_BROWSERS_CLOSING here since logout might be cancelled 29 // by JavaScript after ALL_BROWSERS_CLOSING is sent (crosbug.com/11055). 30 notification_registrar_.Add(this, 31 chrome::NOTIFICATION_APP_TERMINATING, 32 content::NotificationService::AllSources()); 33 34 if (!observer_.is_null()) 35 observer_.Run(ui_session_); 36} 37 38BrowserStateMonitor::~BrowserStateMonitor() { 39} 40 41void BrowserStateMonitor::Observe( 42 int type, 43 const content::NotificationSource& source, 44 const content::NotificationDetails& details) { 45 const InputMethodManager::UISessionState old_ui_session = ui_session_; 46 switch (type) { 47 case chrome::NOTIFICATION_APP_TERMINATING: { 48 ui_session_ = InputMethodManager::STATE_TERMINATING; 49 break; 50 } 51 case chrome::NOTIFICATION_LOGIN_USER_CHANGED: { 52 // The user logged in, but the browser window for user session is not yet 53 // ready. An initial input method hasn't been set to the manager. 54 // Note that the notification is also sent when Chrome crashes/restarts 55 // as of writing, but it might be changed in the future (therefore we need 56 // to listen to NOTIFICATION_SESSION_STARTED as well.) 57 DVLOG(1) << "Received chrome::NOTIFICATION_LOGIN_USER_CHANGED"; 58 ui_session_ = InputMethodManager::STATE_BROWSER_SCREEN; 59 break; 60 } 61 case chrome::NOTIFICATION_SESSION_STARTED: { 62 // The user logged in, and the browser window for user session is ready. 63 // An initial input method has already been set. 64 // We should NOT call InitializePrefMembers() here since the notification 65 // is sent in the PreProfileInit phase in case when Chrome crashes and 66 // restarts. 67 DVLOG(1) << "Received chrome::NOTIFICATION_SESSION_STARTED"; 68 ui_session_ = InputMethodManager::STATE_BROWSER_SCREEN; 69 break; 70 } 71 case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: { 72 const bool is_screen_locked = *content::Details<bool>(details).ptr(); 73 ui_session_ = is_screen_locked ? InputMethodManager::STATE_LOCK_SCREEN 74 : InputMethodManager::STATE_BROWSER_SCREEN; 75 break; 76 } 77 default: { 78 NOTREACHED(); 79 break; 80 } 81 } 82 83 if (old_ui_session != ui_session_ && !observer_.is_null()) 84 observer_.Run(ui_session_); 85 86 // Note: browser notifications are sent in the following order. 87 // 88 // Normal login: 89 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent. 90 // 2. Preferences::NotifyPrefChanged() is called. preload_engines (which 91 // might change the current input method) and current/previous input method 92 // are sent to the manager. 93 // 3. chrome::NOTIFICATION_SESSION_STARTED is sent. 94 // 95 // Chrome crash/restart (after logging in): 96 // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED might be sent. 97 // 2. chrome::NOTIFICATION_SESSION_STARTED is sent. 98 // 3. Preferences::NotifyPrefChanged() is called. The same things as above 99 // happen. 100 // 101 // We have to be careful not to overwrite both local and user prefs when 102 // preloaded engine is set. Note that it does not work to do nothing in 103 // InputMethodChanged() between chrome::NOTIFICATION_LOGIN_USER_CHANGED and 104 // chrome::NOTIFICATION_SESSION_STARTED because SESSION_STARTED is sent very 105 // early on Chrome crash/restart. 106} 107 108} // namespace input_method 109} // namespace chromeos 110