15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/browser_state_monitor.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/ime/input_method_delegate.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace input_method {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BrowserStateMonitor::BrowserStateMonitor(
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const base::Callback<void(InputMethodManager::UISessionState)>& observer)
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : observer_(observer), ui_session_(InputMethodManager::STATE_LOGIN_SCREEN) {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this,
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              chrome::NOTIFICATION_LOGIN_USER_CHANGED,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              chrome::NOTIFICATION_SESSION_STARTED,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should not use ALL_BROWSERS_CLOSING here since logout might be cancelled
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by JavaScript after ALL_BROWSERS_CLOSING is sent (crosbug.com/11055).
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              chrome::NOTIFICATION_APP_TERMINATING,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!observer_.is_null())
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    observer_.Run(ui_session_);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserStateMonitor::~BrowserStateMonitor() {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserStateMonitor::Observe(
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const InputMethodManager::UISessionState old_ui_session = ui_session_;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_APP_TERMINATING: {
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ui_session_ = InputMethodManager::STATE_TERMINATING;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_LOGIN_USER_CHANGED: {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The user logged in, but the browser window for user session is not yet
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ready. An initial input method hasn't been set to the manager.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note that the notification is also sent when Chrome crashes/restarts
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // as of writing, but it might be changed in the future (therefore we need
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to listen to NOTIFICATION_SESSION_STARTED as well.)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Received chrome::NOTIFICATION_LOGIN_USER_CHANGED";
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ui_session_ = InputMethodManager::STATE_BROWSER_SCREEN;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_SESSION_STARTED: {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The user logged in, and the browser window for user session is ready.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // An initial input method has already been set.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We should NOT call InitializePrefMembers() here since the notification
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is sent in the PreProfileInit phase in case when Chrome crashes and
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // restarts.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "Received chrome::NOTIFICATION_SESSION_STARTED";
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ui_session_ = InputMethodManager::STATE_BROWSER_SCREEN;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED: {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const bool is_screen_locked = *content::Details<bool>(details).ptr();
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ui_session_ = is_screen_locked ? InputMethodManager::STATE_LOCK_SCREEN
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                     : InputMethodManager::STATE_BROWSER_SCREEN;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default: {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (old_ui_session != ui_session_ && !observer_.is_null())
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    observer_.Run(ui_session_);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: browser notifications are sent in the following order.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Normal login:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED is sent.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. Preferences::NotifyPrefChanged() is called. preload_engines (which
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    might change the current input method) and current/previous input method
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    are sent to the manager.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. chrome::NOTIFICATION_SESSION_STARTED is sent.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome crash/restart (after logging in):
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. chrome::NOTIFICATION_LOGIN_USER_CHANGED might be sent.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. chrome::NOTIFICATION_SESSION_STARTED is sent.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. Preferences::NotifyPrefChanged() is called. The same things as above
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    happen.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to be careful not to overwrite both local and user prefs when
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // preloaded engine is set. Note that it does not work to do nothing in
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // InputMethodChanged() between chrome::NOTIFICATION_LOGIN_USER_CHANGED and
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome::NOTIFICATION_SESSION_STARTED because SESSION_STARTED is sent very
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // early on Chrome crash/restart.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace input_method
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
110