1 // Copyright 2013 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/extensions/api/screenlock_private/screenlock_private_api.h"
6
7 #include <vector>
8
9 #include "base/lazy_instance.h"
10 #include "base/values.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/common/extensions/api/screenlock_private.h"
13 #include "extensions/browser/event_router.h"
14 #include "extensions/browser/image_loader.h"
15 #include "ui/gfx/image/image.h"
16
17 namespace screenlock = extensions::api::screenlock_private;
18
19 namespace extensions {
20
21 namespace {
22
23 const char kNotLockedError[] = "Screen is not currently locked.";
24 const char kInvalidIconError[] = "Invalid custom icon data.";
25
ToLockHandlerAuthType(screenlock::AuthType auth_type)26 ScreenlockBridge::LockHandler::AuthType ToLockHandlerAuthType(
27 screenlock::AuthType auth_type) {
28 switch (auth_type) {
29 case screenlock::AUTH_TYPE_OFFLINEPASSWORD:
30 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
31 case screenlock::AUTH_TYPE_NUMERICPIN:
32 return ScreenlockBridge::LockHandler::NUMERIC_PIN;
33 case screenlock::AUTH_TYPE_USERCLICK:
34 return ScreenlockBridge::LockHandler::USER_CLICK;
35 case screenlock::AUTH_TYPE_NONE:
36 break;
37 }
38 NOTREACHED();
39 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
40 }
41
FromLockHandlerAuthType(ScreenlockBridge::LockHandler::AuthType auth_type)42 screenlock::AuthType FromLockHandlerAuthType(
43 ScreenlockBridge::LockHandler::AuthType auth_type) {
44 switch (auth_type) {
45 case ScreenlockBridge::LockHandler::OFFLINE_PASSWORD:
46 return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
47 case ScreenlockBridge::LockHandler::NUMERIC_PIN:
48 return screenlock::AUTH_TYPE_NUMERICPIN;
49 case ScreenlockBridge::LockHandler::USER_CLICK:
50 return screenlock::AUTH_TYPE_USERCLICK;
51 case ScreenlockBridge::LockHandler::ONLINE_SIGN_IN:
52 // Apps should treat forced online sign in same as system password.
53 return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
54 }
55 NOTREACHED();
56 return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
57 }
58
59 } // namespace
60
ScreenlockPrivateGetLockedFunction()61 ScreenlockPrivateGetLockedFunction::ScreenlockPrivateGetLockedFunction() {}
62
~ScreenlockPrivateGetLockedFunction()63 ScreenlockPrivateGetLockedFunction::~ScreenlockPrivateGetLockedFunction() {}
64
RunAsync()65 bool ScreenlockPrivateGetLockedFunction::RunAsync() {
66 SetResult(new base::FundamentalValue(ScreenlockBridge::Get()->IsLocked()));
67 SendResponse(error_.empty());
68 return true;
69 }
70
ScreenlockPrivateSetLockedFunction()71 ScreenlockPrivateSetLockedFunction::ScreenlockPrivateSetLockedFunction() {}
72
~ScreenlockPrivateSetLockedFunction()73 ScreenlockPrivateSetLockedFunction::~ScreenlockPrivateSetLockedFunction() {}
74
RunAsync()75 bool ScreenlockPrivateSetLockedFunction::RunAsync() {
76 scoped_ptr<screenlock::SetLocked::Params> params(
77 screenlock::SetLocked::Params::Create(*args_));
78 EXTENSION_FUNCTION_VALIDATE(params.get());
79 if (params->locked)
80 ScreenlockBridge::Get()->Lock(GetProfile());
81 else
82 ScreenlockBridge::Get()->Unlock(GetProfile());
83 SendResponse(error_.empty());
84 return true;
85 }
86
ScreenlockPrivateShowMessageFunction()87 ScreenlockPrivateShowMessageFunction::ScreenlockPrivateShowMessageFunction() {}
88
~ScreenlockPrivateShowMessageFunction()89 ScreenlockPrivateShowMessageFunction::~ScreenlockPrivateShowMessageFunction() {}
90
RunAsync()91 bool ScreenlockPrivateShowMessageFunction::RunAsync() {
92 scoped_ptr<screenlock::ShowMessage::Params> params(
93 screenlock::ShowMessage::Params::Create(*args_));
94 EXTENSION_FUNCTION_VALIDATE(params.get());
95 ScreenlockBridge::LockHandler* locker =
96 ScreenlockBridge::Get()->lock_handler();
97 if (locker)
98 locker->ShowBannerMessage(params->message);
99 SendResponse(error_.empty());
100 return true;
101 }
102
103 ScreenlockPrivateShowCustomIconFunction::
ScreenlockPrivateShowCustomIconFunction()104 ScreenlockPrivateShowCustomIconFunction() {}
105
106 ScreenlockPrivateShowCustomIconFunction::
~ScreenlockPrivateShowCustomIconFunction()107 ~ScreenlockPrivateShowCustomIconFunction() {}
108
RunAsync()109 bool ScreenlockPrivateShowCustomIconFunction::RunAsync() {
110 scoped_ptr<screenlock::ShowCustomIcon::Params> params(
111 screenlock::ShowCustomIcon::Params::Create(*args_));
112 EXTENSION_FUNCTION_VALIDATE(params.get());
113 ScreenlockBridge::LockHandler* locker =
114 ScreenlockBridge::Get()->lock_handler();
115 if (!locker) {
116 SetError(kNotLockedError);
117 return false;
118 }
119
120 const int kMaxButtonIconSize = 40;
121 bool has_scale_100P = false;
122 std::vector<extensions::ImageLoader::ImageRepresentation> icon_info;
123 for (size_t i = 0; i < params->icon.size(); ++i) {
124 ui::ScaleFactor scale_factor;
125 if (params->icon[i]->scale_factor == 1.) {
126 scale_factor = ui::SCALE_FACTOR_100P;
127 } else if (params->icon[i]->scale_factor == 2.) {
128 scale_factor = ui::SCALE_FACTOR_200P;
129 } else {
130 continue;
131 }
132
133 ExtensionResource resource =
134 GetExtension()->GetResource(params->icon[i]->url);
135 if (resource.empty())
136 continue;
137
138 icon_info.push_back(
139 ImageLoader::ImageRepresentation(
140 resource,
141 ImageLoader::ImageRepresentation::RESIZE_WHEN_LARGER,
142 gfx::Size(kMaxButtonIconSize * params->icon[i]->scale_factor,
143 kMaxButtonIconSize * params->icon[i]->scale_factor),
144 scale_factor));
145 if (scale_factor == ui::SCALE_FACTOR_100P)
146 has_scale_100P = true;
147 }
148
149 if (!has_scale_100P) {
150 SetError(kInvalidIconError);
151 return false;
152 }
153
154 extensions::ImageLoader* loader = extensions::ImageLoader::Get(GetProfile());
155 loader->LoadImagesAsync(
156 GetExtension(),
157 icon_info,
158 base::Bind(&ScreenlockPrivateShowCustomIconFunction::OnImageLoaded,
159 this));
160 return true;
161 }
162
OnImageLoaded(const gfx::Image & image)163 void ScreenlockPrivateShowCustomIconFunction::OnImageLoaded(
164 const gfx::Image& image) {
165 ScreenlockBridge::LockHandler* locker =
166 ScreenlockBridge::Get()->lock_handler();
167 locker->ShowUserPodCustomIcon(
168 ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()),
169 image);
170 SendResponse(error_.empty());
171 }
172
173 ScreenlockPrivateHideCustomIconFunction::
ScreenlockPrivateHideCustomIconFunction()174 ScreenlockPrivateHideCustomIconFunction() {
175 }
176
177 ScreenlockPrivateHideCustomIconFunction::
~ScreenlockPrivateHideCustomIconFunction()178 ~ScreenlockPrivateHideCustomIconFunction() {
179 }
180
RunAsync()181 bool ScreenlockPrivateHideCustomIconFunction::RunAsync() {
182 ScreenlockBridge::LockHandler* locker =
183 ScreenlockBridge::Get()->lock_handler();
184 if (locker) {
185 locker->HideUserPodCustomIcon(
186 ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
187 } else {
188 SetError(kNotLockedError);
189 }
190 SendResponse(error_.empty());
191 return true;
192 }
193
ScreenlockPrivateSetAuthTypeFunction()194 ScreenlockPrivateSetAuthTypeFunction::ScreenlockPrivateSetAuthTypeFunction() {}
195
~ScreenlockPrivateSetAuthTypeFunction()196 ScreenlockPrivateSetAuthTypeFunction::~ScreenlockPrivateSetAuthTypeFunction() {}
197
RunAsync()198 bool ScreenlockPrivateSetAuthTypeFunction::RunAsync() {
199 scoped_ptr<screenlock::SetAuthType::Params> params(
200 screenlock::SetAuthType::Params::Create(*args_));
201 EXTENSION_FUNCTION_VALIDATE(params.get());
202
203 ScreenlockBridge::LockHandler* locker =
204 ScreenlockBridge::Get()->lock_handler();
205 if (locker) {
206 std::string initial_value =
207 params->initial_value.get() ? *(params->initial_value.get()) : "";
208 locker->SetAuthType(
209 ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()),
210 ToLockHandlerAuthType(params->auth_type),
211 initial_value);
212 } else {
213 SetError(kNotLockedError);
214 }
215 SendResponse(error_.empty());
216 return true;
217 }
218
ScreenlockPrivateGetAuthTypeFunction()219 ScreenlockPrivateGetAuthTypeFunction::ScreenlockPrivateGetAuthTypeFunction() {}
220
~ScreenlockPrivateGetAuthTypeFunction()221 ScreenlockPrivateGetAuthTypeFunction::~ScreenlockPrivateGetAuthTypeFunction() {}
222
RunAsync()223 bool ScreenlockPrivateGetAuthTypeFunction::RunAsync() {
224 ScreenlockBridge::LockHandler* locker =
225 ScreenlockBridge::Get()->lock_handler();
226 if (locker) {
227 ScreenlockBridge::LockHandler::AuthType auth_type = locker->GetAuthType(
228 ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
229 std::string auth_type_name =
230 screenlock::ToString(FromLockHandlerAuthType(auth_type));
231 SetResult(new base::StringValue(auth_type_name));
232 } else {
233 SetError(kNotLockedError);
234 }
235 SendResponse(error_.empty());
236 return true;
237 }
238
239 ScreenlockPrivateAcceptAuthAttemptFunction::
ScreenlockPrivateAcceptAuthAttemptFunction()240 ScreenlockPrivateAcceptAuthAttemptFunction() {}
241
242 ScreenlockPrivateAcceptAuthAttemptFunction::
~ScreenlockPrivateAcceptAuthAttemptFunction()243 ~ScreenlockPrivateAcceptAuthAttemptFunction() {}
244
RunAsync()245 bool ScreenlockPrivateAcceptAuthAttemptFunction::RunAsync() {
246 scoped_ptr<screenlock::AcceptAuthAttempt::Params> params(
247 screenlock::AcceptAuthAttempt::Params::Create(*args_));
248 EXTENSION_FUNCTION_VALIDATE(params.get());
249
250 ScreenlockBridge::LockHandler* locker =
251 ScreenlockBridge::Get()->lock_handler();
252 if (locker) {
253 if (params->accept) {
254 locker->Unlock(ScreenlockBridge::GetAuthenticatedUserEmail(GetProfile()));
255 } else {
256 locker->EnableInput();
257 }
258 } else {
259 SetError(kNotLockedError);
260 }
261 SendResponse(error_.empty());
262 return true;
263 }
264
ScreenlockPrivateEventRouter(content::BrowserContext * context)265 ScreenlockPrivateEventRouter::ScreenlockPrivateEventRouter(
266 content::BrowserContext* context)
267 : browser_context_(context) {
268 ScreenlockBridge::Get()->AddObserver(this);
269 }
270
~ScreenlockPrivateEventRouter()271 ScreenlockPrivateEventRouter::~ScreenlockPrivateEventRouter() {}
272
OnScreenDidLock()273 void ScreenlockPrivateEventRouter::OnScreenDidLock() {
274 DispatchEvent(screenlock::OnChanged::kEventName,
275 new base::FundamentalValue(true));
276 }
277
OnScreenDidUnlock()278 void ScreenlockPrivateEventRouter::OnScreenDidUnlock() {
279 DispatchEvent(screenlock::OnChanged::kEventName,
280 new base::FundamentalValue(false));
281 }
282
DispatchEvent(const std::string & event_name,base::Value * arg)283 void ScreenlockPrivateEventRouter::DispatchEvent(
284 const std::string& event_name,
285 base::Value* arg) {
286 scoped_ptr<base::ListValue> args(new base::ListValue());
287 if (arg)
288 args->Append(arg);
289 scoped_ptr<extensions::Event> event(new extensions::Event(
290 event_name, args.Pass()));
291 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
292 }
293
294 static base::LazyInstance<extensions::BrowserContextKeyedAPIFactory<
295 ScreenlockPrivateEventRouter> > g_factory = LAZY_INSTANCE_INITIALIZER;
296
297 // static
298 extensions::BrowserContextKeyedAPIFactory<ScreenlockPrivateEventRouter>*
GetFactoryInstance()299 ScreenlockPrivateEventRouter::GetFactoryInstance() {
300 return g_factory.Pointer();
301 }
302
Shutdown()303 void ScreenlockPrivateEventRouter::Shutdown() {
304 ScreenlockBridge::Get()->RemoveObserver(this);
305 }
306
OnAuthAttempted(ScreenlockBridge::LockHandler::AuthType auth_type,const std::string & value)307 void ScreenlockPrivateEventRouter::OnAuthAttempted(
308 ScreenlockBridge::LockHandler::AuthType auth_type,
309 const std::string& value) {
310 scoped_ptr<base::ListValue> args(new base::ListValue());
311 args->AppendString(screenlock::ToString(FromLockHandlerAuthType(auth_type)));
312 args->AppendString(value);
313
314 scoped_ptr<extensions::Event> event(new extensions::Event(
315 screenlock::OnAuthAttempted::kEventName, args.Pass()));
316 extensions::EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
317 }
318
319 } // namespace extensions
320