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