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/signin/screenlock_bridge.h"
6
7#include "base/logging.h"
8#include "base/strings/string16.h"
9#include "chrome/browser/profiles/profile_window.h"
10#include "chrome/browser/signin/signin_manager_factory.h"
11#include "components/signin/core/browser/signin_manager.h"
12
13#if defined(OS_CHROMEOS)
14#include "chromeos/dbus/dbus_thread_manager.h"
15#include "chromeos/dbus/session_manager_client.h"
16#endif
17
18namespace {
19
20base::LazyInstance<ScreenlockBridge> g_screenlock_bridge_bridge_instance =
21    LAZY_INSTANCE_INITIALIZER;
22
23// Ids for the icons that are supported by lock screen and signin screen
24// account picker as user pod custom icons.
25// The id's should be kept in sync with values used by user_pod_row.js.
26const char kLockedUserPodCustomIconId[] = "locked";
27const char kUnlockedUserPodCustomIconId[] = "unlocked";
28const char kHardlockedUserPodCustomIconId[] = "hardlocked";
29const char kSpinnerUserPodCustomIconId[] = "spinner";
30
31// Given the user pod icon, returns its id as used by the user pod UI code.
32std::string GetIdForIcon(ScreenlockBridge::UserPodCustomIcon icon) {
33  switch (icon) {
34    case ScreenlockBridge::USER_POD_CUSTOM_ICON_LOCKED:
35      return kLockedUserPodCustomIconId;
36    case ScreenlockBridge::USER_POD_CUSTOM_ICON_UNLOCKED:
37      return kUnlockedUserPodCustomIconId;
38    case ScreenlockBridge::USER_POD_CUSTOM_ICON_HARDLOCKED:
39      return kHardlockedUserPodCustomIconId;
40    case ScreenlockBridge::USER_POD_CUSTOM_ICON_SPINNER:
41      return kSpinnerUserPodCustomIconId;
42    default:
43      return "";
44  }
45}
46
47}  // namespace
48
49// static
50ScreenlockBridge* ScreenlockBridge::Get() {
51  return g_screenlock_bridge_bridge_instance.Pointer();
52}
53
54ScreenlockBridge::UserPodCustomIconOptions::UserPodCustomIconOptions()
55    : autoshow_tooltip_(false),
56      hardlock_on_click_(false) {
57}
58
59ScreenlockBridge::UserPodCustomIconOptions::~UserPodCustomIconOptions() {}
60
61scoped_ptr<base::DictionaryValue>
62ScreenlockBridge::UserPodCustomIconOptions::ToDictionaryValue() const {
63  scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
64  std::string icon_id = GetIdForIcon(icon_);
65  result->SetString("id", icon_id);
66
67  if (!tooltip_.empty()) {
68    base::DictionaryValue* tooltip_options = new base::DictionaryValue();
69    tooltip_options->SetString("text", tooltip_);
70    tooltip_options->SetBoolean("autoshow", autoshow_tooltip_);
71    result->Set("tooltip", tooltip_options);
72  }
73
74  if (!aria_label_.empty())
75    result->SetString("ariaLabel", aria_label_);
76
77  if (hardlock_on_click_)
78    result->SetBoolean("hardlockOnClick", true);
79
80  return result.Pass();
81}
82
83void ScreenlockBridge::UserPodCustomIconOptions::SetIcon(
84    ScreenlockBridge::UserPodCustomIcon icon) {
85  icon_ = icon;
86}
87
88void ScreenlockBridge::UserPodCustomIconOptions::SetTooltip(
89    const base::string16& tooltip,
90    bool autoshow) {
91  tooltip_ = tooltip;
92  autoshow_tooltip_ = autoshow;
93}
94
95void ScreenlockBridge::UserPodCustomIconOptions::SetAriaLabel(
96    const base::string16& aria_label) {
97  aria_label_ = aria_label;
98}
99
100void ScreenlockBridge::UserPodCustomIconOptions::SetHardlockOnClick() {
101  hardlock_on_click_ = true;
102}
103
104// static
105std::string ScreenlockBridge::GetAuthenticatedUserEmail(Profile* profile) {
106  // |profile| has to be a signed-in profile with SigninManager already
107  // created. Otherwise, just crash to collect stack.
108  SigninManagerBase* signin_manager =
109      SigninManagerFactory::GetForProfileIfExists(profile);
110  return signin_manager->GetAuthenticatedUsername();
111}
112
113ScreenlockBridge::ScreenlockBridge() : lock_handler_(NULL) {
114}
115
116ScreenlockBridge::~ScreenlockBridge() {
117}
118
119void ScreenlockBridge::SetLockHandler(LockHandler* lock_handler) {
120  DCHECK(lock_handler_ == NULL || lock_handler == NULL);
121  lock_handler_ = lock_handler;
122  if (lock_handler_)
123    FOR_EACH_OBSERVER(Observer, observers_, OnScreenDidLock());
124  else
125    FOR_EACH_OBSERVER(Observer, observers_, OnScreenDidUnlock());
126}
127
128void ScreenlockBridge::SetFocusedUser(const std::string& user_id) {
129  if (user_id == focused_user_id_)
130    return;
131  focused_user_id_ = user_id;
132  FOR_EACH_OBSERVER(Observer, observers_, OnFocusedUserChanged(user_id));
133}
134
135bool ScreenlockBridge::IsLocked() const {
136  return lock_handler_ != NULL;
137}
138
139void ScreenlockBridge::Lock(Profile* profile) {
140#if defined(OS_CHROMEOS)
141  chromeos::SessionManagerClient* session_manager =
142      chromeos::DBusThreadManager::Get()->GetSessionManagerClient();
143  session_manager->RequestLockScreen();
144#else
145  profiles::LockProfile(profile);
146#endif
147}
148
149void ScreenlockBridge::Unlock(Profile* profile) {
150  if (lock_handler_)
151    lock_handler_->Unlock(GetAuthenticatedUserEmail(profile));
152}
153
154void ScreenlockBridge::AddObserver(Observer* observer) {
155  observers_.AddObserver(observer);
156}
157
158void ScreenlockBridge::RemoveObserver(Observer* observer) {
159  observers_.RemoveObserver(observer);
160}
161