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