Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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/chromeos/extensions/echo_private_api.h"
      6 
      7 #include <string>
      8 
      9 #include "base/bind.h"
     10 #include "base/file_util.h"
     11 #include "base/location.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "base/time/time.h"
     15 #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
     16 #include "chrome/browser/chromeos/settings/cros_settings.h"
     17 #include "chrome/browser/chromeos/system/statistics_provider.h"
     18 #include "chrome/browser/chromeos/ui/echo_dialog_view.h"
     19 #include "chrome/browser/ui/browser.h"
     20 #include "chrome/browser/ui/browser_window.h"
     21 #include "chrome/common/extensions/api/echo_private.h"
     22 #include "chrome/common/extensions/extension.h"
     23 #include "content/public/browser/browser_thread.h"
     24 
     25 namespace echo_api = extensions::api::echo_private;
     26 
     27 using content::BrowserThread;
     28 
     29 namespace {
     30 
     31 // URL of "More info" link shown in echo dialog in GetUserConsent function.
     32 const char kMoreInfoLink[] =
     33     "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html?"
     34     "answer=2677280";
     35 
     36 }  // namespace
     37 
     38 EchoPrivateGetRegistrationCodeFunction::
     39     EchoPrivateGetRegistrationCodeFunction() {}
     40 
     41 EchoPrivateGetRegistrationCodeFunction::
     42     ~EchoPrivateGetRegistrationCodeFunction() {}
     43 
     44 void EchoPrivateGetRegistrationCodeFunction::GetRegistrationCode(
     45     const std::string& type) {
     46   if (!chromeos::KioskModeSettings::Get()->is_initialized()) {
     47     chromeos::KioskModeSettings::Get()->Initialize(base::Bind(
     48         &EchoPrivateGetRegistrationCodeFunction::GetRegistrationCode,
     49         this, type));
     50     return;
     51   }
     52   // Possible ECHO code type and corresponding key name in StatisticsProvider.
     53   const std::string kCouponType = "COUPON_CODE";
     54   const std::string kGroupType = "GROUP_CODE";
     55 
     56   chromeos::system::StatisticsProvider* provider =
     57       chromeos::system::StatisticsProvider::GetInstance();
     58   std::string result;
     59   if (!chromeos::KioskModeSettings::Get()->IsKioskModeEnabled()) {
     60     // In Kiosk mode, we effectively disable the registration API
     61     // by always returning an empty code.
     62     if (type == kCouponType) {
     63       provider->GetMachineStatistic(chromeos::system::kOffersCouponCodeKey,
     64                                     &result);
     65     } else if (type == kGroupType) {
     66       provider->GetMachineStatistic(chromeos::system::kOffersGroupCodeKey,
     67                                     &result);
     68     }
     69   }
     70 
     71   results_ = echo_api::GetRegistrationCode::Results::Create(result);
     72   SendResponse(true);
     73 }
     74 
     75 bool EchoPrivateGetRegistrationCodeFunction::RunImpl() {
     76   scoped_ptr<echo_api::GetRegistrationCode::Params> params =
     77       echo_api::GetRegistrationCode::Params::Create(*args_);
     78   EXTENSION_FUNCTION_VALIDATE(params);
     79   GetRegistrationCode(params->type);
     80   return true;
     81 }
     82 
     83 EchoPrivateGetOobeTimestampFunction::EchoPrivateGetOobeTimestampFunction() {
     84 }
     85 
     86 EchoPrivateGetOobeTimestampFunction::~EchoPrivateGetOobeTimestampFunction() {
     87 }
     88 
     89 bool EchoPrivateGetOobeTimestampFunction::RunImpl() {
     90   BrowserThread::PostTaskAndReplyWithResult(
     91       BrowserThread::FILE, FROM_HERE,
     92       base::Bind(
     93           &EchoPrivateGetOobeTimestampFunction::GetOobeTimestampOnFileThread,
     94           this),
     95       base::Bind(
     96           &EchoPrivateGetOobeTimestampFunction::SendResponse, this));
     97   return true;
     98 }
     99 
    100 // Get the OOBE timestamp from file /home/chronos/.oobe_completed.
    101 // The timestamp is used to determine when the user first activates the device.
    102 // If we can get the timestamp info, return it as yyyy-mm-dd, otherwise, return
    103 // an empty string.
    104 bool EchoPrivateGetOobeTimestampFunction::GetOobeTimestampOnFileThread() {
    105   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    106 
    107   const char kOobeTimestampFile[] = "/home/chronos/.oobe_completed";
    108   std::string timestamp = "";
    109   base::PlatformFileInfo fileInfo;
    110   if (file_util::GetFileInfo(base::FilePath(kOobeTimestampFile), &fileInfo)) {
    111     base::Time::Exploded ctime;
    112     fileInfo.creation_time.UTCExplode(&ctime);
    113     timestamp += base::StringPrintf("%u-%u-%u",
    114                                     ctime.year,
    115                                     ctime.month,
    116                                     ctime.day_of_month);
    117   }
    118   results_ = echo_api::GetOobeTimestamp::Results::Create(timestamp);
    119   return true;
    120 }
    121 
    122 EchoPrivateCheckAllowRedeemOffersFunction::
    123     EchoPrivateCheckAllowRedeemOffersFunction() {
    124 }
    125 
    126 EchoPrivateCheckAllowRedeemOffersFunction::
    127     ~EchoPrivateCheckAllowRedeemOffersFunction() {
    128 }
    129 
    130 void EchoPrivateCheckAllowRedeemOffersFunction::CheckAllowRedeemOffers() {
    131   chromeos::CrosSettingsProvider::TrustedStatus status =
    132       chromeos::CrosSettings::Get()->PrepareTrustedValues(base::Bind(
    133           &EchoPrivateCheckAllowRedeemOffersFunction::CheckAllowRedeemOffers,
    134           this));
    135   if (status == chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
    136     return;
    137 
    138   bool allow = true;
    139   chromeos::CrosSettings::Get()->GetBoolean(
    140       chromeos::kAllowRedeemChromeOsRegistrationOffers, &allow);
    141   results_ = echo_api::CheckAllowRedeemOffers::Results::Create(allow);
    142   SendResponse(true);
    143 }
    144 
    145 // Check the enterprise policy kAllowRedeemChromeOsRegistrationOffers flag
    146 // value. This policy is used to control whether user can redeem offers using
    147 // enterprise device.
    148 bool EchoPrivateCheckAllowRedeemOffersFunction::RunImpl() {
    149   CheckAllowRedeemOffers();
    150   return true;
    151 }
    152 
    153 EchoPrivateGetUserConsentFunction::EchoPrivateGetUserConsentFunction()
    154     : redeem_offers_allowed_(false) {
    155 }
    156 
    157 // static
    158 scoped_refptr<EchoPrivateGetUserConsentFunction>
    159 EchoPrivateGetUserConsentFunction::CreateForTest(
    160       const DialogShownTestCallback& dialog_shown_callback) {
    161   scoped_refptr<EchoPrivateGetUserConsentFunction> function(
    162       new EchoPrivateGetUserConsentFunction());
    163   function->dialog_shown_callback_ = dialog_shown_callback;
    164   return function;
    165 }
    166 
    167 EchoPrivateGetUserConsentFunction::~EchoPrivateGetUserConsentFunction() {}
    168 
    169 bool EchoPrivateGetUserConsentFunction::RunImpl() {
    170    CheckRedeemOffersAllowed();
    171    return true;
    172 }
    173 
    174 void EchoPrivateGetUserConsentFunction::OnAccept() {
    175   Finalize(true);
    176 }
    177 
    178 void EchoPrivateGetUserConsentFunction::OnCancel() {
    179   Finalize(false);
    180 }
    181 
    182 void EchoPrivateGetUserConsentFunction::OnMoreInfoLinkClicked() {
    183   chrome::NavigateParams params(profile(),
    184                                 GURL(kMoreInfoLink),
    185                                 content::PAGE_TRANSITION_LINK);
    186   // Open the link in a new window. The echo dialog is modal, so the current
    187   // window is useless until the dialog is closed.
    188   params.disposition = NEW_WINDOW;
    189   chrome::Navigate(&params);
    190 }
    191 
    192 void EchoPrivateGetUserConsentFunction::CheckRedeemOffersAllowed() {
    193   chromeos::CrosSettingsProvider::TrustedStatus status =
    194       chromeos::CrosSettings::Get()->PrepareTrustedValues(base::Bind(
    195           &EchoPrivateGetUserConsentFunction::CheckRedeemOffersAllowed,
    196           this));
    197   if (status == chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
    198     return;
    199 
    200   bool allow = true;
    201   chromeos::CrosSettings::Get()->GetBoolean(
    202       chromeos::kAllowRedeemChromeOsRegistrationOffers, &allow);
    203 
    204   OnRedeemOffersAllowedChecked(allow);
    205 }
    206 
    207 void EchoPrivateGetUserConsentFunction::OnRedeemOffersAllowedChecked(
    208     bool is_allowed) {
    209   redeem_offers_allowed_ = is_allowed;
    210 
    211   scoped_ptr<echo_api::GetUserConsent::Params> params =
    212       echo_api::GetUserConsent::Params::Create(*args_);
    213 
    214   // Verify that the passed origin URL is valid.
    215   GURL service_origin = GURL(params->consent_requester.origin);
    216   if (!service_origin.is_valid()) {
    217     error_ = "Invalid origin.";
    218     SendResponse(false);
    219     return;
    220   }
    221 
    222   // Add ref to ensure the function stays around until the dialog listener is
    223   // called. The reference is release in |Finalize|.
    224   AddRef();
    225 
    226   // Create and show the dialog.
    227   chromeos::EchoDialogView* dialog = new chromeos::EchoDialogView(this);
    228   if (redeem_offers_allowed_) {
    229     dialog->InitForEnabledEcho(
    230         UTF8ToUTF16(params->consent_requester.service_name),
    231         UTF8ToUTF16(params->consent_requester.origin));
    232   } else {
    233     dialog->InitForDisabledEcho();
    234   }
    235   dialog->Show(GetCurrentBrowser()->window()->GetNativeWindow());
    236 
    237   // If there is a dialog_shown_callback_, invoke it with the created dialog.
    238   if (!dialog_shown_callback_.is_null())
    239     dialog_shown_callback_.Run(dialog);
    240 }
    241 
    242 void EchoPrivateGetUserConsentFunction::Finalize(bool consent) {
    243   // Consent should not be true if offers redeeming is disabled.
    244   CHECK(redeem_offers_allowed_ || !consent);
    245   results_ = echo_api::GetUserConsent::Results::Create(consent);
    246   SendResponse(true);
    247 
    248   // Release the reference added in |OnRedeemOffersAllowedChecked|, before
    249   // showing the dialog.
    250   Release();
    251 }
    252