Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: ash/common/system/chromeos/session/tray_session_length_limit.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "ash/common/system/chromeos/session/tray_session_length_limit.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <utility>
10
11 #include "ash/common/system/system_notifier.h"
12 #include "ash/common/system/tray/label_tray_view.h"
13 #include "ash/common/system/tray/system_tray.h"
14 #include "ash/common/system/tray/system_tray_delegate.h"
15 #include "ash/common/system/tray/system_tray_notifier.h"
16 #include "ash/common/wm_shell.h"
17 #include "ash/resources/grit/ash_resources.h"
18 #include "ash/strings/grit/ash_strings.h"
19 #include "base/logging.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/l10n/time_format.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/message_center/message_center.h"
25 #include "ui/message_center/notification.h"
26 #include "ui/views/view.h"
27
28 namespace ash {
29 namespace {
30
31 // If the remaining session time falls below this threshold, the user should be
32 // informed that the session is about to expire.
33 const int kExpiringSoonThresholdInMinutes = 5;
34
35 // Use 500ms interval for updates to notification and tray bubble to reduce the
36 // likelihood of a user-visible skip in high load situations (as might happen
37 // with 1000ms).
38 const int kTimerIntervalInMilliseconds = 500;
39
40 } // namespace
41
42 // static
43 const char TraySessionLengthLimit::kNotificationId[] =
44 "chrome://session/timeout";
45
46 TraySessionLengthLimit::TraySessionLengthLimit(SystemTray* system_tray)
47 : SystemTrayItem(system_tray, UMA_SESSION_LENGTH_LIMIT),
48 limit_state_(LIMIT_NONE),
49 last_limit_state_(LIMIT_NONE),
50 tray_bubble_view_(NULL) {
51 WmShell::Get()->system_tray_notifier()->AddSessionLengthLimitObserver(this);
52 Update();
53 }
54
55 TraySessionLengthLimit::~TraySessionLengthLimit() {
56 WmShell::Get()->system_tray_notifier()->RemoveSessionLengthLimitObserver(
57 this);
58 }
59
60 // Add view to tray bubble.
61 views::View* TraySessionLengthLimit::CreateDefaultView(LoginStatus status) {
62 CHECK(!tray_bubble_view_);
63 UpdateState();
64 if (limit_state_ == LIMIT_NONE)
65 return NULL;
66 tray_bubble_view_ =
67 new LabelTrayView(NULL /* click_listener */,
68 IDR_AURA_UBER_TRAY_BUBBLE_SESSION_LENGTH_LIMIT);
69 tray_bubble_view_->SetMessage(ComposeTrayBubbleMessage());
70 return tray_bubble_view_;
71 }
72
73 // View has been removed from tray bubble.
74 void TraySessionLengthLimit::DestroyDefaultView() {
75 tray_bubble_view_ = NULL;
76 }
77
78 void TraySessionLengthLimit::OnSessionStartTimeChanged() {
79 Update();
80 }
81
82 void TraySessionLengthLimit::OnSessionLengthLimitChanged() {
83 Update();
84 }
85
86 void TraySessionLengthLimit::Update() {
87 UpdateState();
88 UpdateNotification();
89 UpdateTrayBubbleView();
90 }
91
92 void TraySessionLengthLimit::UpdateState() {
93 SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
94 if (delegate->GetSessionStartTime(&session_start_time_) &&
95 delegate->GetSessionLengthLimit(&time_limit_)) {
96 const base::TimeDelta expiring_soon_threshold(
97 base::TimeDelta::FromMinutes(kExpiringSoonThresholdInMinutes));
98 remaining_session_time_ =
99 std::max(time_limit_ - (base::TimeTicks::Now() - session_start_time_),
100 base::TimeDelta());
101 limit_state_ = remaining_session_time_ <= expiring_soon_threshold
102 ? LIMIT_EXPIRING_SOON
103 : LIMIT_SET;
104 if (!timer_)
105 timer_.reset(new base::RepeatingTimer);
106 if (!timer_->IsRunning()) {
107 timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds(
108 kTimerIntervalInMilliseconds),
109 this, &TraySessionLengthLimit::Update);
110 }
111 } else {
112 remaining_session_time_ = base::TimeDelta();
113 limit_state_ = LIMIT_NONE;
114 timer_.reset();
115 }
116 }
117
118 void TraySessionLengthLimit::UpdateNotification() {
119 message_center::MessageCenter* message_center =
120 message_center::MessageCenter::Get();
121
122 // If state hasn't changed and the notification has already been acknowledged,
123 // we won't re-create it.
124 if (limit_state_ == last_limit_state_ &&
125 !message_center->FindVisibleNotificationById(kNotificationId)) {
126 return;
127 }
128
129 // After state change, any possibly existing notification is removed to make
130 // sure it is re-shown even if it had been acknowledged by the user before
131 // (and in the rare case of state change towards LIMIT_NONE to make the
132 // notification disappear).
133 if (limit_state_ != last_limit_state_ &&
134 message_center->FindVisibleNotificationById(kNotificationId)) {
135 message_center::MessageCenter::Get()->RemoveNotification(
136 kNotificationId, false /* by_user */);
137 }
138
139 // For LIMIT_NONE, there's nothing more to do.
140 if (limit_state_ == LIMIT_NONE) {
141 last_limit_state_ = limit_state_;
142 return;
143 }
144
145 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
146 message_center::RichNotificationData data;
147 data.should_make_spoken_feedback_for_popup_updates =
148 (limit_state_ != last_limit_state_);
149 std::unique_ptr<message_center::Notification> notification(
150 new message_center::Notification(
151 message_center::NOTIFICATION_TYPE_SIMPLE, kNotificationId,
152 base::string16() /* title */,
153 ComposeNotificationMessage() /* message */,
154 bundle.GetImageNamed(
155 IDR_AURA_UBER_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT),
156 base::string16() /* display_source */, GURL(),
157 message_center::NotifierId(
158 message_center::NotifierId::SYSTEM_COMPONENT,
159 system_notifier::kNotifierSessionLengthTimeout),
160 data, NULL /* delegate */));
161 notification->SetSystemPriority();
162 if (message_center->FindVisibleNotificationById(kNotificationId))
163 message_center->UpdateNotification(kNotificationId,
164 std::move(notification));
165 else
166 message_center->AddNotification(std::move(notification));
167 last_limit_state_ = limit_state_;
168 }
169
170 void TraySessionLengthLimit::UpdateTrayBubbleView() const {
171 if (!tray_bubble_view_)
172 return;
173 if (limit_state_ == LIMIT_NONE)
174 tray_bubble_view_->SetMessage(base::string16());
175 else
176 tray_bubble_view_->SetMessage(ComposeTrayBubbleMessage());
177 tray_bubble_view_->Layout();
178 }
179
180 base::string16 TraySessionLengthLimit::ComposeNotificationMessage() const {
181 return l10n_util::GetStringFUTF16(
182 IDS_ASH_STATUS_TRAY_NOTIFICATION_SESSION_LENGTH_LIMIT,
183 ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION,
184 ui::TimeFormat::LENGTH_LONG, 10,
185 remaining_session_time_));
186 }
187
188 base::string16 TraySessionLengthLimit::ComposeTrayBubbleMessage() const {
189 return l10n_util::GetStringFUTF16(
190 IDS_ASH_STATUS_TRAY_BUBBLE_SESSION_LENGTH_LIMIT,
191 ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION,
192 ui::TimeFormat::LENGTH_LONG, 10,
193 remaining_session_time_));
194 }
195
196 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698