| 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/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
| 9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/extensions/apps_promo.h" | 14 #include "chrome/browser/extensions/apps_promo.h" |
| 15 #include "chrome/browser/prefs/pref_service.h" | 15 #include "chrome/browser/prefs/pref_service.h" |
| 16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
| 17 #include "chrome/browser/sync/sync_ui_util.h" | 17 #include "chrome/browser/sync/sync_ui_util.h" |
| 18 #include "chrome/browser/web_resource/promo_notification.h" |
| 18 #include "chrome/common/chrome_notification_types.h" | 19 #include "chrome/common/chrome_notification_types.h" |
| 19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/chrome_version_info.h" | 21 #include "chrome/common/chrome_version_info.h" |
| 21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
| 22 #include "content/browser/browser_thread.h" | 23 #include "content/browser/browser_thread.h" |
| 23 #include "content/common/notification_service.h" | 24 #include "content/common/notification_service.h" |
| 24 #include "googleurl/src/gurl.h" | 25 #include "googleurl/src/gurl.h" |
| 25 | 26 |
| 26 namespace { | 27 namespace { |
| 27 | 28 |
| 28 // Delay on first fetch so we don't interfere with startup. | 29 // Delay on first fetch so we don't interfere with startup. |
| 29 static const int kStartResourceFetchDelay = 5000; | 30 static const int kStartResourceFetchDelay = 5000; |
| 30 | 31 |
| 31 // Delay between calls to update the cache (48 hours), and 3 min in debug mode. | 32 // Delay between calls to update the cache (48 hours), and 3 min in debug mode. |
| 32 static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; | 33 static const int kCacheUpdateDelay = 48 * 60 * 60 * 1000; |
| 33 static const int kDebugCacheUpdateDelay = 3 * 60 * 1000; | 34 static const int kTestCacheUpdateDelay = 3 * 60 * 1000; |
| 34 | |
| 35 // Users are randomly assigned to one of kNTPPromoGroupSize buckets, in order | |
| 36 // to be able to roll out promos slowly, or display different promos to | |
| 37 // different groups. | |
| 38 static const int kNTPPromoGroupSize = 100; | |
| 39 | |
| 40 // Maximum number of hours for each time slice (4 weeks). | |
| 41 static const int kMaxTimeSliceHours = 24 * 7 * 4; | |
| 42 | 35 |
| 43 // The version of the service (used to expire the cache when upgrading Chrome | 36 // The version of the service (used to expire the cache when upgrading Chrome |
| 44 // to versions with different types of promos). | 37 // to versions with different types of promos). |
| 45 static const int kPromoServiceVersion = 2; | 38 static const int kPromoServiceVersion = 2; |
| 46 | 39 |
| 47 // Properties used by the server. | 40 // Properties used by the server. |
| 48 static const char kAnswerIdProperty[] = "answer_id"; | 41 static const char kAnswerIdProperty[] = "answer_id"; |
| 49 static const char kWebStoreHeaderProperty[] = "question"; | 42 static const char kWebStoreHeaderProperty[] = "question"; |
| 50 static const char kWebStoreButtonProperty[] = "inproduct_target"; | 43 static const char kWebStoreButtonProperty[] = "inproduct_target"; |
| 51 static const char kWebStoreLinkProperty[] = "inproduct"; | 44 static const char kWebStoreLinkProperty[] = "inproduct"; |
| 52 static const char kWebStoreExpireProperty[] = "tooltip"; | 45 static const char kWebStoreExpireProperty[] = "tooltip"; |
| 53 | 46 |
| 54 chrome::VersionInfo::Channel GetChannel() { | |
| 55 // GetChannel hits the registry on Windows. See http://crbug.com/70898. | |
| 56 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
| 57 return chrome::VersionInfo::GetChannel(); | |
| 58 } | |
| 59 | |
| 60 int GetNextQuestionValue(const std::string& question, | |
| 61 size_t* index, | |
| 62 bool* err) { | |
| 63 if (*err) | |
| 64 return 0; | |
| 65 | |
| 66 size_t new_index = question.find(':', *index); | |
| 67 // Note that substr correctly handles npos. | |
| 68 std::string fragment(question.substr(*index, new_index - *index)); | |
| 69 *index = new_index + 1; | |
| 70 | |
| 71 int value; | |
| 72 *err = !base::StringToInt(fragment, &value); | |
| 73 return value; | |
| 74 } | |
| 75 | |
| 76 const char* GetPromoResourceURL() { | 47 const char* GetPromoResourceURL() { |
| 77 std::string promo_server_url = CommandLine::ForCurrentProcess()-> | 48 std::string promo_server_url = CommandLine::ForCurrentProcess()-> |
| 78 GetSwitchValueASCII(switches::kPromoServerURL); | 49 GetSwitchValueASCII(switches::kPromoServerURL); |
| 79 return promo_server_url.empty() ? | 50 return promo_server_url.empty() ? |
| 80 PromoResourceService::kDefaultPromoResourceServer : | 51 PromoResourceService::kDefaultPromoResourceServer : |
| 81 promo_server_url.c_str(); | 52 promo_server_url.c_str(); |
| 82 } | 53 } |
| 83 | 54 |
| 55 bool IsTest() { |
| 56 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kPromoServerURL); |
| 57 } |
| 58 |
| 84 int GetCacheUpdateDelay() { | 59 int GetCacheUpdateDelay() { |
| 85 return CommandLine::ForCurrentProcess()->HasSwitch( | 60 return IsTest() ? kTestCacheUpdateDelay : kCacheUpdateDelay; |
| 86 switches::kPromoServerURL) ? kDebugCacheUpdateDelay : kCacheUpdateDelay; | |
| 87 } | 61 } |
| 88 | 62 |
| 89 } // namespace | 63 } // namespace |
| 90 | 64 |
| 91 // Server for dynamically loaded NTP HTML elements. | 65 // Server for dynamically loaded NTP HTML elements. |
| 92 const char* PromoResourceService::kDefaultPromoResourceServer = | 66 const char* PromoResourceService::kDefaultPromoResourceServer = |
| 93 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; | 67 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; |
| 94 | 68 |
| 95 // static | 69 // static |
| 96 void PromoResourceService::RegisterPrefs(PrefService* local_state) { | 70 void PromoResourceService::RegisterPrefs(PrefService* local_state) { |
| 97 local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); | 71 local_state->RegisterIntegerPref(prefs::kNTPPromoVersion, 0); |
| 98 local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); | 72 local_state->RegisterStringPref(prefs::kNTPPromoLocale, std::string()); |
| 99 } | 73 } |
| 100 | 74 |
| 101 // static | 75 // static |
| 102 void PromoResourceService::RegisterUserPrefs(PrefService* prefs) { | 76 void PromoResourceService::RegisterUserPrefs(PrefService* prefs) { |
| 103 prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart, | 77 prefs->RegisterDoublePref(prefs::kNTPCustomLogoStart, |
| 104 0, | 78 0, |
| 105 PrefService::UNSYNCABLE_PREF); | 79 PrefService::UNSYNCABLE_PREF); |
| 106 prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd, | 80 prefs->RegisterDoublePref(prefs::kNTPCustomLogoEnd, |
| 107 0, | 81 0, |
| 108 PrefService::UNSYNCABLE_PREF); | 82 PrefService::UNSYNCABLE_PREF); |
| 109 prefs->RegisterDoublePref(prefs::kNTPPromoStart, | 83 PromoNotification::RegisterUserPrefs(prefs); |
| 110 0, | 84 } |
| 111 PrefService::UNSYNCABLE_PREF); | 85 |
| 112 prefs->RegisterDoublePref(prefs::kNTPPromoEnd, | 86 // static |
| 113 0, | 87 chrome::VersionInfo::Channel PromoResourceService::GetChannel() { |
| 114 PrefService::UNSYNCABLE_PREF); | 88 // GetChannel hits the registry on Windows. See http://crbug.com/70898. |
| 115 prefs->RegisterStringPref(prefs::kNTPPromoLine, | 89 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 116 std::string(), | 90 return chrome::VersionInfo::GetChannel(); |
| 117 PrefService::UNSYNCABLE_PREF); | |
| 118 prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, | |
| 119 false, | |
| 120 PrefService::UNSYNCABLE_PREF); | |
| 121 prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, | |
| 122 0, | |
| 123 PrefService::UNSYNCABLE_PREF); | |
| 124 prefs->RegisterIntegerPref( | |
| 125 prefs::kNTPPromoBuild, | |
| 126 ALL_BUILDS, | |
| 127 PrefService::UNSYNCABLE_PREF); | |
| 128 prefs->RegisterIntegerPref(prefs::kNTPPromoGroupTimeSlice, | |
| 129 0, | |
| 130 PrefService::UNSYNCABLE_PREF); | |
| 131 prefs->RegisterIntegerPref(prefs::kNTPPromoGroupMax, | |
| 132 0, | |
| 133 PrefService::UNSYNCABLE_PREF); | |
| 134 } | 91 } |
| 135 | 92 |
| 136 // static | 93 // static |
| 137 bool PromoResourceService::IsBuildTargeted(chrome::VersionInfo::Channel channel, | 94 bool PromoResourceService::IsBuildTargeted(chrome::VersionInfo::Channel channel, |
| 138 int builds_allowed) { | 95 int builds_allowed) { |
| 139 if (builds_allowed == NO_BUILD) | 96 if (builds_allowed == NO_BUILD) |
| 140 return false; | 97 return false; |
| 141 switch (channel) { | 98 switch (channel) { |
| 142 case chrome::VersionInfo::CHANNEL_CANARY: | 99 case chrome::VersionInfo::CHANNEL_CANARY: |
| 143 return (CANARY_BUILD & builds_allowed) != 0; | 100 return (CANARY_BUILD & builds_allowed) != 0; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 166 channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) { | 123 channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) { |
| 167 Init(); | 124 Init(); |
| 168 } | 125 } |
| 169 | 126 |
| 170 PromoResourceService::~PromoResourceService() { } | 127 PromoResourceService::~PromoResourceService() { } |
| 171 | 128 |
| 172 void PromoResourceService::Init() { | 129 void PromoResourceService::Init() { |
| 173 ScheduleNotificationOnInit(); | 130 ScheduleNotificationOnInit(); |
| 174 } | 131 } |
| 175 | 132 |
| 176 bool PromoResourceService::IsThisBuildTargeted(int builds_targeted) { | 133 bool PromoResourceService::IsBuildTargeted(int builds_targeted) { |
| 177 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) | 134 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) |
| 178 channel_ = GetChannel(); | 135 channel_ = GetChannel(); |
| 179 | 136 |
| 180 return IsBuildTargeted(channel_, builds_targeted); | 137 return IsBuildTargeted(channel_, builds_targeted); |
| 181 } | 138 } |
| 182 | 139 |
| 183 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { | 140 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { |
| 184 UnpackLogoSignal(parsed_json); | 141 UnpackLogoSignal(parsed_json); |
| 185 UnpackNotificationSignal(parsed_json); | 142 UnpackNotificationSignal(parsed_json); |
| 186 UnpackWebStoreSignal(parsed_json); | 143 UnpackWebStoreSignal(parsed_json); |
| 187 } | 144 } |
| 188 | 145 |
| 146 void PromoResourceService::OnNewNotification(double start, double end) { |
| 147 ScheduleNotification(start, end); |
| 148 } |
| 149 |
| 189 void PromoResourceService::ScheduleNotification(double promo_start, | 150 void PromoResourceService::ScheduleNotification(double promo_start, |
| 190 double promo_end) { | 151 double promo_end) { |
| 191 if (promo_start > 0 && promo_end > 0) { | 152 if (promo_start > 0 && promo_end > 0) { |
| 192 int64 ms_until_start = | 153 int64 ms_until_start = |
| 193 static_cast<int64>((base::Time::FromDoubleT( | 154 static_cast<int64>((base::Time::FromDoubleT( |
| 194 promo_start) - base::Time::Now()).InMilliseconds()); | 155 promo_start) - base::Time::Now()).InMilliseconds()); |
| 195 int64 ms_until_end = | 156 int64 ms_until_end = |
| 196 static_cast<int64>((base::Time::FromDoubleT( | 157 static_cast<int64>((base::Time::FromDoubleT( |
| 197 promo_end) - base::Time::Now()).InMilliseconds()); | 158 promo_end) - base::Time::Now()).InMilliseconds()); |
| 198 if (ms_until_start > 0) | 159 if (ms_until_start > 0) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 return local_state->GetInteger(prefs::kNTPPromoVersion); | 194 return local_state->GetInteger(prefs::kNTPPromoVersion); |
| 234 } | 195 } |
| 235 | 196 |
| 236 std::string PromoResourceService::GetPromoLocale() { | 197 std::string PromoResourceService::GetPromoLocale() { |
| 237 PrefService* local_state = g_browser_process->local_state(); | 198 PrefService* local_state = g_browser_process->local_state(); |
| 238 return local_state->GetString(prefs::kNTPPromoLocale); | 199 return local_state->GetString(prefs::kNTPPromoLocale); |
| 239 } | 200 } |
| 240 | 201 |
| 241 void PromoResourceService::UnpackNotificationSignal( | 202 void PromoResourceService::UnpackNotificationSignal( |
| 242 const DictionaryValue& parsed_json) { | 203 const DictionaryValue& parsed_json) { |
| 243 // Check for newly received start and end values. | 204 PromoNotification promo_notification(prefs_, this); |
| 244 std::string promo_start_string, promo_end_string; | 205 promo_notification.InitFromJson(parsed_json); |
| 245 | |
| 246 DictionaryValue* topic_dict; | |
| 247 if (parsed_json.GetDictionary("topic", &topic_dict)) { | |
| 248 ListValue* answer_list; | |
| 249 if (topic_dict->GetList("answers", &answer_list)) { | |
| 250 for (ListValue::const_iterator answer_iter = answer_list->begin(); | |
| 251 answer_iter != answer_list->end(); ++answer_iter) { | |
| 252 if (!(*answer_iter)->IsType(Value::TYPE_DICTIONARY)) | |
| 253 continue; | |
| 254 | |
| 255 ParseNotification(static_cast<DictionaryValue*>(*answer_iter), | |
| 256 &promo_start_string, &promo_end_string); | |
| 257 } | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 CheckForNewNotification(promo_start_string, promo_end_string); | |
| 262 } | |
| 263 | |
| 264 void PromoResourceService::ParseNotification( | |
| 265 DictionaryValue* a_dic, | |
| 266 std::string* promo_start_string, | |
| 267 std::string* promo_end_string) { | |
| 268 std::string promo_signal; | |
| 269 if (a_dic->GetString("name", &promo_signal)) { | |
| 270 if (promo_signal == "promo_start") { | |
| 271 SetNotificationParams(a_dic); | |
| 272 SetNotificationLine(a_dic); | |
| 273 | |
| 274 a_dic->GetString("inproduct", promo_start_string); | |
| 275 } else if (promo_signal == "promo_end") { | |
| 276 a_dic->GetString("inproduct", promo_end_string); | |
| 277 } | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 void PromoResourceService::SetNotificationParams(DictionaryValue* a_dic) { | |
| 282 std::string question; | |
| 283 a_dic->GetString("question", &question); | |
| 284 | |
| 285 size_t index(0); | |
| 286 bool err(false); | |
| 287 int promo_build = GetNextQuestionValue(question, &index, &err); | |
| 288 int time_slice = GetNextQuestionValue(question, &index, &err); | |
| 289 int max_group = GetNextQuestionValue(question, &index, &err); | |
| 290 | |
| 291 if (err || | |
| 292 promo_build < 0 || | |
| 293 promo_build > ALL_BUILDS || | |
| 294 time_slice < 0 || | |
| 295 time_slice > kMaxTimeSliceHours || | |
| 296 max_group < 0 || | |
| 297 max_group >= kNTPPromoGroupSize) { | |
| 298 // If values are not valid, do not show promo. | |
| 299 NOTREACHED() << "Invalid server data, question=" << question << | |
| 300 ", build=" << promo_build << | |
| 301 ", time_slice=" << time_slice << | |
| 302 ", max_group=" << max_group; | |
| 303 promo_build = NO_BUILD; | |
| 304 time_slice = 0; | |
| 305 max_group = 0; | |
| 306 } | |
| 307 | |
| 308 prefs_->SetInteger(prefs::kNTPPromoBuild, promo_build); | |
| 309 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, time_slice); | |
| 310 prefs_->SetInteger(prefs::kNTPPromoGroupMax, max_group); | |
| 311 } | |
| 312 | |
| 313 void PromoResourceService::SetNotificationLine(DictionaryValue* a_dic) { | |
| 314 std::string promo_line; | |
| 315 a_dic->GetString("tooltip", &promo_line); | |
| 316 if (!promo_line.empty()) | |
| 317 prefs_->SetString(prefs::kNTPPromoLine, promo_line); | |
| 318 } | |
| 319 | |
| 320 void PromoResourceService::CheckForNewNotification( | |
| 321 const std::string& promo_start_string, | |
| 322 const std::string& promo_end_string) { | |
| 323 double promo_start = 0.0, promo_end = 0.0; | |
| 324 ParseNewNotificationTimes(promo_start_string, promo_end_string, | |
| 325 &promo_start, &promo_end); | |
| 326 | |
| 327 double old_promo_start = 0.0, old_promo_end = 0.0; | |
| 328 GetCurrentNotificationTimes(&old_promo_start, &old_promo_end); | |
| 329 | |
| 330 // If start or end times have changed, trigger a new web resource | |
| 331 // notification, so that the logo on the NTP is updated. This check is | |
| 332 // outside the reading of the web resource data, because the absence of | |
| 333 // dates counts as a triggering change if there were dates before. | |
| 334 // Also create new promo groups, and reset the promo closed preference, | |
| 335 // to signal a new promo. | |
| 336 if (old_promo_start != promo_start || old_promo_end != promo_end) | |
| 337 OnNewNotification(promo_start, promo_end); | |
| 338 } | |
| 339 | |
| 340 void PromoResourceService::ParseNewNotificationTimes( | |
| 341 const std::string& promo_start_string, | |
| 342 const std::string& promo_end_string, | |
| 343 double* promo_start, | |
| 344 double* promo_end) { | |
| 345 *promo_start = *promo_end = 0.0; | |
| 346 | |
| 347 if (promo_start_string.empty() && !promo_end_string.empty()) | |
| 348 return; | |
| 349 | |
| 350 base::Time start_time, end_time; | |
| 351 if (!base::Time::FromString(promo_start_string.c_str(), &start_time) || | |
| 352 !base::Time::FromString(promo_end_string.c_str(), &end_time)) | |
| 353 return; | |
| 354 | |
| 355 *promo_start = start_time.ToDoubleT(); | |
| 356 *promo_end = end_time.ToDoubleT(); | |
| 357 } | |
| 358 | |
| 359 void PromoResourceService::GetCurrentNotificationTimes(double* old_promo_start, | |
| 360 double* old_promo_end) { | |
| 361 *old_promo_start = *old_promo_end = 0.0; | |
| 362 if (prefs_->HasPrefPath(prefs::kNTPPromoStart) && | |
| 363 prefs_->HasPrefPath(prefs::kNTPPromoEnd)) { | |
| 364 *old_promo_start = prefs_->GetDouble(prefs::kNTPPromoStart); | |
| 365 *old_promo_end = prefs_->GetDouble(prefs::kNTPPromoEnd); | |
| 366 } | |
| 367 } | |
| 368 | |
| 369 int PromoResourceService::ResetNotificationGroup() { | |
| 370 srand(static_cast<uint32>(time(NULL))); | |
| 371 const int promo_group = rand() % kNTPPromoGroupSize; | |
| 372 prefs_->SetInteger(prefs::kNTPPromoGroup, promo_group); | |
| 373 return promo_group; | |
| 374 } | |
| 375 | |
| 376 // static | |
| 377 double PromoResourceService::GetNotificationStartTime(PrefService* prefs) { | |
| 378 if (!prefs->HasPrefPath(prefs::kNTPPromoStart)) | |
| 379 return 0.0; | |
| 380 | |
| 381 const double promo_start = prefs->GetDouble(prefs::kNTPPromoStart); | |
| 382 | |
| 383 if (!prefs->HasPrefPath(prefs::kNTPPromoGroup) || | |
| 384 !prefs->HasPrefPath(prefs::kNTPPromoGroupTimeSlice)) | |
| 385 return promo_start; | |
| 386 | |
| 387 const int promo_group = prefs->GetInteger(prefs::kNTPPromoGroup); | |
| 388 const int time_slice = prefs->GetInteger(prefs::kNTPPromoGroupTimeSlice); | |
| 389 // Adjust promo_start using group time slice, adjusted from hours to seconds. | |
| 390 static const double kSecondsInHour = 60.0 * 60.0; | |
| 391 return promo_start + promo_group * time_slice * kSecondsInHour; | |
| 392 } | |
| 393 | |
| 394 void PromoResourceService::OnNewNotification(double promo_start, | |
| 395 double promo_end) { | |
| 396 ResetNotificationGroup(); | |
| 397 | |
| 398 prefs_->SetBoolean(prefs::kNTPPromoClosed, false); | |
| 399 | |
| 400 prefs_->SetDouble(prefs::kNTPPromoStart, promo_start); | |
| 401 prefs_->SetDouble(prefs::kNTPPromoEnd, promo_end); | |
| 402 | |
| 403 ScheduleNotification(GetNotificationStartTime(prefs_), promo_end); | |
| 404 } | 206 } |
| 405 | 207 |
| 406 bool PromoResourceService::CanShowNotificationPromo(Profile* profile) { | 208 bool PromoResourceService::CanShowNotificationPromo(Profile* profile) { |
| 407 PrefService* prefs = profile->GetPrefs(); | 209 PromoNotification promo_notification(profile->GetPrefs(), NULL); |
| 408 | 210 promo_notification.InitFromPrefs(); |
| 409 // Check if promo has been closed by the user. | 211 return promo_notification.CanShow(); |
| 410 if (prefs->HasPrefPath(prefs::kNTPPromoClosed) && | |
| 411 prefs->GetBoolean(prefs::kNTPPromoClosed)) | |
| 412 return false; | |
| 413 | |
| 414 // Check if our build is appropriate for this promo. | |
| 415 if (!prefs->HasPrefPath(prefs::kNTPPromoBuild) || | |
| 416 !IsBuildTargeted(GetChannel(), prefs->GetInteger(prefs::kNTPPromoBuild))) | |
| 417 return false; | |
| 418 | |
| 419 // Check if we are in the right group for this promo. | |
| 420 if (!prefs->FindPreference(prefs::kNTPPromoGroup) || | |
| 421 !prefs->FindPreference(prefs::kNTPPromoGroupMax) || | |
| 422 (prefs->GetInteger(prefs::kNTPPromoGroup) >= | |
| 423 prefs->GetInteger(prefs::kNTPPromoGroupMax))) | |
| 424 return false; | |
| 425 | |
| 426 // Check if we are in the right time window for this promo. | |
| 427 if (!prefs->FindPreference(prefs::kNTPPromoStart) || | |
| 428 !prefs->FindPreference(prefs::kNTPPromoEnd) || | |
| 429 base::Time::FromDoubleT(GetNotificationStartTime(prefs)) > | |
| 430 base::Time::Now() || | |
| 431 base::Time::FromDoubleT(prefs->GetDouble(prefs::kNTPPromoEnd)) < | |
| 432 base::Time::Now()) | |
| 433 return false; | |
| 434 | |
| 435 return prefs->HasPrefPath(prefs::kNTPPromoLine); | |
| 436 } | 212 } |
| 437 | 213 |
| 438 void PromoResourceService::UnpackWebStoreSignal( | 214 void PromoResourceService::UnpackWebStoreSignal( |
| 439 const DictionaryValue& parsed_json) { | 215 const DictionaryValue& parsed_json) { |
| 440 DictionaryValue* topic_dict; | 216 DictionaryValue* topic_dict; |
| 441 ListValue* answer_list; | 217 ListValue* answer_list; |
| 442 | 218 |
| 443 bool is_webstore_active = false; | 219 bool is_webstore_active = false; |
| 444 bool signal_found = false; | 220 bool signal_found = false; |
| 445 AppsPromo::PromoData promo_data; | 221 AppsPromo::PromoData promo_data; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 // (4) optional text that specifies a URL of a logo image | 266 // (4) optional text that specifies a URL of a logo image |
| 491 promo_logo = name.substr(split+1); | 267 promo_logo = name.substr(split+1); |
| 492 | 268 |
| 493 if (!a_dic->GetString(kAnswerIdProperty, &promo_data.id) || | 269 if (!a_dic->GetString(kAnswerIdProperty, &promo_data.id) || |
| 494 !a_dic->GetString(kWebStoreHeaderProperty, &promo_data.header) || | 270 !a_dic->GetString(kWebStoreHeaderProperty, &promo_data.header) || |
| 495 !a_dic->GetString(kWebStoreButtonProperty, &promo_data.button) || | 271 !a_dic->GetString(kWebStoreButtonProperty, &promo_data.button) || |
| 496 !a_dic->GetString(kWebStoreLinkProperty, &promo_link) || | 272 !a_dic->GetString(kWebStoreLinkProperty, &promo_link) || |
| 497 !a_dic->GetString(kWebStoreExpireProperty, &promo_data.expire)) | 273 !a_dic->GetString(kWebStoreExpireProperty, &promo_data.expire)) |
| 498 continue; | 274 continue; |
| 499 | 275 |
| 500 if (IsThisBuildTargeted(target_builds)) { | 276 if (IsBuildTargeted(target_builds)) { |
| 501 // The downloader will set the promo prefs and send the | 277 // The downloader will set the promo prefs and send the |
| 502 // NOTIFICATION_WEB_STORE_PROMO_LOADED notification. | 278 // NOTIFICATION_WEB_STORE_PROMO_LOADED notification. |
| 503 promo_data.link = GURL(promo_link); | 279 promo_data.link = GURL(promo_link); |
| 504 promo_data.logo = GURL(promo_logo); | 280 promo_data.logo = GURL(promo_logo); |
| 505 apps_promo_logo_fetcher_.reset( | 281 apps_promo_logo_fetcher_.reset( |
| 506 new AppsPromoLogoFetcher(profile_, promo_data)); | 282 new AppsPromoLogoFetcher(profile_, promo_data)); |
| 507 signal_found = true; | 283 signal_found = true; |
| 508 break; | 284 break; |
| 509 } | 285 } |
| 510 } | 286 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 if (!(old_logo_start == logo_start) || | 353 if (!(old_logo_start == logo_start) || |
| 578 !(old_logo_end == logo_end)) { | 354 !(old_logo_end == logo_end)) { |
| 579 prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); | 355 prefs_->SetDouble(prefs::kNTPCustomLogoStart, logo_start); |
| 580 prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); | 356 prefs_->SetDouble(prefs::kNTPCustomLogoEnd, logo_end); |
| 581 NotificationService* service = NotificationService::current(); | 357 NotificationService* service = NotificationService::current(); |
| 582 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, | 358 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, |
| 583 Source<WebResourceService>(this), | 359 Source<WebResourceService>(this), |
| 584 NotificationService::NoDetails()); | 360 NotificationService::NoDetails()); |
| 585 } | 361 } |
| 586 } | 362 } |
| OLD | NEW |