OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/apps_promo.h" | 5 #include "chrome/browser/extensions/apps_promo.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
11 #include "chrome/browser/prefs/pref_service.h" | 11 #include "chrome/browser/prefs/pref_service.h" |
12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/common/chrome_notification_types.h" | 13 #include "chrome/common/chrome_notification_types.h" |
14 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
15 #include "chrome/common/extensions/extension.h" | 15 #include "chrome/common/extensions/extension.h" |
16 #include "chrome/common/pref_names.h" | 16 #include "chrome/common/pref_names.h" |
17 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
18 #include "content/public/common/url_constants.h" | 18 #include "content/public/common/url_constants.h" |
19 #include "net/base/load_flags.h" | |
20 #include "net/url_request/url_fetcher.h" | |
21 #include "net/url_request/url_request_status.h" | |
22 | 19 |
23 const int AppsPromo::kDefaultAppsCounterMax = 10; | 20 const int AppsPromo::kDefaultAppsCounterMax = 10; |
24 | 21 |
25 namespace { | 22 namespace { |
26 | 23 |
27 // The default logo for the promo. | 24 // The default logo for the promo. |
28 const char kDefaultLogo[] = "chrome://theme/IDR_WEBSTORE_ICON"; | 25 const char kDefaultLogo[] = "chrome://theme/IDR_WEBSTORE_ICON"; |
29 | 26 |
30 // The default promo data (this is only used for testing with | 27 // The default promo data (this is only used for testing with |
31 // --force-apps-promo-visible). | 28 // --force-apps-promo-visible). |
32 const char kDefaultHeader[] = "Browse thousands of apps and games for Chrome"; | 29 const char kDefaultHeader[] = "Browse thousands of apps and games for Chrome"; |
33 const char kDefaultButton[] = "Visit the Chrome Web Store"; | 30 const char kDefaultButton[] = "Visit the Chrome Web Store"; |
34 const char kDefaultExpire[] = "No thanks"; | 31 const char kDefaultExpire[] = "No thanks"; |
35 const char kDefaultLink[] = "https://chrome.google.com/webstore"; | 32 const char kDefaultLink[] = "https://chrome.google.com/webstore"; |
36 | 33 |
37 // Http success status code. | |
38 const int kHttpSuccess = 200; | |
39 | |
40 // The match pattern for valid logo URLs. | |
41 const char kValidLogoPattern[] = "https://*.google.com/*.png"; | |
42 | |
43 // The prefix for 'data' URL images. | |
44 const char kPNGDataURLPrefix[] = "data:image/png;base64,"; | |
45 | |
46 // Returns the string pref at |path|, using |fallback| as the default (if there | 34 // Returns the string pref at |path|, using |fallback| as the default (if there |
47 // is no pref value present). |fallback| is used for debugging in concert with | 35 // is no pref value present). |fallback| is used for debugging in concert with |
48 // --force-apps-promo-visible. | 36 // --force-apps-promo-visible. |
49 std::string GetStringPref(const char* path, const std::string& fallback) { | 37 std::string GetStringPref(const char* path, const std::string& fallback) { |
50 PrefService* local_state = g_browser_process->local_state(); | 38 PrefService* local_state = g_browser_process->local_state(); |
51 std::string retval(local_state->GetString(path)); | 39 std::string retval(local_state->GetString(path)); |
52 if (retval.empty() && CommandLine::ForCurrentProcess()->HasSwitch( | 40 if (retval.empty() && CommandLine::ForCurrentProcess()->HasSwitch( |
53 switches::kForceAppsPromoVisible)) { | 41 switches::kForceAppsPromoVisible)) { |
54 retval = fallback; | 42 retval = fallback; |
55 } | 43 } |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 bool AppsPromo::GetDefaultAppsInstalled() const { | 290 bool AppsPromo::GetDefaultAppsInstalled() const { |
303 return prefs_->GetBoolean(prefs::kDefaultAppsInstalled); | 291 return prefs_->GetBoolean(prefs::kDefaultAppsInstalled); |
304 } | 292 } |
305 | 293 |
306 AppsPromo::UserGroup AppsPromo::GetCurrentUserGroup() const { | 294 AppsPromo::UserGroup AppsPromo::GetCurrentUserGroup() const { |
307 const PrefService::Preference* last_promo_id | 295 const PrefService::Preference* last_promo_id |
308 = prefs_->FindPreference(prefs::kNtpWebStorePromoLastId); | 296 = prefs_->FindPreference(prefs::kNtpWebStorePromoLastId); |
309 CHECK(last_promo_id); | 297 CHECK(last_promo_id); |
310 return last_promo_id->IsDefaultValue() ? USERS_NEW : USERS_EXISTING; | 298 return last_promo_id->IsDefaultValue() ? USERS_NEW : USERS_EXISTING; |
311 } | 299 } |
312 | |
313 AppsPromoLogoFetcher::AppsPromoLogoFetcher( | |
314 Profile* profile, | |
315 const AppsPromo::PromoData& promo_data) | |
316 : profile_(profile), | |
317 promo_data_(promo_data) { | |
318 if (SupportsLogoURL()) { | |
319 if (HaveCachedLogo()) { | |
320 promo_data_.logo = AppsPromo::GetPromo().logo; | |
321 SavePromo(); | |
322 } else { | |
323 FetchLogo(); | |
324 } | |
325 } else { | |
326 // We only care about the source URL when this fetches the logo. | |
327 AppsPromo::SetSourcePromoLogoURL(GURL()); | |
328 SavePromo(); | |
329 } | |
330 } | |
331 | |
332 AppsPromoLogoFetcher::~AppsPromoLogoFetcher() {} | |
333 | |
334 void AppsPromoLogoFetcher::OnURLFetchComplete( | |
335 const net::URLFetcher* source) { | |
336 std::string data; | |
337 std::string base64_data; | |
338 | |
339 CHECK(source == url_fetcher_.get()); | |
340 source->GetResponseAsString(&data); | |
341 | |
342 if (source->GetStatus().is_success() && | |
343 source->GetResponseCode() == kHttpSuccess && | |
344 base::Base64Encode(data, &base64_data)) { | |
345 AppsPromo::SetSourcePromoLogoURL(promo_data_.logo); | |
346 promo_data_.logo = GURL(kPNGDataURLPrefix + base64_data); | |
347 } else { | |
348 // The logo wasn't downloaded correctly or we failed to encode it in | |
349 // base64. Reset the source URL so we fetch it again next time. AppsPromo | |
350 // will revert to the default logo. | |
351 AppsPromo::SetSourcePromoLogoURL(GURL()); | |
352 } | |
353 | |
354 SavePromo(); | |
355 } | |
356 | |
357 void AppsPromoLogoFetcher::FetchLogo() { | |
358 CHECK(promo_data_.logo.scheme() == chrome::kHttpsScheme); | |
359 | |
360 url_fetcher_.reset(net::URLFetcher::Create( | |
361 0, promo_data_.logo, net::URLFetcher::GET, this)); | |
362 url_fetcher_->SetRequestContext( | |
363 g_browser_process->system_request_context()); | |
364 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
365 net::LOAD_DO_NOT_SAVE_COOKIES); | |
366 url_fetcher_->Start(); | |
367 } | |
368 | |
369 bool AppsPromoLogoFetcher::HaveCachedLogo() { | |
370 return promo_data_.logo == AppsPromo::GetSourcePromoLogoURL(); | |
371 } | |
372 | |
373 void AppsPromoLogoFetcher::SavePromo() { | |
374 AppsPromo::SetPromo(promo_data_); | |
375 | |
376 content::NotificationService::current()->Notify( | |
377 chrome::NOTIFICATION_WEB_STORE_PROMO_LOADED, | |
378 content::Source<Profile>(profile_), | |
379 content::NotificationService::NoDetails()); | |
380 } | |
381 | |
382 bool AppsPromoLogoFetcher::SupportsLogoURL() { | |
383 URLPattern allowed_urls(URLPattern::SCHEME_HTTPS, kValidLogoPattern); | |
384 return allowed_urls.MatchesURL(promo_data_.logo); | |
385 } | |
OLD | NEW |