1// Copyright 2014 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 "athena/system/power_button_controller.h"
6
7#include "athena/screen/public/screen_manager.h"
8#include "athena/strings/grit/athena_strings.h"
9#include "chromeos/dbus/dbus_thread_manager.h"
10#include "ui/base/l10n/l10n_util.h"
11#include "ui/gfx/font_list.h"
12#include "ui/views/background.h"
13#include "ui/views/border.h"
14#include "ui/views/controls/label.h"
15#include "ui/views/layout/box_layout.h"
16#include "ui/views/widget/widget.h"
17
18namespace athena {
19namespace {
20
21// The amount of time that the power button must be held to show the shutdown
22// warning dialog.
23const int kShowShutdownWarningTimeoutMs = 1000;
24
25// The amount of time that the power button must be held to shut down the
26// device.
27const int kShutdownTimeoutMs = 5000;
28
29}  // namespace
30
31PowerButtonController::PowerButtonController(aura::Window* dialog_container)
32    : warning_message_container_(dialog_container),
33      brightness_is_zero_(false),
34      state_(STATE_OTHER) {
35  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
36      this);
37}
38
39PowerButtonController::~PowerButtonController() {
40  chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
41      this);
42}
43
44void PowerButtonController::ShowShutdownWarningDialog() {
45  state_ = STATE_SHUTDOWN_WARNING_VISIBLE;
46
47  shutdown_warning_message_.reset(new views::Widget);
48
49  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
50  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
51  params.parent = warning_message_container_;
52  shutdown_warning_message_->Init(params);
53
54  views::Label* label =
55      new views::Label(l10n_util::GetStringUTF16(IDS_ATHENA_SHUTDOWN_WARNING));
56  label->SetBackgroundColor(SK_ColorWHITE);
57  label->SetFontList(gfx::FontList().DeriveWithStyle(gfx::Font::BOLD));
58
59  views::View* container = new views::View;
60  container->AddChildView(label);
61
62  const int kBorderSpacing = 50;
63  container->SetLayoutManager(new views::BoxLayout(
64      views::BoxLayout::kHorizontal, kBorderSpacing, kBorderSpacing, 0));
65  container->set_background(
66      views::Background::CreateSolidBackground(SK_ColorWHITE));
67  container->SetBorder(views::Border::CreateSolidBorder(1, SK_ColorBLACK));
68
69  shutdown_warning_message_->SetContentsView(container);
70  shutdown_warning_message_->CenterWindow(container->GetPreferredSize());
71  shutdown_warning_message_->Show();
72
73  timer_.Start(FROM_HERE,
74               base::TimeDelta::FromMilliseconds(kShutdownTimeoutMs -
75                                                 kShowShutdownWarningTimeoutMs),
76               this,
77               &PowerButtonController::Shutdown);
78}
79
80void PowerButtonController::Shutdown() {
81  state_ = STATE_SHUTDOWN_REQUESTED;
82  chromeos::DBusThreadManager::Get()
83      ->GetPowerManagerClient()
84      ->RequestShutdown();
85}
86
87void PowerButtonController::BrightnessChanged(int level, bool user_initiated) {
88  if (brightness_is_zero_)
89    zero_brightness_end_time_ = base::TimeTicks::Now();
90  brightness_is_zero_ = (level == 0);
91}
92
93void PowerButtonController::PowerButtonEventReceived(
94    bool down,
95    const base::TimeTicks& timestamp) {
96  if (state_ == STATE_SHUTDOWN_REQUESTED)
97    return;
98
99  // Avoid requesting suspend or shutdown if the power button is pressed while
100  // the screen is off (http://crbug.com/128451).
101  base::TimeDelta time_since_zero_brightness = brightness_is_zero_ ?
102      base::TimeDelta() : (base::TimeTicks::Now() - zero_brightness_end_time_);
103  const int kShortTimeMs = 10;
104  if (time_since_zero_brightness.InMilliseconds() <= kShortTimeMs)
105    return;
106
107  if (down) {
108    state_ = STATE_SUSPEND_ON_RELEASE;
109    timer_.Start(
110        FROM_HERE,
111        base::TimeDelta::FromMilliseconds(kShowShutdownWarningTimeoutMs),
112        this,
113        &PowerButtonController::ShowShutdownWarningDialog);
114  } else {
115    if (state_ == STATE_SUSPEND_ON_RELEASE) {
116      chromeos::DBusThreadManager::Get()
117          ->GetPowerManagerClient()
118          ->RequestSuspend();
119    }
120    state_ = STATE_OTHER;
121    timer_.Stop();
122    shutdown_warning_message_.reset();
123  }
124}
125
126}  // namespace athena
127