kiosk_mode_idle_app_name_notification.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h"
6
7#include "ash/shell.h"
8#include "base/bind.h"
9#include "base/command_line.h"
10#include "base/logging.h"
11#include "chrome/browser/chromeos/login/user_manager.h"
12#include "chrome/browser/chromeos/ui/idle_app_name_notification_view.h"
13#include "chrome/browser/extensions/extension_service.h"
14#include "chrome/browser/profiles/profile_manager.h"
15#include "chrome/common/chrome_switches.h"
16#include "chromeos/dbus/dbus_thread_manager.h"
17#include "extensions/browser/extension_system.h"
18#include "ui/wm/core/user_activity_detector.h"
19
20namespace chromeos {
21
22namespace {
23
24// The timeout in ms before the message shows up.
25const int kIdleAppNameNotificationTimeoutMs = 2 * 60 * 1000;
26
27// The duration of visibility for the message.
28const int kMessageVisibilityTimeMs = 3000;
29
30// The anomation time to show / hide the message.
31const int kMessageAnimationTimeMs = 200;
32
33// Our global instance of the Kiosk mode message.
34KioskModeIdleAppNameNotification* g_kiosk_mode_idle_app_message = NULL;
35
36}  // namespace
37
38// static
39void KioskModeIdleAppNameNotification::Initialize() {
40  DCHECK(!g_kiosk_mode_idle_app_message);
41  g_kiosk_mode_idle_app_message = new KioskModeIdleAppNameNotification();
42}
43
44// static
45void KioskModeIdleAppNameNotification::Shutdown() {
46  if (g_kiosk_mode_idle_app_message) {
47    delete g_kiosk_mode_idle_app_message;
48    g_kiosk_mode_idle_app_message = NULL;
49  }
50}
51
52KioskModeIdleAppNameNotification::KioskModeIdleAppNameNotification()
53    : show_notification_upon_next_user_activity_(false) {
54  // Note: The timeout is currently fixed. If that changes we need to check if
55  // the KioskModeSettings were already initialized.
56  Setup();
57}
58
59KioskModeIdleAppNameNotification::~KioskModeIdleAppNameNotification() {
60  if (ash::Shell::HasInstance() &&
61      ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) {
62    ash::Shell::GetInstance()->user_activity_detector()->RemoveObserver(this);
63    // At this time the DBusThreadManager might already be gone.
64    if (chromeos::DBusThreadManager::IsInitialized())
65      chromeos::DBusThreadManager::Get()->GetPowerManagerClient(
66          )->RemoveObserver(this);
67  }
68}
69
70void KioskModeIdleAppNameNotification::Setup() {
71  DCHECK(UserManager::Get()->IsUserLoggedIn());
72  Start();
73}
74
75void KioskModeIdleAppNameNotification::OnUserActivity(const ui::Event* event) {
76  if (show_notification_upon_next_user_activity_) {
77    CommandLine* command_line = CommandLine::ForCurrentProcess();
78    const std::string app_id =
79        command_line->GetSwitchValueASCII(::switches::kAppId);
80    Profile* profile = ProfileManager::GetActiveUserProfile();
81    notification_.reset(
82        new IdleAppNameNotificationView(
83            kMessageVisibilityTimeMs,
84            kMessageAnimationTimeMs,
85            extensions::ExtensionSystem::Get(profile
86                )->extension_service()->GetInstalledExtension(app_id)));
87    show_notification_upon_next_user_activity_ = false;
88  }
89  ResetTimer();
90}
91
92void KioskModeIdleAppNameNotification::SystemResumed(
93    const base::TimeDelta& sleep_duration) {
94  // When we come back from a system resume we stop the timer and show the
95  // message.
96  timer_.Stop();
97  OnTimeout();
98}
99
100void KioskModeIdleAppNameNotification::Start() {
101  if (!ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this)) {
102    ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this);
103    chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
104        this);
105  }
106  ResetTimer();
107}
108
109void KioskModeIdleAppNameNotification::ResetTimer() {
110  if (timer_.IsRunning()) {
111    timer_.Reset();
112  } else {
113    // OneShotTimer destroys the posted task after running it, so Reset()
114    // isn't safe to call on a timer that's already fired.
115    timer_.Start(
116        FROM_HERE,
117        base::TimeDelta::FromMilliseconds(kIdleAppNameNotificationTimeoutMs),
118        base::Bind(&KioskModeIdleAppNameNotification::OnTimeout,
119                   base::Unretained(this)));
120  }
121}
122
123void KioskModeIdleAppNameNotification::OnTimeout() {
124  show_notification_upon_next_user_activity_ = true;
125}
126
127}  // namespace chromeos
128