Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: chrome/browser/web_resource/notification_promo.cc

Issue 8520009: Only show G+ promo for users logged into G+ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/notification_promo.h" 5 #include "chrome/browser/web_resource/notification_promo.h"
6 6
7 #include "base/bind.h"
7 #include "base/rand_util.h" 8 #include "base/rand_util.h"
8 #include "base/string_number_conversions.h" 9 #include "base/string_number_conversions.h"
10 #include "base/string_split.h"
9 #include "base/time.h" 11 #include "base/time.h"
10 #include "base/values.h" 12 #include "base/values.h"
11 #include "chrome/browser/prefs/pref_service.h" 13 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile_impl.h"
12 #include "chrome/browser/web_resource/promo_resource_service.h" 15 #include "chrome/browser/web_resource/promo_resource_service.h"
13 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
17 #include "googleurl/src/gurl.h"
18 #include "net/base/cookie_store.h"
19 #include "net/url_request/url_request_context.h"
14 20
15 namespace { 21 namespace {
16 22
17 // Maximum number of views. 23 // Maximum number of views.
18 static const int kMaxViews = 1000; 24 static const int kMaxViews = 1000;
19 25
20 // Maximum number of hours for each time slice (4 weeks). 26 // Maximum number of hours for each time slice (4 weeks).
21 static const int kMaxTimeSliceHours = 24 * 7 * 4; 27 static const int kMaxTimeSliceHours = 24 * 7 * 4;
22 28
23 bool OutOfBounds(int var, int min, int max) { 29 bool OutOfBounds(int var, int min, int max) {
24 return var < min || var > max; 30 return var < min || var > max;
25 } 31 }
26 32
27 static const char kHeaderProperty[] = "topic"; 33 static const char kHeaderProperty[] = "topic";
28 static const char kArrayProperty[] = "answers"; 34 static const char kArrayProperty[] = "answers";
29 static const char kIdentifierProperty[] = "name"; 35 static const char kIdentifierProperty[] = "name";
30 static const char kStartPropertyValue[] = "promo_start"; 36 static const char kStartPropertyValue[] = "promo_start";
31 static const char kEndPropertyValue[] = "promo_end"; 37 static const char kEndPropertyValue[] = "promo_end";
32 static const char kTextProperty[] = "tooltip"; 38 static const char kTextProperty[] = "tooltip";
33 static const char kTimeProperty[] = "inproduct"; 39 static const char kTimeProperty[] = "inproduct";
34 static const char kParamsProperty[] = "question"; 40 static const char kParamsProperty[] = "question";
35 41
42 static const char kGPlusDomainUrl[] = "http://plus.google.com/";
43 static const char kGPlusDomainSecureCookieId[] = "SID=";
44 static const char kSplitStringToken = ';';
45
36 // Time getters. 46 // Time getters.
37 double GetTimeFromDict(const DictionaryValue* dict) { 47 double GetTimeFromDict(const DictionaryValue* dict) {
38 std::string time_str; 48 std::string time_str;
39 if (!dict->GetString(kTimeProperty, &time_str)) 49 if (!dict->GetString(kTimeProperty, &time_str))
40 return 0.0; 50 return 0.0;
41 51
42 base::Time time; 52 base::Time time;
43 if (time_str.empty() || !base::Time::FromString(time_str.c_str(), &time)) 53 if (time_str.empty() || !base::Time::FromString(time_str.c_str(), &time))
44 return 0.0; 54 return 0.0;
45 55
46 return time.ToDoubleT(); 56 return time.ToDoubleT();
47 } 57 }
48 58
49 double GetTimeFromPrefs(PrefService* prefs, const char* pref) { 59 double GetTimeFromPrefs(PrefService* prefs, const char* pref) {
50 return prefs->HasPrefPath(pref) ? prefs->GetDouble(pref) : 0.0; 60 return prefs->HasPrefPath(pref) ? prefs->GetDouble(pref) : 0.0;
51 } 61 }
52 62
53 } // namespace 63 } // namespace
54 64
55 NotificationPromo::NotificationPromo(PrefService* prefs, Delegate* delegate) 65 NotificationPromo::NotificationPromo(Profile* profile, Delegate* delegate)
56 : prefs_(prefs), 66 : profile_(profile),
57 delegate_(delegate), 67 delegate_(delegate),
68 prefs_(profile_->GetPrefs()),
58 start_(0.0), 69 start_(0.0),
59 end_(0.0), 70 end_(0.0),
60 build_(PromoResourceService::NO_BUILD), 71 build_(PromoResourceService::NO_BUILD),
61 time_slice_(0), 72 time_slice_(0),
62 max_group_(0), 73 max_group_(0),
63 max_views_(0), 74 max_views_(0),
64 platform_(PLATFORM_NONE), 75 platform_(PLATFORM_NONE),
65 group_(0), 76 group_(0),
66 views_(0), 77 views_(0),
67 text_(), 78 text_(),
68 closed_(false) { 79 closed_(false),
69 DCHECK(prefs); 80 gplus_(false),
81 feature_mask_(0) {
82 DCHECK(profile);
83 DCHECK(prefs_);
70 } 84 }
71 85
72 void NotificationPromo::InitFromJson(const DictionaryValue& json) { 86 NotificationPromo::~NotificationPromo() {}
87
88 void NotificationPromo::InitFromJson(const DictionaryValue& json,
89 bool do_cookie_check) {
73 DictionaryValue* dict; 90 DictionaryValue* dict;
74 if (json.GetDictionary(kHeaderProperty, &dict)) { 91 if (json.GetDictionary(kHeaderProperty, &dict)) {
75 ListValue* answers; 92 ListValue* answers;
76 if (dict->GetList(kArrayProperty, &answers)) { 93 if (dict->GetList(kArrayProperty, &answers)) {
77 for (ListValue::const_iterator it = answers->begin(); 94 for (ListValue::const_iterator it = answers->begin();
78 it != answers->end(); 95 it != answers->end();
79 ++it) { 96 ++it) {
80 if ((*it)->IsType(Value::TYPE_DICTIONARY)) 97 if ((*it)->IsType(Value::TYPE_DICTIONARY))
81 Parse(static_cast<DictionaryValue*>(*it)); 98 Parse(static_cast<DictionaryValue*>(*it));
82 } 99 }
83 } 100 }
84 } 101 }
102 if (do_cookie_check) {
103 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
104 base::Bind(&NotificationPromo::GetCookies, this,
105 profile_->GetRequestContext()));
106 } else {
107 CheckForNewNotification(false);
108 }
109 }
85 110
86 CheckForNewNotification(); 111 // static
112 bool NotificationPromo::CheckForGPlusCookie(const std::string& cookies) {
113 std::vector<std::string> cookie_list;
114 base::SplitString(cookies, kSplitStringToken, &cookie_list);
115 for (std::vector<std::string>::const_iterator current = cookie_list.begin();
116 current != cookie_list.end();
117 ++current) {
118 if ((*current).find(kGPlusDomainSecureCookieId) == 0) {
119 return true;
120 }
121 }
122 return false;
123 }
124
125 void NotificationPromo::GetCookiesCallback(const std::string& cookies) {
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
127 bool found_cookie = NotificationPromo::CheckForGPlusCookie(cookies);
128 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
129 base::Bind(&NotificationPromo::CheckForNewNotification, this,
130 found_cookie));
131 }
132
133 void NotificationPromo::GetCookies(net::URLRequestContextGetter* getter) {
134 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
135 getter->GetURLRequestContext()->cookie_store()->
136 GetCookiesWithOptionsAsync(
137 GURL(kGPlusDomainUrl), net::CookieOptions(),
138 base::Bind(&NotificationPromo::GetCookiesCallback, this));
87 } 139 }
88 140
89 void NotificationPromo::Parse(const DictionaryValue* dict) { 141 void NotificationPromo::Parse(const DictionaryValue* dict) {
90 std::string key; 142 std::string key;
91 if (dict->GetString(kIdentifierProperty, &key)) { 143 if (dict->GetString(kIdentifierProperty, &key)) {
92 if (key == kStartPropertyValue) { 144 if (key == kStartPropertyValue) {
93 ParseParams(dict); 145 ParseParams(dict);
94 dict->GetString(kTextProperty, &text_); 146 dict->GetString(kTextProperty, &text_);
95 start_ = GetTimeFromDict(dict); 147 start_ = GetTimeFromDict(dict);
96 } else if (key == kEndPropertyValue) { 148 } else if (key == kEndPropertyValue) {
97 end_ = GetTimeFromDict(dict); 149 end_ = GetTimeFromDict(dict);
98 } 150 }
99 } 151 }
100 } 152 }
101 153
102 void NotificationPromo::ParseParams(const DictionaryValue* dict) { 154 void NotificationPromo::ParseParams(const DictionaryValue* dict) {
103 std::string question; 155 std::string question;
104 if (!dict->GetString(kParamsProperty, &question)) 156 if (!dict->GetString(kParamsProperty, &question))
105 return; 157 return;
106 158
107 size_t index = 0; 159 size_t index = 0;
108 bool err = false; 160 bool err = false;
109 161
110 build_ = GetNextQuestionValue(question, &index, &err); 162 build_ = GetNextQuestionValue(question, &index, &err);
111 time_slice_ = GetNextQuestionValue(question, &index, &err); 163 time_slice_ = GetNextQuestionValue(question, &index, &err);
112 max_group_ = GetNextQuestionValue(question, &index, &err); 164 max_group_ = GetNextQuestionValue(question, &index, &err);
113 max_views_ = GetNextQuestionValue(question, &index, &err); 165 max_views_ = GetNextQuestionValue(question, &index, &err);
114 platform_ = GetNextQuestionValue(question, &index, &err); 166 platform_ = GetNextQuestionValue(question, &index, &err);
167 feature_mask_ = GetNextQuestionValue(question, &index, &err);
115 168
116 if (err || 169 if (err ||
117 OutOfBounds(build_, PromoResourceService::NO_BUILD, 170 OutOfBounds(build_, PromoResourceService::NO_BUILD,
118 PromoResourceService::ALL_BUILDS) || 171 PromoResourceService::ALL_BUILDS) ||
119 OutOfBounds(time_slice_, 0, kMaxTimeSliceHours) || 172 OutOfBounds(time_slice_, 0, kMaxTimeSliceHours) ||
120 OutOfBounds(max_group_, 0, kMaxGroupSize) || 173 OutOfBounds(max_group_, 0, kMaxGroupSize) ||
121 OutOfBounds(max_views_, 0, kMaxViews) || 174 OutOfBounds(max_views_, 0, kMaxViews) ||
122 OutOfBounds(platform_, PLATFORM_NONE, PLATFORM_ALL)) { 175 OutOfBounds(platform_, PLATFORM_NONE, PLATFORM_ALL)) {
123 // If values are not valid, do not show promo notification. 176 // If values are not valid, do not show promo notification.
124 DLOG(ERROR) << "Invalid server data, question=" << question << 177 DLOG(ERROR) << "Invalid server data, question=" << question <<
125 ", build=" << build_ << 178 ", build=" << build_ <<
126 ", time_slice=" << time_slice_ << 179 ", time_slice=" << time_slice_ <<
127 ", max_group=" << max_group_ << 180 ", max_group=" << max_group_ <<
128 ", max_views=" << max_views_ << 181 ", max_views=" << max_views_ <<
129 ", platform_=" << platform_; 182 ", platform_=" << platform_ <<
183 ", feature_mask=" << feature_mask_;
130 build_ = PromoResourceService::NO_BUILD; 184 build_ = PromoResourceService::NO_BUILD;
131 time_slice_ = 0; 185 time_slice_ = 0;
132 max_group_ = 0; 186 max_group_ = 0;
133 max_views_ = 0; 187 max_views_ = 0;
134 platform_ = PLATFORM_NONE; 188 platform_ = PLATFORM_NONE;
189 feature_mask_ = 0;
135 } 190 }
136 } 191 }
137 192
138 void NotificationPromo::CheckForNewNotification() { 193 void NotificationPromo::CheckForNewNotification(bool found_cookie) {
194 double start = 0.0;
195 double end = 0.0;
196 bool new_notification = false;
197
198 gplus_ = found_cookie;
139 const double old_start = GetTimeFromPrefs(prefs_, prefs::kNTPPromoStart); 199 const double old_start = GetTimeFromPrefs(prefs_, prefs::kNTPPromoStart);
140 const double old_end = GetTimeFromPrefs(prefs_, prefs::kNTPPromoEnd); 200 const double old_end = GetTimeFromPrefs(prefs_, prefs::kNTPPromoEnd);
141 const bool has_platform = prefs_->HasPrefPath(prefs::kNTPPromoPlatform); 201 const bool has_platform = prefs_->HasPrefPath(prefs::kNTPPromoPlatform);
142 202
203 const bool old_gplus = prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus);
204 const int old_feature_mask = prefs_->GetInteger(prefs::kNTPPromoFeatureMask);
143 // Trigger a new notification if the times have changed, or if 205 // Trigger a new notification if the times have changed, or if
144 // we previously never wrote out a platform preference. This handles 206 // we previously never wrote out a feature_mask or platform preference, or
145 // the case where we update to a new client in the middle of a promo. 207 // if the user's gplus cookies have changed.
146 if (old_start != start_ || old_end != end_ || !has_platform) 208 if (old_start != start_ || old_end != end_ || old_gplus != gplus_ ||
209 old_feature_mask != feature_mask_ || !has_platform) {
147 OnNewNotification(); 210 OnNewNotification();
211 start = StartTimeWithOffset();
212 end = end_;
213 new_notification = true;
214 }
215 if (delegate_) {
216 // If no change needed, call delegate with default values (this
217 // is for testing purposes).
218 delegate_->OnNotificationParsed(start, end, new_notification);
219 }
148 } 220 }
149 221
150 void NotificationPromo::OnNewNotification() { 222 void NotificationPromo::OnNewNotification() {
151 group_ = NewGroup(); 223 group_ = NewGroup();
152 WritePrefs(); 224 WritePrefs();
153 if (delegate_)
154 delegate_->OnNewNotification(StartTimeWithOffset(), end_);
155 } 225 }
156 226
157 // static 227 // static
158 int NotificationPromo::NewGroup() { 228 int NotificationPromo::NewGroup() {
159 return base::RandInt(0, kMaxGroupSize); 229 return base::RandInt(0, kMaxGroupSize);
160 } 230 }
161 231
162 // static 232 // static
163 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) { 233 void NotificationPromo::RegisterUserPrefs(PrefService* prefs) {
164 prefs->RegisterDoublePref(prefs::kNTPPromoStart, 234 prefs->RegisterDoublePref(prefs::kNTPPromoStart,
(...skipping 24 matching lines...) Expand all
189 PrefService::UNSYNCABLE_PREF); 259 PrefService::UNSYNCABLE_PREF);
190 prefs->RegisterIntegerPref(prefs::kNTPPromoGroup, 260 prefs->RegisterIntegerPref(prefs::kNTPPromoGroup,
191 0, 261 0,
192 PrefService::UNSYNCABLE_PREF); 262 PrefService::UNSYNCABLE_PREF);
193 prefs->RegisterIntegerPref(prefs::kNTPPromoViews, 263 prefs->RegisterIntegerPref(prefs::kNTPPromoViews,
194 0, 264 0,
195 PrefService::UNSYNCABLE_PREF); 265 PrefService::UNSYNCABLE_PREF);
196 prefs->RegisterBooleanPref(prefs::kNTPPromoClosed, 266 prefs->RegisterBooleanPref(prefs::kNTPPromoClosed,
197 false, 267 false,
198 PrefService::UNSYNCABLE_PREF); 268 PrefService::UNSYNCABLE_PREF);
269 prefs->RegisterBooleanPref(prefs::kNTPPromoIsLoggedInToPlus,
270 false,
271 PrefService::UNSYNCABLE_PREF);
272 prefs->RegisterIntegerPref(prefs::kNTPPromoFeatureMask,
273 0,
274 PrefService::UNSYNCABLE_PREF);
199 } 275 }
200 276
277 // static
278 NotificationPromo* NotificationPromo::Create(Profile *profile,
279 NotificationPromo::Delegate * delegate) {
280 return new NotificationPromo(profile, delegate);
281 }
201 282
202 void NotificationPromo::WritePrefs() { 283 void NotificationPromo::WritePrefs() {
203 prefs_->SetDouble(prefs::kNTPPromoStart, start_); 284 prefs_->SetDouble(prefs::kNTPPromoStart, start_);
204 prefs_->SetDouble(prefs::kNTPPromoEnd, end_); 285 prefs_->SetDouble(prefs::kNTPPromoEnd, end_);
205 286
206 prefs_->SetInteger(prefs::kNTPPromoBuild, build_); 287 prefs_->SetInteger(prefs::kNTPPromoBuild, build_);
207 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, time_slice_); 288 prefs_->SetInteger(prefs::kNTPPromoGroupTimeSlice, time_slice_);
208 prefs_->SetInteger(prefs::kNTPPromoGroupMax, max_group_); 289 prefs_->SetInteger(prefs::kNTPPromoGroupMax, max_group_);
209 prefs_->SetInteger(prefs::kNTPPromoViewsMax, max_views_); 290 prefs_->SetInteger(prefs::kNTPPromoViewsMax, max_views_);
210 prefs_->SetInteger(prefs::kNTPPromoPlatform, platform_); 291 prefs_->SetInteger(prefs::kNTPPromoPlatform, platform_);
211 292
212 prefs_->SetString(prefs::kNTPPromoLine, text_); 293 prefs_->SetString(prefs::kNTPPromoLine, text_);
213 prefs_->SetInteger(prefs::kNTPPromoGroup, group_); 294 prefs_->SetInteger(prefs::kNTPPromoGroup, group_);
214 prefs_->SetInteger(prefs::kNTPPromoViews, views_); 295 prefs_->SetInteger(prefs::kNTPPromoViews, views_);
215 prefs_->SetBoolean(prefs::kNTPPromoClosed, closed_); 296 prefs_->SetBoolean(prefs::kNTPPromoClosed, closed_);
297 prefs_->SetBoolean(prefs::kNTPPromoIsLoggedInToPlus, gplus_);
298 prefs_->SetInteger(prefs::kNTPPromoFeatureMask, feature_mask_);
216 } 299 }
217 300
218 void NotificationPromo::InitFromPrefs() { 301 void NotificationPromo::InitFromPrefs() {
219 start_ = prefs_->GetDouble(prefs::kNTPPromoStart); 302 start_ = prefs_->GetDouble(prefs::kNTPPromoStart);
220 end_ = prefs_->GetDouble(prefs::kNTPPromoEnd); 303 end_ = prefs_->GetDouble(prefs::kNTPPromoEnd);
221 build_ = prefs_->GetInteger(prefs::kNTPPromoBuild); 304 build_ = prefs_->GetInteger(prefs::kNTPPromoBuild);
222 time_slice_ = prefs_->GetInteger(prefs::kNTPPromoGroupTimeSlice); 305 time_slice_ = prefs_->GetInteger(prefs::kNTPPromoGroupTimeSlice);
223 max_group_ = prefs_->GetInteger(prefs::kNTPPromoGroupMax); 306 max_group_ = prefs_->GetInteger(prefs::kNTPPromoGroupMax);
224 max_views_ = prefs_->GetInteger(prefs::kNTPPromoViewsMax); 307 max_views_ = prefs_->GetInteger(prefs::kNTPPromoViewsMax);
225 platform_ = prefs_->GetInteger(prefs::kNTPPromoPlatform); 308 platform_ = prefs_->GetInteger(prefs::kNTPPromoPlatform);
226 text_ = prefs_->GetString(prefs::kNTPPromoLine); 309 text_ = prefs_->GetString(prefs::kNTPPromoLine);
227 group_ = prefs_->GetInteger(prefs::kNTPPromoGroup); 310 group_ = prefs_->GetInteger(prefs::kNTPPromoGroup);
228 views_ = prefs_->GetInteger(prefs::kNTPPromoViews); 311 views_ = prefs_->GetInteger(prefs::kNTPPromoViews);
229 closed_ = prefs_->GetBoolean(prefs::kNTPPromoClosed); 312 closed_ = prefs_->GetBoolean(prefs::kNTPPromoClosed);
313
314 if (prefs_->HasPrefPath(prefs::kNTPPromoIsLoggedInToPlus))
315 gplus_ = prefs_->GetBoolean(prefs::kNTPPromoIsLoggedInToPlus);
316
317 if (prefs_->HasPrefPath(prefs::kNTPPromoFeatureMask))
318 feature_mask_ = prefs_->GetInteger(prefs::kNTPPromoFeatureMask);
230 } 319 }
231 320
232 bool NotificationPromo::CanShow() const { 321 bool NotificationPromo::CanShow() const {
233 return !closed_ && 322 return !closed_ &&
234 !text_.empty() && 323 !text_.empty() &&
235 group_ < max_group_ && 324 group_ < max_group_ &&
236 views_ < max_views_ && 325 views_ < max_views_ &&
237 IsPlatformAllowed(platform_) && 326 IsPlatformAllowed(platform_) &&
238 IsBuildAllowed(build_) && 327 IsBuildAllowed(build_) &&
239 base::Time::FromDoubleT(StartTimeWithOffset()) < base::Time::Now() && 328 base::Time::FromDoubleT(StartTimeWithOffset()) < base::Time::Now() &&
240 base::Time::FromDoubleT(end_) > base::Time::Now(); 329 base::Time::FromDoubleT(end_) > base::Time::Now() &&
330 (!(feature_mask_ & NotificationPromo::FEATURE_GPLUS) || gplus_);
241 } 331 }
242 332
243 void NotificationPromo::HandleClosed() { 333 void NotificationPromo::HandleClosed() {
244 prefs_->SetBoolean(prefs::kNTPPromoClosed, true); 334 prefs_->SetBoolean(prefs::kNTPPromoClosed, true);
245 } 335 }
246 336
247 bool NotificationPromo::HandleViewed() { 337 bool NotificationPromo::HandleViewed() {
248 if (prefs_->HasPrefPath(prefs::kNTPPromoViewsMax)) 338 if (prefs_->HasPrefPath(prefs::kNTPPromoViewsMax))
249 max_views_ = prefs_->GetInteger(prefs::kNTPPromoViewsMax); 339 max_views_ = prefs_->GetInteger(prefs::kNTPPromoViewsMax);
250 340
(...skipping 24 matching lines...) Expand all
275 // Order is important - OS_LINUX and OS_CHROMEOS can both be defined. 365 // Order is important - OS_LINUX and OS_CHROMEOS can both be defined.
276 #if defined(OS_WIN) 366 #if defined(OS_WIN)
277 return PLATFORM_WIN; 367 return PLATFORM_WIN;
278 #elif defined(OS_MACOSX) 368 #elif defined(OS_MACOSX)
279 return PLATFORM_MAC; 369 return PLATFORM_MAC;
280 #elif defined(OS_CHROMEOS) 370 #elif defined(OS_CHROMEOS)
281 return PLATFORM_CHROMEOS; 371 return PLATFORM_CHROMEOS;
282 #elif defined(OS_LINUX) 372 #elif defined(OS_LINUX)
283 return PLATFORM_LINUX; 373 return PLATFORM_LINUX;
284 #else 374 #else
285 return PLATFORM_NONE; 375 return PLATFORM_NONE;
286 #endif 376 #endif
287 } 377 }
288 378
289 double NotificationPromo::StartTimeWithOffset() const { 379 double NotificationPromo::StartTimeWithOffset() const {
290 // Adjust start using group and time slice, adjusted from hours to seconds. 380 // Adjust start using group and time slice, adjusted from hours to seconds.
291 static const double kSecondsInHour = 60.0 * 60.0; 381 static const double kSecondsInHour = 60.0 * 60.0;
292 return start_ + group_ * time_slice_ * kSecondsInHour; 382 return start_ + group_ * time_slice_ * kSecondsInHour;
293 } 383 }
294 384
295 // static 385 // static
(...skipping 19 matching lines...) Expand all
315 start_ == other.start_ && 405 start_ == other.start_ &&
316 end_ == other.end_ && 406 end_ == other.end_ &&
317 build_ == other.build_ && 407 build_ == other.build_ &&
318 time_slice_ == other.time_slice_ && 408 time_slice_ == other.time_slice_ &&
319 max_group_ == other.max_group_ && 409 max_group_ == other.max_group_ &&
320 max_views_ == other.max_views_ && 410 max_views_ == other.max_views_ &&
321 platform_ == other.platform_ && 411 platform_ == other.platform_ &&
322 group_ == other.group_ && 412 group_ == other.group_ &&
323 views_ == other.views_ && 413 views_ == other.views_ &&
324 text_ == other.text_ && 414 text_ == other.text_ &&
325 closed_ == other.closed_; 415 closed_ == other.closed_ &&
416 gplus_ == other.gplus_ &&
417 feature_mask_ == other.feature_mask_;
326 } 418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698