Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / signin / easy_unlock_screenlock_state_handler.cc
blob0b5226fd19c254004df9b7cea860d752f110a13c
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.
5 #include "chrome/browser/signin/easy_unlock_screenlock_state_handler.h"
7 #include "base/bind.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chromeos/chromeos_utils.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "ui/base/l10n/l10n_util.h"
15 namespace {
17 ScreenlockBridge::UserPodCustomIcon GetIconForState(
18 EasyUnlockScreenlockStateHandler::State state) {
19 switch (state) {
20 case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH:
21 case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE:
22 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED:
23 case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED:
24 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY:
25 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE:
26 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
27 return ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED;
28 case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING:
29 return ScreenlockBridge::USER_POD_CUSTOM_ICON_SPINNER;
30 case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED:
31 return ScreenlockBridge::USER_POD_CUSTOM_ICON_UNLOCKED;
32 default:
33 return ScreenlockBridge::USER_POD_CUSTOM_ICON_NONE;
37 bool HardlockOnClick(EasyUnlockScreenlockStateHandler::State state) {
38 return state != EasyUnlockScreenlockStateHandler::STATE_INACTIVE;
41 size_t GetTooltipResourceId(EasyUnlockScreenlockStateHandler::State state) {
42 switch (state) {
43 case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH:
44 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_NO_BLUETOOTH;
45 case EasyUnlockScreenlockStateHandler::STATE_NO_PHONE:
46 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_NO_PHONE;
47 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_AUTHENTICATED:
48 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_PHONE_NOT_AUTHENTICATED;
49 case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED:
50 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_PHONE_LOCKED;
51 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE:
52 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_PHONE_UNLOCKABLE;
53 case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY:
54 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_PHONE_NOT_NEARBY;
55 case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED:
56 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_INSTRUCTIONS;
57 case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
58 return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_UNSUPPORTED_ANDROID_VERSION;
59 default:
60 return 0;
64 bool TooltipContainsDeviceType(EasyUnlockScreenlockStateHandler::State state) {
65 return state == EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED ||
66 state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE ||
67 state == EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH ||
68 state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED;
71 bool IsLocaleEnUS() {
72 return g_browser_process->GetApplicationLocale() == "en-US";
75 } // namespace
78 EasyUnlockScreenlockStateHandler::EasyUnlockScreenlockStateHandler(
79 const std::string& user_email,
80 HardlockState initial_hardlock_state,
81 ScreenlockBridge* screenlock_bridge)
82 : state_(STATE_INACTIVE),
83 user_email_(user_email),
84 screenlock_bridge_(screenlock_bridge),
85 hardlock_state_(initial_hardlock_state),
86 hardlock_ui_shown_(false),
87 is_trial_run_(false) {
88 DCHECK(screenlock_bridge_);
89 screenlock_bridge_->AddObserver(this);
92 EasyUnlockScreenlockStateHandler::~EasyUnlockScreenlockStateHandler() {
93 screenlock_bridge_->RemoveObserver(this);
94 // Make sure the screenlock state set by this gets cleared.
95 ChangeState(STATE_INACTIVE);
98 bool EasyUnlockScreenlockStateHandler::IsActive() const {
99 return state_ != STATE_INACTIVE;
102 void EasyUnlockScreenlockStateHandler::ChangeState(State new_state) {
103 if (state_ == new_state)
104 return;
106 state_ = new_state;
108 // If lock screen is not active or it forces offline password, just cache the
109 // current state. The screenlock state will get refreshed in |ScreenDidLock|.
110 if (!screenlock_bridge_->IsLocked())
111 return;
113 // No hardlock UI for trial run.
114 if (!is_trial_run_ && hardlock_state_ != NO_HARDLOCK) {
115 ShowHardlockUI();
116 return;
119 UpdateScreenlockAuthType();
121 ScreenlockBridge::UserPodCustomIcon icon = GetIconForState(state_);
123 if (icon == ScreenlockBridge::USER_POD_CUSTOM_ICON_NONE) {
124 screenlock_bridge_->lock_handler()->HideUserPodCustomIcon(user_email_);
125 return;
128 ScreenlockBridge::UserPodCustomIconOptions icon_options;
129 icon_options.SetIcon(icon);
131 // Don't hardlock on trial run.
132 if (!is_trial_run_ && HardlockOnClick(state_))
133 icon_options.SetHardlockOnClick();
135 UpdateTooltipOptions(is_trial_run_, &icon_options);
137 screenlock_bridge_->lock_handler()->ShowUserPodCustomIcon(user_email_,
138 icon_options);
141 void EasyUnlockScreenlockStateHandler::SetHardlockState(
142 HardlockState new_state) {
143 if (hardlock_state_ == new_state)
144 return;
146 hardlock_state_ = new_state;
148 // If hardlock_state_ was set to NO_HARDLOCK, this means the screen is about
149 // to get unlocked. No need to update it in this case.
150 if (hardlock_state_ != NO_HARDLOCK) {
151 hardlock_ui_shown_ = false;
153 RefreshScreenlockState();
157 void EasyUnlockScreenlockStateHandler::MaybeShowHardlockUI() {
158 if (hardlock_state_ != NO_HARDLOCK)
159 ShowHardlockUI();
162 void EasyUnlockScreenlockStateHandler::SetTrialRun() {
163 if (is_trial_run_)
164 return;
165 is_trial_run_ = true;
166 RefreshScreenlockState();
169 void EasyUnlockScreenlockStateHandler::OnScreenDidLock() {
170 RefreshScreenlockState();
173 void EasyUnlockScreenlockStateHandler::OnScreenDidUnlock() {
174 hardlock_ui_shown_ = false;
175 is_trial_run_ = false;
178 void EasyUnlockScreenlockStateHandler::OnFocusedUserChanged(
179 const std::string& user_id) {
182 void EasyUnlockScreenlockStateHandler::RefreshScreenlockState() {
183 State last_state = state_;
184 // This should force updating screenlock state.
185 state_ = STATE_INACTIVE;
186 ChangeState(last_state);
189 void EasyUnlockScreenlockStateHandler::ShowHardlockUI() {
190 DCHECK(hardlock_state_ != NO_HARDLOCK);
192 if (!screenlock_bridge_->IsLocked())
193 return;
195 if (screenlock_bridge_->lock_handler()->GetAuthType(user_email_) !=
196 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD) {
197 screenlock_bridge_->lock_handler()->SetAuthType(
198 user_email_,
199 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
200 base::string16());
203 if (hardlock_state_ == NO_PAIRING) {
204 screenlock_bridge_->lock_handler()->HideUserPodCustomIcon(user_email_);
205 hardlock_ui_shown_ = false;
206 return;
209 if (hardlock_ui_shown_)
210 return;
212 ScreenlockBridge::UserPodCustomIconOptions icon_options;
213 icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_HARDLOCKED);
215 // TODO(tbarzic): Remove this condition for M-40.
216 if (IsLocaleEnUS()) {
217 base::string16 tooltip;
218 if (hardlock_state_ == USER_HARDLOCK) {
219 tooltip = l10n_util::GetStringFUTF16(
220 IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_USER, GetDeviceName());
221 } else if (hardlock_state_ == PAIRING_CHANGED) {
222 tooltip = l10n_util::GetStringUTF16(
223 IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_PAIRING_CHANGED);
224 } else {
225 LOG(ERROR) << "Unknown hardlock state " << hardlock_state_;
227 icon_options.SetTooltip(tooltip, true /* autoshow */);
230 screenlock_bridge_->lock_handler()->ShowUserPodCustomIcon(user_email_,
231 icon_options);
232 hardlock_ui_shown_ = true;
235 void EasyUnlockScreenlockStateHandler::UpdateTooltipOptions(
236 bool trial_run,
237 ScreenlockBridge::UserPodCustomIconOptions* icon_options) {
238 size_t resource_id = 0;
239 base::string16 device_name;
240 if (trial_run && state_ == STATE_AUTHENTICATED) {
241 // TODO(tbarzic): Remove this condition for M-40 branch.
242 if (IsLocaleEnUS())
243 resource_id = IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_INITIAL_AUTHENTICATED;
244 else
245 resource_id = IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_TUTORIAL;
246 } else {
247 resource_id = GetTooltipResourceId(state_);
248 if (TooltipContainsDeviceType(state_))
249 device_name = GetDeviceName();
252 if (!resource_id)
253 return;
255 base::string16 tooltip;
256 if (device_name.empty()) {
257 tooltip = l10n_util::GetStringUTF16(resource_id);
258 } else {
259 tooltip = l10n_util::GetStringFUTF16(resource_id, device_name);
262 if (tooltip.empty())
263 return;
265 icon_options->SetTooltip(tooltip, trial_run /* autoshow tooltip */);
268 base::string16 EasyUnlockScreenlockStateHandler::GetDeviceName() {
269 #if defined(OS_CHROMEOS)
270 return chromeos::GetChromeDeviceType();
271 #else
272 // TODO(tbarzic): Figure out the name for non Chrome OS case.
273 return base::ASCIIToUTF16("Chrome");
274 #endif
277 void EasyUnlockScreenlockStateHandler::UpdateScreenlockAuthType() {
278 if (!is_trial_run_ && hardlock_state_ != NO_HARDLOCK)
279 return;
281 if (state_ == STATE_AUTHENTICATED) {
282 if (screenlock_bridge_->lock_handler()->GetAuthType(user_email_) !=
283 ScreenlockBridge::LockHandler::USER_CLICK) {
284 screenlock_bridge_->lock_handler()->SetAuthType(
285 user_email_,
286 ScreenlockBridge::LockHandler::USER_CLICK,
287 l10n_util::GetStringUTF16(
288 IDS_EASY_UNLOCK_SCREENLOCK_USER_POD_AUTH_VALUE));
290 } else if (screenlock_bridge_->lock_handler()->GetAuthType(user_email_) !=
291 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD) {
292 screenlock_bridge_->lock_handler()->SetAuthType(
293 user_email_,
294 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD,
295 base::string16());