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