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 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 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 61 ScreenlockPrivateGetLockedFunction::ScreenlockPrivateGetLockedFunction() {} 62 63 ScreenlockPrivateGetLockedFunction::~ScreenlockPrivateGetLockedFunction() {} 64 65 bool ScreenlockPrivateGetLockedFunction::RunAsync() { 66 SetResult(new base::FundamentalValue(ScreenlockBridge::Get()->IsLocked())); 67 SendResponse(error_.empty()); 68 return true; 69 } 70 71 ScreenlockPrivateSetLockedFunction::ScreenlockPrivateSetLockedFunction() {} 72 73 ScreenlockPrivateSetLockedFunction::~ScreenlockPrivateSetLockedFunction() {} 74 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 87 ScreenlockPrivateShowMessageFunction::ScreenlockPrivateShowMessageFunction() {} 88 89 ScreenlockPrivateShowMessageFunction::~ScreenlockPrivateShowMessageFunction() {} 90 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:: 104 ScreenlockPrivateShowCustomIconFunction() {} 105 106 ScreenlockPrivateShowCustomIconFunction:: 107 ~ScreenlockPrivateShowCustomIconFunction() {} 108 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 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:: 174 ScreenlockPrivateHideCustomIconFunction() { 175 } 176 177 ScreenlockPrivateHideCustomIconFunction:: 178 ~ScreenlockPrivateHideCustomIconFunction() { 179 } 180 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 194 ScreenlockPrivateSetAuthTypeFunction::ScreenlockPrivateSetAuthTypeFunction() {} 195 196 ScreenlockPrivateSetAuthTypeFunction::~ScreenlockPrivateSetAuthTypeFunction() {} 197 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 219 ScreenlockPrivateGetAuthTypeFunction::ScreenlockPrivateGetAuthTypeFunction() {} 220 221 ScreenlockPrivateGetAuthTypeFunction::~ScreenlockPrivateGetAuthTypeFunction() {} 222 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:: 240 ScreenlockPrivateAcceptAuthAttemptFunction() {} 241 242 ScreenlockPrivateAcceptAuthAttemptFunction:: 243 ~ScreenlockPrivateAcceptAuthAttemptFunction() {} 244 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 265 ScreenlockPrivateEventRouter::ScreenlockPrivateEventRouter( 266 content::BrowserContext* context) 267 : browser_context_(context) { 268 ScreenlockBridge::Get()->AddObserver(this); 269 } 270 271 ScreenlockPrivateEventRouter::~ScreenlockPrivateEventRouter() {} 272 273 void ScreenlockPrivateEventRouter::OnScreenDidLock() { 274 DispatchEvent(screenlock::OnChanged::kEventName, 275 new base::FundamentalValue(true)); 276 } 277 278 void ScreenlockPrivateEventRouter::OnScreenDidUnlock() { 279 DispatchEvent(screenlock::OnChanged::kEventName, 280 new base::FundamentalValue(false)); 281 } 282 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>* 299 ScreenlockPrivateEventRouter::GetFactoryInstance() { 300 return g_factory.Pointer(); 301 } 302 303 void ScreenlockPrivateEventRouter::Shutdown() { 304 ScreenlockBridge::Get()->RemoveObserver(this); 305 } 306 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