1// Copyright (c) 2013 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/power/suspend_observer.h"
6
7#include "ash/shell.h"
8#include "ash/wm/user_activity_detector.h"
9#include "base/prefs/pref_service.h"
10#include "chrome/browser/chromeos/login/user_manager.h"
11#include "chrome/browser/extensions/api/system_private/system_private_api.h"
12#include "chrome/browser/profiles/profile.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/common/pref_names.h"
15#include "chromeos/dbus/dbus_thread_manager.h"
16#include "chromeos/display/output_configurator.h"
17
18namespace chromeos {
19
20SuspendObserver::SuspendObserver()
21    : power_client_(DBusThreadManager::Get()->GetPowerManagerClient()),
22      session_client_(DBusThreadManager::Get()->GetSessionManagerClient()),
23      screen_locked_(false) {
24  power_client_->AddObserver(this);
25  session_client_->AddObserver(this);
26}
27
28SuspendObserver::~SuspendObserver() {
29  session_client_->RemoveObserver(this);
30  session_client_ = NULL;
31  power_client_->RemoveObserver(this);
32  power_client_ = NULL;
33}
34
35void SuspendObserver::SuspendImminent() {
36  // If the lock-before-suspending pref is set, get a callback to block
37  // suspend and ask the session manager to lock the screen.
38  Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
39  if (profile && profile->GetPrefs()->GetBoolean(prefs::kEnableScreenLock) &&
40      UserManager::Get()->CanCurrentUserLock() && !screen_locked_) {
41    screen_lock_callback_ = power_client_->GetSuspendReadinessCallback();
42    VLOG(1) << "Requesting screen lock from SuspendObserver";
43    session_client_->RequestLockScreen();
44  }
45
46  ash::Shell::GetInstance()->user_activity_detector()->OnDisplayPowerChanging();
47  ash::Shell::GetInstance()->output_configurator()->SuspendDisplays();
48}
49
50void SuspendObserver::ScreenIsLocked() {
51  screen_locked_ = true;
52
53  // Stop blocking suspend after the screen is locked.
54  if (!screen_lock_callback_.is_null()) {
55    VLOG(1) << "Screen locked due to suspend";
56    // Run the callback asynchronously.  ScreenIsLocked() is currently
57    // called asynchronously after RequestLockScreen(), but this guards
58    // against it being made synchronous later.
59    base::MessageLoop::current()->PostTask(FROM_HERE, screen_lock_callback_);
60    screen_lock_callback_.Reset();
61  } else {
62    VLOG(1) << "Screen locked without suspend";
63  }
64}
65
66void SuspendObserver::ScreenIsUnlocked() {
67  screen_locked_ = false;
68}
69
70}  // namespace chromeos
71