OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 // to versions with different types of promos). | 37 // to versions with different types of promos). |
38 static const int kPromoServiceVersion = 7; | 38 static const int kPromoServiceVersion = 7; |
39 | 39 |
40 // Properties used by the server. | 40 // Properties used by the server. |
41 static const char kAnswerIdProperty[] = "answer_id"; | 41 static const char kAnswerIdProperty[] = "answer_id"; |
42 static const char kWebStoreHeaderProperty[] = "question"; | 42 static const char kWebStoreHeaderProperty[] = "question"; |
43 static const char kWebStoreButtonProperty[] = "inproduct_target"; | 43 static const char kWebStoreButtonProperty[] = "inproduct_target"; |
44 static const char kWebStoreLinkProperty[] = "inproduct"; | 44 static const char kWebStoreLinkProperty[] = "inproduct"; |
45 static const char kWebStoreExpireProperty[] = "tooltip"; | 45 static const char kWebStoreExpireProperty[] = "tooltip"; |
46 | 46 |
47 GURL GetPromoResourceURL(bool legacy) { | 47 GURL GetPromoResourceURL() { |
48 const std::string promo_server_url = CommandLine::ForCurrentProcess()-> | 48 const std::string promo_server_url = CommandLine::ForCurrentProcess()-> |
49 GetSwitchValueASCII(switches::kPromoServerURL); | 49 GetSwitchValueASCII(switches::kPromoServerURL); |
50 if (!promo_server_url.empty()) | 50 return promo_server_url.empty() ? |
51 return GURL(promo_server_url); | 51 NotificationPromo::PromoServerURL() : GURL(promo_server_url); |
52 return legacy ? GURL(PromoResourceService::kDefaultPromoResourceServer) : | |
53 NotificationPromo::PromoServerURL(); | |
54 } | 52 } |
55 | 53 |
56 bool IsTest() { | 54 bool IsTest() { |
57 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kPromoServerURL); | 55 return CommandLine::ForCurrentProcess()->HasSwitch(switches::kPromoServerURL); |
58 } | 56 } |
59 | 57 |
60 int GetCacheUpdateDelay() { | 58 int GetCacheUpdateDelay() { |
61 return IsTest() ? kTestCacheUpdateDelay : kCacheUpdateDelay; | 59 return IsTest() ? kTestCacheUpdateDelay : kCacheUpdateDelay; |
62 } | 60 } |
63 | 61 |
64 } // namespace | 62 } // namespace |
65 | 63 |
66 // Server for dynamically loaded NTP HTML elements. | |
67 const char* PromoResourceService::kDefaultPromoResourceServer = | |
68 "https://www.google.com/support/chrome/bin/topic/1142433/inproduct?hl="; | |
69 | |
70 | |
71 | |
72 // static | 64 // static |
73 void PromoResourceService::RegisterPrefs(PrefService* local_state) { | 65 void PromoResourceService::RegisterPrefs(PrefService* local_state) { |
74 local_state->RegisterIntegerPref(prefs::kNtpPromoVersion, 0); | 66 local_state->RegisterIntegerPref(prefs::kNtpPromoVersion, 0); |
75 local_state->RegisterStringPref(prefs::kNtpPromoLocale, std::string()); | 67 local_state->RegisterStringPref(prefs::kNtpPromoLocale, std::string()); |
76 } | 68 } |
77 | 69 |
78 // static | 70 // static |
79 void PromoResourceService::RegisterUserPrefs(PrefService* prefs) { | 71 void PromoResourceService::RegisterUserPrefs(PrefService* prefs) { |
80 prefs->RegisterStringPref(prefs::kNtpPromoResourceCacheUpdate, | 72 prefs->RegisterStringPref(prefs::kNtpPromoResourceCacheUpdate, |
81 "0", | 73 "0", |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 return (STABLE_BUILD & builds_allowed) != 0; | 107 return (STABLE_BUILD & builds_allowed) != 0; |
116 default: | 108 default: |
117 // Show promos for local builds when using a custom promo URL. | 109 // Show promos for local builds when using a custom promo URL. |
118 return CommandLine::ForCurrentProcess()->HasSwitch( | 110 return CommandLine::ForCurrentProcess()->HasSwitch( |
119 switches::kPromoServerURL); | 111 switches::kPromoServerURL); |
120 } | 112 } |
121 } | 113 } |
122 | 114 |
123 PromoResourceService::PromoResourceService(Profile* profile) | 115 PromoResourceService::PromoResourceService(Profile* profile) |
124 : WebResourceService(profile->GetPrefs(), | 116 : WebResourceService(profile->GetPrefs(), |
125 GetPromoResourceURL(false), | 117 GetPromoResourceURL(), |
126 true, // append locale to URL | 118 true, // append locale to URL |
127 prefs::kNtpPromoResourceCacheUpdate, | 119 prefs::kNtpPromoResourceCacheUpdate, |
128 kStartResourceFetchDelay, | 120 kStartResourceFetchDelay, |
129 GetCacheUpdateDelay()), | 121 GetCacheUpdateDelay()), |
130 profile_(profile), | 122 profile_(profile), |
131 channel_(chrome::VersionInfo::CHANNEL_UNKNOWN), | 123 channel_(chrome::VersionInfo::CHANNEL_UNKNOWN), |
132 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | 124 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), |
133 web_resource_update_scheduled_(false) { | 125 web_resource_update_scheduled_(false) { |
134 ScheduleNotificationOnInit(); | 126 ScheduleNotificationOnInit(); |
135 } | 127 } |
136 | 128 |
137 PromoResourceService::~PromoResourceService() { } | 129 PromoResourceService::~PromoResourceService() { } |
138 | 130 |
139 bool PromoResourceService::IsBuildTargeted(int builds_targeted) { | 131 bool PromoResourceService::IsBuildTargeted(int builds_targeted) { |
140 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) | 132 if (channel_ == chrome::VersionInfo::CHANNEL_UNKNOWN) |
141 channel_ = GetChannel(); | 133 channel_ = GetChannel(); |
142 | 134 |
143 return IsBuildTargeted(channel_, builds_targeted); | 135 return IsBuildTargeted(channel_, builds_targeted); |
144 } | 136 } |
145 | 137 |
146 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { | 138 void PromoResourceService::Unpack(const DictionaryValue& parsed_json) { |
147 UnpackLogoSignal(parsed_json); | 139 UnpackLogoSignal(parsed_json); |
148 UnpackNotificationSignal(parsed_json); | 140 UnpackNotificationSignal(parsed_json); |
149 UnpackWebStoreSignal(parsed_json); | 141 UnpackWebStoreSignal(parsed_json); |
150 } | 142 } |
151 | 143 |
152 void PromoResourceService::OnNotificationParsed(double start, double end, | |
153 bool new_notification) { | |
154 if (new_notification) { | |
155 ScheduleNotification(start, end); | |
156 } | |
157 } | |
158 | |
159 void PromoResourceService::ScheduleNotification(double promo_start, | 144 void PromoResourceService::ScheduleNotification(double promo_start, |
160 double promo_end) { | 145 double promo_end) { |
161 if (promo_start > 0 && promo_end > 0) { | 146 if (promo_start > 0 && promo_end > 0) { |
162 int64 ms_until_start = | 147 int64 ms_until_start = |
163 static_cast<int64>((base::Time::FromDoubleT( | 148 static_cast<int64>((base::Time::FromDoubleT( |
164 promo_start) - base::Time::Now()).InMilliseconds()); | 149 promo_start) - base::Time::Now()).InMilliseconds()); |
165 int64 ms_until_end = | 150 int64 ms_until_end = |
166 static_cast<int64>((base::Time::FromDoubleT( | 151 static_cast<int64>((base::Time::FromDoubleT( |
167 promo_end) - base::Time::Now()).InMilliseconds()); | 152 promo_end) - base::Time::Now()).InMilliseconds()); |
168 if (ms_until_start > 0) | 153 if (ms_until_start > 0) |
169 PostNotification(ms_until_start); | 154 PostNotification(ms_until_start); |
170 if (ms_until_end > 0) { | 155 if (ms_until_end > 0) { |
171 PostNotification(ms_until_end); | 156 PostNotification(ms_until_end); |
172 if (ms_until_start <= 0) { | 157 if (ms_until_start <= 0) { |
173 // Notify immediately if time is between start and end. | 158 // Notify immediately if time is between start and end. |
174 PostNotification(0); | 159 PostNotification(0); |
175 } | 160 } |
176 } | 161 } |
177 } | 162 } |
178 } | 163 } |
179 | 164 |
180 void PromoResourceService::ScheduleNotificationOnInit() { | 165 void PromoResourceService::ScheduleNotificationOnInit() { |
181 std::string locale = g_browser_process->GetApplicationLocale(); | 166 std::string locale = g_browser_process->GetApplicationLocale(); |
182 if ((GetPromoServiceVersion() != kPromoServiceVersion) || | 167 if (GetPromoServiceVersion() != kPromoServiceVersion || |
183 (GetPromoLocale() != locale)) { | 168 GetPromoLocale() != locale) { |
184 // If the promo service has been upgraded or Chrome switched locales, | 169 // If the promo service has been upgraded or Chrome switched locales, |
185 // refresh the promos. | 170 // refresh the promos. |
| 171 // TODO(achuith): Mixing local_state and prefs does not work for |
| 172 // multi-profile case. We should probably store version/locale in prefs_ |
| 173 // as well. |
186 PrefService* local_state = g_browser_process->local_state(); | 174 PrefService* local_state = g_browser_process->local_state(); |
187 local_state->SetInteger(prefs::kNtpPromoVersion, kPromoServiceVersion); | 175 local_state->SetInteger(prefs::kNtpPromoVersion, kPromoServiceVersion); |
188 local_state->SetString(prefs::kNtpPromoLocale, locale); | 176 local_state->SetString(prefs::kNtpPromoLocale, locale); |
189 prefs_->ClearPref(prefs::kNtpPromoResourceCacheUpdate); | 177 prefs_->ClearPref(prefs::kNtpPromoResourceCacheUpdate); |
190 AppsPromo::ClearPromo(); | 178 AppsPromo::ClearPromo(); |
191 PostNotification(0); | 179 PostNotification(0); |
192 } else { | 180 } else { |
193 // If the promo start is in the future, set a notification task to | 181 // If the promo start is in the future, set a notification task to |
194 // invalidate the NTP cache at the time of the promo start. | 182 // invalidate the NTP cache at the time of the promo start. |
195 double promo_start = prefs_->GetDouble(prefs::kNtpPromoStart); | 183 double promo_start = prefs_->GetDouble(prefs::kNtpPromoStart); |
196 double promo_end = prefs_->GetDouble(prefs::kNtpPromoEnd); | 184 double promo_end = prefs_->GetDouble(prefs::kNtpPromoEnd); |
197 ScheduleNotification(promo_start, promo_end); | 185 ScheduleNotification(promo_start, promo_end); |
198 } | 186 } |
199 } | 187 } |
200 | 188 |
201 void PromoResourceService::PostNotification(int64 delay_ms) { | 189 void PromoResourceService::PostNotification(int64 delay_ms) { |
202 if (web_resource_update_scheduled_) | 190 if (web_resource_update_scheduled_) |
203 return; | 191 return; |
| 192 // TODO(achuith): This crashes if we post delay_ms = 0 to the message loop. |
| 193 // during startup. |
204 if (delay_ms > 0) { | 194 if (delay_ms > 0) { |
205 web_resource_update_scheduled_ = true; | 195 web_resource_update_scheduled_ = true; |
206 MessageLoop::current()->PostDelayedTask( | 196 MessageLoop::current()->PostDelayedTask( |
207 FROM_HERE, | 197 FROM_HERE, |
208 base::Bind(&PromoResourceService::PromoResourceStateChange, | 198 base::Bind(&PromoResourceService::PromoResourceStateChange, |
209 weak_ptr_factory_.GetWeakPtr()), | 199 weak_ptr_factory_.GetWeakPtr()), |
210 base::TimeDelta::FromMilliseconds(delay_ms)); | 200 base::TimeDelta::FromMilliseconds(delay_ms)); |
211 } else if (delay_ms == 0) { | 201 } else if (delay_ms == 0) { |
212 PromoResourceStateChange(); | 202 PromoResourceStateChange(); |
213 } | 203 } |
(...skipping 13 matching lines...) Expand all Loading... |
227 return local_state->GetInteger(prefs::kNtpPromoVersion); | 217 return local_state->GetInteger(prefs::kNtpPromoVersion); |
228 } | 218 } |
229 | 219 |
230 std::string PromoResourceService::GetPromoLocale() { | 220 std::string PromoResourceService::GetPromoLocale() { |
231 PrefService* local_state = g_browser_process->local_state(); | 221 PrefService* local_state = g_browser_process->local_state(); |
232 return local_state->GetString(prefs::kNtpPromoLocale); | 222 return local_state->GetString(prefs::kNtpPromoLocale); |
233 } | 223 } |
234 | 224 |
235 void PromoResourceService::UnpackNotificationSignal( | 225 void PromoResourceService::UnpackNotificationSignal( |
236 const DictionaryValue& parsed_json) { | 226 const DictionaryValue& parsed_json) { |
237 scoped_refptr<NotificationPromo> notification_promo = | 227 NotificationPromo notification_promo(profile_); |
238 NotificationPromo::Create(profile_, this); | 228 notification_promo.InitFromJson(parsed_json); |
239 notification_promo->InitFromJson(parsed_json); | 229 |
| 230 if (notification_promo.new_notification()) { |
| 231 ScheduleNotification(notification_promo.StartTimeForGroup(), |
| 232 notification_promo.EndTime()); |
| 233 } |
240 } | 234 } |
241 | 235 |
242 bool PromoResourceService::CanShowNotificationPromo(Profile* profile) { | 236 bool PromoResourceService::CanShowNotificationPromo(Profile* profile) { |
243 scoped_refptr<NotificationPromo> notification_promo = | 237 NotificationPromo notification_promo(profile); |
244 NotificationPromo::Create(profile, NULL); | 238 notification_promo.InitFromPrefs(); |
245 notification_promo->InitFromPrefs(); | 239 return notification_promo.CanShow(); |
246 return notification_promo->CanShow(); | |
247 } | 240 } |
248 | 241 |
249 void PromoResourceService::UnpackWebStoreSignal( | 242 void PromoResourceService::UnpackWebStoreSignal( |
250 const DictionaryValue& parsed_json) { | 243 const DictionaryValue& parsed_json) { |
251 DictionaryValue* topic_dict; | 244 DictionaryValue* topic_dict; |
252 ListValue* answer_list; | 245 ListValue* answer_list; |
253 | 246 |
254 bool is_webstore_active = false; | 247 bool is_webstore_active = false; |
255 bool signal_found = false; | 248 bool signal_found = false; |
256 AppsPromo::PromoData promo_data; | 249 AppsPromo::PromoData promo_data; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 !(old_logo_end == logo_end)) { | 382 !(old_logo_end == logo_end)) { |
390 prefs_->SetDouble(prefs::kNtpCustomLogoStart, logo_start); | 383 prefs_->SetDouble(prefs::kNtpCustomLogoStart, logo_start); |
391 prefs_->SetDouble(prefs::kNtpCustomLogoEnd, logo_end); | 384 prefs_->SetDouble(prefs::kNtpCustomLogoEnd, logo_end); |
392 content::NotificationService* service = | 385 content::NotificationService* service = |
393 content::NotificationService::current(); | 386 content::NotificationService::current(); |
394 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, | 387 service->Notify(chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED, |
395 content::Source<WebResourceService>(this), | 388 content::Source<WebResourceService>(this), |
396 content::NotificationService::NoDetails()); | 389 content::NotificationService::NoDetails()); |
397 } | 390 } |
398 } | 391 } |
OLD | NEW |