1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/web_resource/promo_resource_service.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/string_number_conversions.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/threading/thread_restrictions.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/time.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/values.h" 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/browser_process.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/apps_promo.h" 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/platform_util.h" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/prefs/pref_service.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/profiles/profile.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/sync/sync_ui_util.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/pref_names.h" 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "googleurl/src/gurl.h" 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace { 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Delay on first fetch so we don't interfere with startup. 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kStartResourceFetchDelay = 5000; 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Delay between calls to update the cache (48 hours). 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// to be able to roll out promos slowly, or display different promos to 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// different groups. 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kNTPPromoGroupSize = 16; 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Maximum number of hours for each time slice (4 weeks). 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kMaxTimeSliceHours = 24 * 7 * 4; 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// The version of the service (used to expire the cache when upgrading Chrome 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// to versions with different types of promos). 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const int kPromoServiceVersion = 1; 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Properties used by the server. 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kAnswerIdProperty[] = "answer_id"; 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kWebStoreHeaderProperty[] = "question"; 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kWebStoreButtonProperty[] = "inproduct_target"; 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kWebStoreLinkProperty[] = "inproduct"; 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char kWebStoreExpireProperty[] = "tooltip"; 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Server for dynamically loaded NTP HTML elements. TODO(mirandac): append 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// locale for future usage, when we're serving localizable strings. 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char* PromoResourceService::kDefaultPromoResourceServer = 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PromoResourceService::RegisterPrefs(PrefService* local_state) { 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PromoResourceService::RegisterUserPrefs(PrefService* prefs) { 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart, 0); 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd, 0); 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterDoublePref(prefs::kNTPPromoStart, 0); 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterDoublePref(prefs::kNTPPromoEnd, 0); 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterStringPref(prefs::kNTPPromoLine, std::string()); 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, false); 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, -1); 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterIntegerPref(prefs::kNTPPromoBuild, 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CANARY_BUILD | DEV_BUILD | BETA_BUILD | STABLE_BUILD); 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, 0); 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool PromoResourceService::IsBuildTargeted(const std::string& channel, 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int builds_allowed) { 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (builds_allowed == NO_BUILD) 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (channel == "canary" || channel == "canary-m") { 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (CANARY_BUILD & builds_allowed) != 0; 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (channel == "dev" || channel == "dev-m") { 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (DEV_BUILD & builds_allowed) != 0; 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (channel == "beta" || channel == "beta-m") { 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (BETA_BUILD & builds_allowed) != 0; 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (channel == "" || channel == "m") { 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (STABLE_BUILD & builds_allowed) != 0; 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 95dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenPromoResourceService::PromoResourceService(Profile* profile) 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen : WebResourceService(profile, 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen profile->GetPrefs(), 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PromoResourceService::kDefaultPromoResourceServer, 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen true, // append locale to URL 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NotificationType::PROMO_RESOURCE_STATE_CHANGED, 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs::kNTPPromoResourceCacheUpdate, 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kStartResourceFetchDelay, 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen kCacheUpdateDelay), 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_resource_cache_(NULL), 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen channel_(NULL) { 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Init(); 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenPromoResourceService::~PromoResourceService() { } 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PromoResourceService::Init() { 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ScheduleNotificationOnInit(); 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool PromoResourceService::IsThisBuildTargeted(int builds_targeted) { 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (channel_ == NULL) { 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io; 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen channel_ = platform_util::GetVersionStringModifier().c_str(); 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return IsBuildTargeted(channel_, builds_targeted); 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PromoResourceService::Unpack(const DictionaryValue& parsed_json) { 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UnpackLogoSignal(parsed_json); 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen UnpackPromoSignal(parsed_json); 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UnpackWebStoreSignal(parsed_json); 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PromoResourceService::ScheduleNotification(double promo_start, 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double promo_end) { 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (promo_start > 0 && promo_end > 0) { 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int64 ms_until_start = 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<int64>((base::Time::FromDoubleT( 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_start) - base::Time::Now()).InMilliseconds()); 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int64 ms_until_end = 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<int64>((base::Time::FromDoubleT( 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_end) - base::Time::Now()).InMilliseconds()); 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ms_until_start > 0) 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PostNotification(ms_until_start); 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ms_until_end > 0) { 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PostNotification(ms_until_end); 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (ms_until_start <= 0) { 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Notify immediately if time is between start and end. 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PostNotification(0); 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PromoResourceService::ScheduleNotificationOnInit() { 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string locale = g_browser_process->GetApplicationLocale(); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if ((GetPromoServiceVersion() != kPromoServiceVersion) || 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (GetPromoLocale() != locale)) { 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the promo service has been upgraded or Chrome switched locales, 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // refresh the promos. 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PrefService* local_state = g_browser_process->local_state(); 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen local_state->SetInteger(prefs::kNTPPromoVersion, kPromoServiceVersion); 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen local_state->SetString(prefs::kNTPPromoLocale, locale); 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs_->ClearPref(prefs::kNTPPromoResourceCacheUpdate); 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AppsPromo::ClearPromo(); 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PostNotification(0); 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the promo start is in the future, set a notification task to 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // invalidate the NTP cache at the time of the promo start. 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ScheduleNotification(promo_start, promo_end); 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint PromoResourceService::GetPromoServiceVersion() { 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PrefService* local_state = g_browser_process->local_state(); 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return local_state->GetInteger(prefs::kNTPPromoVersion); 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::string PromoResourceService::GetPromoLocale() { 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PrefService* local_state = g_browser_process->local_state(); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return local_state->GetString(prefs::kNTPPromoLocale); 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PromoResourceService::UnpackPromoSignal( 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const DictionaryValue& parsed_json) { 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* topic_dict; 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ListValue* answer_list; 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double old_promo_start = 0; 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double old_promo_end = 0; 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double promo_start = 0; 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double promo_end = 0; 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for preexisting start and end values. 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for newly received start and end values. 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parsed_json.GetDictionary("topic", &topic_dict)) { 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (topic_dict->GetList("answers", &answer_list)) { 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string promo_start_string = ""; 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string promo_end_string = ""; 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string promo_string = ""; 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string promo_build = ""; 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int promo_build_type = 0; 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int time_slice_hrs = 0; 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ListValue::const_iterator answer_iter = answer_list->begin(); 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen answer_iter != answer_list->end(); ++answer_iter) { 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* a_dic = 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<DictionaryValue*>(*answer_iter); 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string promo_signal; 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (a_dic->GetString("name", &promo_signal)) { 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (promo_signal == "promo_start") { 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("question", &promo_build); 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen size_t split = promo_build.find(":"); 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (split != std::string::npos && 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::StringToInt(promo_build.substr(0, split), 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &promo_build_type) && 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::StringToInt(promo_build.substr(split+1), 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen &time_slice_hrs) && 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_build_type >= 0 && 224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && 225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen time_slice_hrs >= 0 && 226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen time_slice_hrs <= kMaxTimeSliceHours) { 227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); 228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen time_slice_hrs); 230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If no time data or bad time data are set, do not show promo. 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD); 233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); 234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("inproduct", &promo_start_string); 236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("tooltip", &promo_string); 237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetString(prefs::kNTPPromoLine, promo_string); 238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen srand(static_cast<uint32>(time(NULL))); 239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetInteger(prefs::kNTPPromoGroup, 240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen rand() % kNTPPromoGroupSize); 241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (promo_signal == "promo_end") { 242dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("inproduct", &promo_end_string); 243dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!promo_start_string.empty() && 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_start_string.length() > 0 && 248dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen !promo_end_string.empty() && 249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_end_string.length() > 0) { 250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time start_time; 251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time end_time; 252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (base::Time::FromString( 253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASCIIToWide(promo_start_string).c_str(), &start_time) && 254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time::FromString( 255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASCIIToWide(promo_end_string).c_str(), &end_time)) { 256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Add group time slice, adjusted from hours to seconds. 257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_start = start_time.ToDoubleT() + 258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen (prefs_->FindPreference(prefs::kNTPPromoGroup) ? 259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->GetInteger(prefs::kNTPPromoGroup) * 260dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen time_slice_hrs * 60 * 60 : 0); 261dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_end = end_time.ToDoubleT(); 262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // If start or end times have changed, trigger a new web resource 268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // notification, so that the logo on the NTP is updated. This check is 269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // outside the reading of the web resource data, because the absence of 270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // dates counts as a triggering change if there were dates before. 271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Also reset the promo closed preference, to signal a new promo. 272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!(old_promo_start == promo_start) || 273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen !(old_promo_end == promo_end)) { 274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); 275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); 276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetBoolean(prefs::kNTPPromoClosed, false); 277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ScheduleNotification(promo_start, promo_end); 278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PromoResourceService::UnpackWebStoreSignal( 282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const DictionaryValue& parsed_json) { 283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* topic_dict; 284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* answer_list; 285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool signal_found = false; 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_id = ""; 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_header = ""; 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_button = ""; 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_link = ""; 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_expire = ""; 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int target_builds = 0; 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!parsed_json.GetDictionary("topic", &topic_dict) || 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !topic_dict->GetList("answers", &answer_list)) 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ListValue::const_iterator answer_iter = answer_list->begin(); 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen answer_iter != answer_list->end(); ++answer_iter) { 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* a_dic = 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<DictionaryValue*>(*answer_iter); 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string name; 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!a_dic->GetString("name", &name)) 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t split = name.find(":"); 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (split == std::string::npos) 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string promo_signal = name.substr(0, split); 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (promo_signal != "webstore_promo" || 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !base::StringToInt(name.substr(split+1), &target_builds)) 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!a_dic->GetString(kAnswerIdProperty, &promo_id) || 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !a_dic->GetString(kWebStoreHeaderProperty, &promo_header) || 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !a_dic->GetString(kWebStoreButtonProperty, &promo_button) || 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !a_dic->GetString(kWebStoreLinkProperty, &promo_link) || 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !a_dic->GetString(kWebStoreExpireProperty, &promo_expire)) 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen continue; 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (IsThisBuildTargeted(target_builds)) { 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Store the first web store promo that targets the current build. 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AppsPromo::SetPromo( 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen promo_id, promo_header, promo_button, GURL(promo_link), promo_expire); 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen signal_found = true; 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!signal_found) { 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If no web store promos target this build, then clear all the prefs. 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen AppsPromo::ClearPromo(); 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::current()->Notify( 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationType::WEB_STORE_PROMO_LOADED, 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Source<PromoResourceService>(this), 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NotificationService::NoDetails()); 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PromoResourceService::UnpackLogoSignal( 348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const DictionaryValue& parsed_json) { 349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* topic_dict; 350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ListValue* answer_list; 351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double old_logo_start = 0; 352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double old_logo_end = 0; 353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double logo_start = 0; 354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen double logo_end = 0; 355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for preexisting start and end values. 357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (prefs_->HasPrefPath(prefs::kNTPCustomLogoStart) && 358dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->HasPrefPath(prefs::kNTPCustomLogoEnd)) { 359dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_logo_start = prefs_->GetDouble(prefs::kNTPCustomLogoStart); 360dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen old_logo_end = prefs_->GetDouble(prefs::kNTPCustomLogoEnd); 361dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 362dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 363dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check for newly received start and end values. 364dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parsed_json.GetDictionary("topic", &topic_dict)) { 365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (topic_dict->GetList("answers", &answer_list)) { 366dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string logo_start_string = ""; 367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string logo_end_string = ""; 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ListValue::const_iterator answer_iter = answer_list->begin(); 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen answer_iter != answer_list->end(); ++answer_iter) { 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) 371dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen continue; 372dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DictionaryValue* a_dic = 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static_cast<DictionaryValue*>(*answer_iter); 374dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string logo_signal; 375dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (a_dic->GetString("name", &logo_signal)) { 376dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (logo_signal == "custom_logo_start") { 377dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("inproduct", &logo_start_string); 378dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else if (logo_signal == "custom_logo_end") { 379dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen a_dic->GetString("inproduct", &logo_end_string); 380dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 381dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 382dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 383dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!logo_start_string.empty() && 384dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen logo_start_string.length() > 0 && 385dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen !logo_end_string.empty() && 386dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen logo_end_string.length() > 0) { 387dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time start_time; 388dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time end_time; 389dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (base::Time::FromString( 390dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASCIIToWide(logo_start_string).c_str(), &start_time) && 391dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::Time::FromString( 392dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ASCIIToWide(logo_end_string).c_str(), &end_time)) { 393dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen logo_start = start_time.ToDoubleT(); 394dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen logo_end = end_time.ToDoubleT(); 395dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 396dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 397dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 398dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 399dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 400dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // If logo start or end times have changed, trigger a new web resource 401dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // notification, so that the logo on the NTP is updated. This check is 402dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // outside the reading of the web resource data, because the absence of 403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // dates counts as a triggering change if there were dates before. 404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!(old_logo_start == logo_start) || 405dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen !(old_logo_end == logo_end)) { 406dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); 407dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); 408dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NotificationService* service = NotificationService::current(); 409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen service->Notify(NotificationType::PROMO_RESOURCE_STATE_CHANGED, 410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen Source<WebResourceService>(this), 411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen NotificationService::NoDetails()); 412dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 413dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 414dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 415dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace PromoResourceServiceUtil { 416dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 417dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool CanShowPromo(Profile* profile) { 418dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool promo_closed = false; 419dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrefService* prefs = profile->GetPrefs(); 420dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (prefs->HasPrefPath(prefs::kNTPPromoClosed)) 421dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed); 422dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 423dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Only show if not synced. 424dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool is_synced = 425dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen (profile->HasProfileSyncService() && 426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen sync_ui_util::GetStatus( 427dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen profile->GetProfileSyncService()) == sync_ui_util::SYNCED); 428dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 429dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool is_promo_build = false; 430dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { 431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // GetVersionStringModifier hits the registry. See http://crbug.com/70898. 432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io; 433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string channel = platform_util::GetVersionStringModifier(); 434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen is_promo_build = PromoResourceService::IsBuildTargeted( 435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen channel, prefs->GetInteger(prefs::kNTPPromoBuild)); 436dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 437dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 438dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return !promo_closed && !is_synced && is_promo_build; 439dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 440dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 441dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace PromoResourceServiceUtil 442