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 "chromeos/components/proximity_auth/screenlock_bridge.h"
6 
7 #include <utility>
8 
9 #include <memory>
10 
11 #include "base/strings/string16.h"
12 #include "build/build_config.h"
13 #include "chromeos/components/multidevice/logging/logging.h"
14 #include "chromeos/dbus/session_manager/session_manager_client.h"
15 
16 namespace proximity_auth {
17 namespace {
18 
19 base::LazyInstance<ScreenlockBridge>::DestructorAtExit
20     g_screenlock_bridge_instance = LAZY_INSTANCE_INITIALIZER;
21 
22 // Ids for the icons that are supported by lock screen and signin screen
23 // account picker as user pod custom icons.
24 // The id's should be kept in sync with values used by user_pod_row.js.
25 const char kLockedUserPodCustomIconId[] = "locked";
26 const char kLockedToBeActivatedUserPodCustomIconId[] = "locked-to-be-activated";
27 const char kLockedWithProximityHintUserPodCustomIconId[] =
28     "locked-with-proximity-hint";
29 const char kUnlockedUserPodCustomIconId[] = "unlocked";
30 const char kHardlockedUserPodCustomIconId[] = "hardlocked";
31 const char kSpinnerUserPodCustomIconId[] = "spinner";
32 
33 // Given the user pod icon, returns its id as used by the user pod UI code.
GetIdForIcon(ScreenlockBridge::UserPodCustomIcon icon)34 std::string GetIdForIcon(ScreenlockBridge::UserPodCustomIcon icon) {
35   switch (icon) {
36     case ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED:
37       return kLockedUserPodCustomIconId;
38     case ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED_TO_BE_ACTIVATED:
39       return kLockedToBeActivatedUserPodCustomIconId;
40     case ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED_WITH_PROXIMITY_HINT:
41       return kLockedWithProximityHintUserPodCustomIconId;
42     case ScreenlockBridge::USER_POD_CUSTOM_ICON_UNLOCKED:
43       return kUnlockedUserPodCustomIconId;
44     case ScreenlockBridge::USER_POD_CUSTOM_ICON_HARDLOCKED:
45       return kHardlockedUserPodCustomIconId;
46     case ScreenlockBridge::USER_POD_CUSTOM_ICON_SPINNER:
47       return kSpinnerUserPodCustomIconId;
48     default:
49       return "";
50   }
51 }
52 
53 }  // namespace
54 
UserPodCustomIconOptions()55 ScreenlockBridge::UserPodCustomIconOptions::UserPodCustomIconOptions()
56     : autoshow_tooltip_(false), hardlock_on_click_(false) {}
57 
~UserPodCustomIconOptions()58 ScreenlockBridge::UserPodCustomIconOptions::~UserPodCustomIconOptions() {}
59 
60 std::unique_ptr<base::DictionaryValue>
ToDictionaryValue() const61 ScreenlockBridge::UserPodCustomIconOptions::ToDictionaryValue() const {
62   auto result = std::make_unique<base::DictionaryValue>();
63   result->SetString("id", GetIDString());
64 
65   if (!tooltip_.empty()) {
66     auto tooltip_options = std::make_unique<base::DictionaryValue>();
67     tooltip_options->SetString("text", tooltip_);
68     tooltip_options->SetBoolean("autoshow", autoshow_tooltip_);
69     result->Set("tooltip", std::move(tooltip_options));
70   }
71 
72   if (!aria_label_.empty())
73     result->SetString("ariaLabel", aria_label_);
74 
75   if (hardlock_on_click_)
76     result->SetBoolean("hardlockOnClick", true);
77 
78   return result;
79 }
80 
SetIcon(ScreenlockBridge::UserPodCustomIcon icon)81 void ScreenlockBridge::UserPodCustomIconOptions::SetIcon(
82     ScreenlockBridge::UserPodCustomIcon icon) {
83   icon_ = icon;
84 }
85 
SetTooltip(const base::string16 & tooltip,bool autoshow)86 void ScreenlockBridge::UserPodCustomIconOptions::SetTooltip(
87     const base::string16& tooltip,
88     bool autoshow) {
89   tooltip_ = tooltip;
90   autoshow_tooltip_ = autoshow;
91 }
92 
SetAriaLabel(const base::string16 & aria_label)93 void ScreenlockBridge::UserPodCustomIconOptions::SetAriaLabel(
94     const base::string16& aria_label) {
95   aria_label_ = aria_label;
96 }
97 
SetHardlockOnClick()98 void ScreenlockBridge::UserPodCustomIconOptions::SetHardlockOnClick() {
99   hardlock_on_click_ = true;
100 }
101 
GetIDString() const102 std::string ScreenlockBridge::UserPodCustomIconOptions::GetIDString() const {
103   return GetIdForIcon(icon_);
104 }
105 
106 // static
Get()107 ScreenlockBridge* ScreenlockBridge::Get() {
108   return g_screenlock_bridge_instance.Pointer();
109 }
110 
SetLockHandler(LockHandler * lock_handler)111 void ScreenlockBridge::SetLockHandler(LockHandler* lock_handler) {
112   // Don't notify observers if there is no change -- i.e. if the screen was
113   // already unlocked, and is remaining unlocked.
114   if (lock_handler == lock_handler_)
115     return;
116 
117   DCHECK(lock_handler_ == nullptr || lock_handler == nullptr);
118 
119   // TODO(isherman): If |lock_handler| is null, then |lock_handler_| might have
120   // been freed. Cache the screen type rather than querying it below.
121   LockHandler::ScreenType screen_type;
122   if (lock_handler_)
123     screen_type = lock_handler_->GetScreenType();
124   else
125     screen_type = lock_handler->GetScreenType();
126 
127   lock_handler_ = lock_handler;
128   if (lock_handler_) {
129     for (auto& observer : observers_)
130       observer.OnScreenDidLock(screen_type);
131   } else {
132     focused_account_id_ = EmptyAccountId();
133     for (auto& observer : observers_)
134       observer.OnScreenDidUnlock(screen_type);
135   }
136 }
137 
SetFocusedUser(const AccountId & account_id)138 void ScreenlockBridge::SetFocusedUser(const AccountId& account_id) {
139   if (account_id == focused_account_id_)
140     return;
141   focused_account_id_ = account_id;
142   for (auto& observer : observers_)
143     observer.OnFocusedUserChanged(account_id);
144 }
145 
IsLocked() const146 bool ScreenlockBridge::IsLocked() const {
147   return lock_handler_ != nullptr;
148 }
149 
Lock()150 void ScreenlockBridge::Lock() {
151   chromeos::SessionManagerClient::Get()->RequestLockScreen();
152 }
153 
Unlock(const AccountId & account_id)154 void ScreenlockBridge::Unlock(const AccountId& account_id) {
155   if (lock_handler_)
156     lock_handler_->Unlock(account_id);
157 }
158 
AddObserver(Observer * observer)159 void ScreenlockBridge::AddObserver(Observer* observer) {
160   observers_.AddObserver(observer);
161 }
162 
RemoveObserver(Observer * observer)163 void ScreenlockBridge::RemoveObserver(Observer* observer) {
164   observers_.RemoveObserver(observer);
165 }
166 
ScreenlockBridge()167 ScreenlockBridge::ScreenlockBridge()
168     : lock_handler_(nullptr), focused_account_id_(EmptyAccountId()) {}
169 
~ScreenlockBridge()170 ScreenlockBridge::~ScreenlockBridge() {}
171 
172 }  // namespace proximity_auth
173