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"
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"
17 ScreenlockBridge::UserPodCustomIcon
GetIconForState(
18 EasyUnlockScreenlockStateHandler::State 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
;
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
) {
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
;
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
;
72 return g_browser_process
->GetApplicationLocale() == "en-US";
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
)
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())
113 // No hardlock UI for trial run.
114 if (!is_trial_run_
&& hardlock_state_
!= NO_HARDLOCK
) {
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_
);
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_
,
141 void EasyUnlockScreenlockStateHandler::SetHardlockState(
142 HardlockState new_state
) {
143 if (hardlock_state_
== new_state
)
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
)
162 void EasyUnlockScreenlockStateHandler::SetTrialRun() {
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())
195 if (screenlock_bridge_
->lock_handler()->GetAuthType(user_email_
) !=
196 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD
) {
197 screenlock_bridge_
->lock_handler()->SetAuthType(
199 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD
,
203 if (hardlock_state_
== NO_PAIRING
) {
204 screenlock_bridge_
->lock_handler()->HideUserPodCustomIcon(user_email_
);
205 hardlock_ui_shown_
= false;
209 if (hardlock_ui_shown_
)
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
);
225 LOG(ERROR
) << "Unknown hardlock state " << hardlock_state_
;
227 icon_options
.SetTooltip(tooltip
, true /* autoshow */);
230 screenlock_bridge_
->lock_handler()->ShowUserPodCustomIcon(user_email_
,
232 hardlock_ui_shown_
= true;
235 void EasyUnlockScreenlockStateHandler::UpdateTooltipOptions(
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.
243 resource_id
= IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_INITIAL_AUTHENTICATED
;
245 resource_id
= IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_TUTORIAL
;
247 resource_id
= GetTooltipResourceId(state_
);
248 if (TooltipContainsDeviceType(state_
))
249 device_name
= GetDeviceName();
255 base::string16 tooltip
;
256 if (device_name
.empty()) {
257 tooltip
= l10n_util::GetStringUTF16(resource_id
);
259 tooltip
= l10n_util::GetStringFUTF16(resource_id
, device_name
);
265 icon_options
->SetTooltip(tooltip
, trial_run
/* autoshow tooltip */);
268 base::string16
EasyUnlockScreenlockStateHandler::GetDeviceName() {
269 #if defined(OS_CHROMEOS)
270 return chromeos::GetChromeDeviceType();
272 // TODO(tbarzic): Figure out the name for non Chrome OS case.
273 return base::ASCIIToUTF16("Chrome");
277 void EasyUnlockScreenlockStateHandler::UpdateScreenlockAuthType() {
278 if (!is_trial_run_
&& hardlock_state_
!= NO_HARDLOCK
)
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(
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(
294 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD
,