Home | History | Annotate | Download | only in screenlock_private
      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