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