Chromium Code Reviews| 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/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 // to versions with different types of promos). | 41 // to versions with different types of promos). |
| 42 static const int kPromoServiceVersion = 2; | 42 static const int kPromoServiceVersion = 2; |
| 43 | 43 |
| 44 // Properties used by the server. | 44 // Properties used by the server. |
| 45 static const char kAnswerIdProperty[] = "answer_id"; | 45 static const char kAnswerIdProperty[] = "answer_id"; |
| 46 static const char kWebStoreHeaderProperty[] = "question"; | 46 static const char kWebStoreHeaderProperty[] = "question"; |
| 47 static const char kWebStoreButtonProperty[] = "inproduct_target"; | 47 static const char kWebStoreButtonProperty[] = "inproduct_target"; |
| 48 static const char kWebStoreLinkProperty[] = "inproduct"; | 48 static const char kWebStoreLinkProperty[] = "inproduct"; |
| 49 static const char kWebStoreExpireProperty[] = "tooltip"; | 49 static const char kWebStoreExpireProperty[] = "tooltip"; |
| 50 | 50 |
| 51 chrome::VersionInfo::Channel GetChannel() { | |
| 52 // GetChannel hits the registry on Windows. See http://crbug.com/70898. | |
| 53 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 54 return chrome::VersionInfo::GetChannel(); | |
| 55 } | |
| 56 | |
| 51 } // namespace | 57 } // namespace |
| 52 | 58 |
| 53 // Server for dynamically loaded NTP HTML elements. TODO(mirandac): append | 59 // Server for dynamically loaded NTP HTML elements. |
| 54 // locale for future usage, when we're serving localizable strings. | |
| 55 const char* PromoResourceService::kDefaultPromoResourceServer = | 60 const char* PromoResourceService::kDefaultPromoResourceServer = |
| 56 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; | 61 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; |
| 57 | 62 |
| 58 // static | 63 // static |
| 59 void PromoResourceService::RegisterPrefs(PrefService* local_state) { | 64 void PromoResourceService::RegisterPrefs(PrefService* local_state) { |
| 60 local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); | 65 local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); |
| 61 local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); | 66 local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); |
| 62 } | 67 } |
| 63 | 68 |
| 64 // static | 69 // static |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 Init(); | 130 Init(); |
| 126 } | 131 } |
| 127 | 132 |
| 128 PromoResourceService::~PromoResourceService() { } | 133 PromoResourceService::~PromoResourceService() { } |
| 129 | 134 |
| 130 void PromoResourceService::Init() { | 135 void PromoResourceService::Init() { |
| 131 ScheduleNotificationOnInit(); | 136 ScheduleNotificationOnInit(); |
| 132 } | 137 } |
| 133 | 138 |
| 134 bool PromoResourceService::IsThisBuildTargeted(int builds_targeted) { | 139 bool PromoResourceService::IsThisBuildTargeted(int builds_targeted) { |
| 135 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) { | 140 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) |
| 136 // GetChannel hits the registry on Windows. See http://crbug.com/70898. | 141 channel_ = GetChannel(); |
| 137 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 138 channel_ = chrome::VersionInfo::GetChannel(); | |
| 139 } | |
| 140 | 142 |
| 141 return IsBuildTargeted(channel_, builds_targeted); | 143 return IsBuildTargeted(channel_, builds_targeted); |
| 142 } | 144 } |
| 143 | 145 |
| 144 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { | 146 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { |
| 145 UnpackLogoSignal(parsed_json); | 147 UnpackLogoSignal(parsed_json); |
| 146 UnpackPromoSignal(parsed_json); | 148 UnpackPromoSignal(parsed_json); |
| 147 UnpackWebStoreSignal(parsed_json); | 149 UnpackWebStoreSignal(parsed_json); |
| 148 } | 150 } |
| 149 | 151 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 } | 197 } |
| 196 | 198 |
| 197 std::string PromoResourceService::GetPromoLocale() { | 199 std::string PromoResourceService::GetPromoLocale() { |
| 198 PrefService* local_state = g_browser_process->local_state(); | 200 PrefService* local_state = g_browser_process->local_state(); |
| 199 return local_state->GetString(prefs::kNTPPromoLocale); | 201 return local_state->GetString(prefs::kNTPPromoLocale); |
| 200 } | 202 } |
| 201 | 203 |
| 202 void PromoResourceService::UnpackPromoSignal( | 204 void PromoResourceService::UnpackPromoSignal( |
| 203 const DictionaryValue& parsed_json) { | 205 const DictionaryValue& parsed_json) { |
| 204 DictionaryValue* topic_dict; | 206 DictionaryValue* topic_dict; |
| 205 ListValue* answer_list; | |
| 206 double old_promo_start = 0; | |
| 207 double old_promo_end = 0; | |
| 208 double promo_start = 0; | |
| 209 double promo_end = 0; | |
| 210 | |
| 211 // Check for preexisting start and end values. | |
| 212 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && | |
| 213 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { | |
| 214 old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); | |
| 215 old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); | |
| 216 } | |
| 217 | 207 |
| 218 // Check for newly received start and end values. | 208 // Check for newly received start and end values. |
| 209 double promo_start = 0.0, promo_end = 0.0; | |
| 210 int time_slice_hrs = 0; | |
| 219 if (parsed_json.GetDictionary("topic", &topic_dict)) { | 211 if (parsed_json.GetDictionary("topic", &topic_dict)) { |
| 212 ListValue* answer_list; | |
| 220 if (topic_dict->GetList("answers", &answer_list)) { | 213 if (topic_dict->GetList("answers", &answer_list)) { |
| 221 std::string promo_start_string = ""; | 214 std::string promo_start_string, promo_end_string; |
| 222 std::string promo_end_string = ""; | |
| 223 std::string promo_string = ""; | |
| 224 std::string promo_build = ""; | |
| 225 int promo_build_type = 0; | |
| 226 int time_slice_hrs = 0; | |
| 227 for (ListValue::const_iterator answer_iter = answer_list->begin(); | 215 for (ListValue::const_iterator answer_iter = answer_list->begin(); |
| 228 answer_iter != answer_list->end(); ++answer_iter) { | 216 answer_iter != answer_list->end(); ++answer_iter) { |
| 229 if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) | 217 if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) |
| 230 continue; | 218 continue; |
| 231 DictionaryValue* a_dic = | 219 DictionaryValue* a_dic = |
| 232 static_cast<DictionaryValue*>(*answer_iter); | 220 static_cast<DictionaryValue*>(*answer_iter); |
| 233 std::string promo_signal; | 221 std::string promo_signal; |
| 234 if (a_dic->GetString("name", &promo_signal)) { | 222 if (a_dic->GetString("name", &promo_signal)) { |
| 235 if (promo_signal == "promo_start") { | 223 if (promo_signal == "promo_start") { |
| 224 std::string promo_build; | |
| 236 a_dic->GetString("question", &promo_build); | 225 a_dic->GetString("question", &promo_build); |
| 237 size_t split = promo_build.find(":"); | 226 size_t split = promo_build.find(":"); |
| 227 int promo_build_type = 0; | |
| 238 if (split != std::string::npos && | 228 if (split != std::string::npos && |
| 239 base::StringToInt(promo_build.substr(0, split), | 229 base::StringToInt(promo_build.substr(0, split), |
| 240 &promo_build_type) && | 230 &promo_build_type) && |
| 241 base::StringToInt(promo_build.substr(split+1), | 231 base::StringToInt(promo_build.substr(split+1), |
| 242 &time_slice_hrs) && | 232 &time_slice_hrs) && |
| 243 promo_build_type >= 0 && | 233 promo_build_type >= 0 && |
| 244 promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && | 234 promo_build_type <= (DEV_BUILD | BETA_BUILD | STABLE_BUILD) && |
| 245 time_slice_hrs >= 0 && | 235 time_slice_hrs >= 0 && |
| 246 time_slice_hrs <= kMaxTimeSliceHours) { | 236 time_slice_hrs <= kMaxTimeSliceHours) { |
| 247 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); | 237 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build_type); |
| 248 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, | 238 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, |
| 249 time_slice_hrs); | 239 time_slice_hrs); |
| 250 } else { | 240 } else { |
| 251 // If no time data or bad time data are set, do not show promo. | 241 // If no time data or bad time data are set, do not show promo. |
| 252 prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD); | 242 prefs_->SetInteger(prefs::kNTPPromoBuild, NO_BUILD); |
| 253 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); | 243 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, 0); |
| 254 } | 244 } |
| 255 a_dic->GetString("inproduct", &promo_start_string); | 245 a_dic->GetString("inproduct", &promo_start_string); |
| 256 a_dic->GetString("tooltip", &promo_string); | 246 std::string promo_line; |
| 257 prefs_->SetString(prefs::kNTPPromoLine, promo_string); | 247 a_dic->GetString("tooltip", &promo_line); |
| 248 prefs_->SetString(prefs::kNTPPromoLine, promo_line); | |
| 258 srand(static_cast<uint32>(time(NULL))); | 249 srand(static_cast<uint32>(time(NULL))); |
| 259 prefs_->SetInteger(prefs::kNTPPromoGroup, | 250 prefs_->SetInteger(prefs::kNTPPromoGroup, |
| 260 rand() % kNTPPromoGroupSize); | 251 rand() % kNTPPromoGroupSize); |
| 261 } else if (promo_signal == "promo_end") { | 252 } else if (promo_signal == "promo_end") { |
| 262 a_dic->GetString("inproduct", &promo_end_string); | 253 a_dic->GetString("inproduct", &promo_end_string); |
| 263 } | 254 } |
| 264 } | 255 } |
| 265 } | 256 } |
| 266 if (!promo_start_string.empty() && | 257 |
| 267 promo_start_string.length() > 0 && | 258 if (!promo_start_string.empty() && !promo_end_string.empty()) { |
| 268 !promo_end_string.empty() && | |
| 269 promo_end_string.length() > 0) { | |
| 270 base::Time start_time; | 259 base::Time start_time; |
| 271 base::Time end_time; | 260 base::Time end_time; |
| 272 if (base::Time::FromString(promo_start_string.c_str(), &start_time) && | 261 if (base::Time::FromString(promo_start_string.c_str(), &start_time) && |
| 273 base::Time::FromString(promo_end_string.c_str(), &end_time)) { | 262 base::Time::FromString(promo_end_string.c_str(), &end_time)) { |
| 274 // Add group time slice, adjusted from hours to seconds. | 263 // Add group time slice, adjusted from hours to seconds. |
| 275 promo_start = start_time.ToDoubleT() + | 264 promo_start = start_time.ToDoubleT() + |
| 276 (prefs_->FindPreference(prefs::kNTPPromoGroup) ? | 265 (prefs_->FindPreference(prefs::kNTPPromoGroup) ? |
| 277 prefs_->GetInteger(prefs::kNTPPromoGroup) * | 266 prefs_->GetInteger(prefs::kNTPPromoGroup) * |
| 278 time_slice_hrs * 60 * 60 : 0); | 267 time_slice_hrs * 60 * 60 : 0); |
| 279 promo_end = end_time.ToDoubleT(); | 268 promo_end = end_time.ToDoubleT(); |
| 280 } | 269 } |
| 281 } | 270 } |
| 282 } | 271 } |
| 283 } | 272 } |
| 284 | 273 |
| 274 // Check for pre-existing start and end values. | |
| 275 double old_promo_start = 0.0, old_promo_end = 0.0; | |
| 276 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && | |
| 277 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { | |
| 278 old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); | |
| 279 old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); | |
| 280 } | |
| 281 | |
| 285 // If start or end times have changed, trigger a new web resource | 282 // If start or end times have changed, trigger a new web resource |
| 286 // notification, so that the logo on the NTP is updated. This check is | 283 // notification, so that the logo on the NTP is updated. This check is |
| 287 // outside the reading of the web resource data, because the absence of | 284 // outside the reading of the web resource data, because the absence of |
| 288 // dates counts as a triggering change if there were dates before. | 285 // dates counts as a triggering change if there were dates before. |
| 289 // Also reset the promo closed preference, to signal a new promo. | 286 // Also reset the promo closed preference, to signal a new promo. |
| 290 if (!(old_promo_start == promo_start) || | 287 if (old_promo_start != promo_start || |
| 291 !(old_promo_end == promo_end)) { | 288 old_promo_end != promo_end) { |
| 292 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); | 289 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); |
| 293 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); | 290 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); |
| 294 prefs_->SetBoolean(prefs::kNTPPromoClosed, false); | 291 prefs_->SetBoolean(prefs::kNTPPromoClosed, false); |
| 295 ScheduleNotification(promo_start, promo_end); | 292 ScheduleNotification(promo_start, promo_end); |
| 296 } | 293 } |
| 297 } | 294 } |
| 298 | 295 |
| 299 void PromoResourceService::UnpackWebStoreSignal( | 296 void PromoResourceService::UnpackWebStoreSignal( |
| 300 const DictionaryValue& parsed_json) { | 297 const DictionaryValue& parsed_json) { |
| 301 DictionaryValue* topic_dict; | 298 DictionaryValue* topic_dict; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 !(old_logo_end == logo_end)) { | 443 !(old_logo_end == logo_end)) { |
| 447 prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); | 444 prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); |
| 448 prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); | 445 prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); |
| 449 NotificationService* service = NotificationService::current(); | 446 NotificationService* service = NotificationService::current(); |
| 450 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, | 447 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, |
| 451 Source<WebResourceService>(this), | 448 Source<WebResourceService>(this), |
| 452 NotificationService::NoDetails()); | 449 NotificationService::NoDetails()); |
| 453 } | 450 } |
| 454 } | 451 } |
| 455 | 452 |
| 456 namespace PromoResourceServiceUtil { | 453 bool PromoResourceService::CanShowPromo(Profile* profile) { |
|
jstritar
2011/08/19 14:56:13
What do you think of renaming this something more
achuithb
2011/08/19 20:16:14
Do you have any suggestions? It looks like this cl
jstritar
2011/08/22 18:06:39
Hmmm... not sure. I guess this type of promo is ca
| |
| 454 PrefService* prefs = profile->GetPrefs(); | |
| 457 | 455 |
| 458 bool CanShowPromo(Profile* profile) { | 456 // Check if promo has been closed by the user. |
| 459 bool promo_closed = false; | 457 if (prefs->HasPrefPath(prefs::kNTPPromoClosed) && |
| 460 PrefService* prefs = profile->GetPrefs(); | 458 prefs->GetBoolean(prefs::kNTPPromoClosed)) |
| 461 if (prefs->HasPrefPath(prefs::kNTPPromoClosed)) | 459 return false; |
| 462 promo_closed = prefs->GetBoolean(prefs::kNTPPromoClosed); | |
| 463 | 460 |
| 464 // Only show if not synced. | 461 // Check if our build is appropriate for this promo. |
| 465 bool is_synced = | 462 if (!prefs->HasPrefPath(prefs::kNTPPromoBuild) || |
| 466 (profile->HasProfileSyncService() && | 463 !IsBuildTargeted(GetChannel(), prefs->GetInteger(prefs::kNTPPromoBuild))) |
| 467 sync_ui_util::GetStatus( | 464 return false; |
|
jstritar
2011/08/19 14:56:13
If we want to avoid calling GetChannel() on the UI
achuithb
2011/08/19 20:16:14
So I looked into doing this. CanShowPromo is a sta
jstritar
2011/08/22 18:06:39
I was thinking something like what we do in Unpack
| |
| 468 profile->GetProfileSyncService()) == sync_ui_util::SYNCED); | |
| 469 | 465 |
| 470 bool is_promo_build = false; | 466 // Check if we are in the right time window for this promo. |
| 471 if (prefs->HasPrefPath(prefs::kNTPPromoBuild)) { | 467 if (!prefs->FindPreference(prefs::kNTPPromoStart) || |
| 472 // GetChannel hits the registry on Windows. See http://crbug.com/70898. | 468 !prefs->FindPreference(prefs::kNTPPromoEnd) || |
| 473 base::ThreadRestrictions::ScopedAllowIO allow_io; | 469 base::Time::FromDoubleT(prefs->GetDouble(prefs::kNTPPromoStart)) > |
| 474 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); | 470 base::Time::Now() || |
| 475 is_promo_build = PromoResourceService::IsBuildTargeted( | 471 base::Time::FromDoubleT(prefs->GetDouble(prefs::kNTPPromoEnd)) < |
| 476 channel, prefs->GetInteger(prefs::kNTPPromoBuild)); | 472 base::Time::Now()) |
| 477 } | 473 return false; |
| 478 | 474 |
| 479 return !promo_closed && !is_synced && is_promo_build; | 475 return prefs->HasPrefPath(prefs::kNTPPromoLine); |
| 480 } | 476 } |
| 481 | |
| 482 } // namespace PromoResourceServiceUtil | |
| OLD | NEW |