OLD | NEW |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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 "ios/chrome/browser/notification_promo.h" | 5 #include "ios/chrome/browser/notification_promo.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "base/time/time.h" | 11 #include "base/time/time.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "components/pref_registry/pref_registry_syncable.h" | 13 #include "components/pref_registry/pref_registry_syncable.h" |
14 #include "components/prefs/pref_registry_simple.h" | 14 #include "components/prefs/pref_registry_simple.h" |
15 #include "components/prefs/pref_service.h" | 15 #include "components/prefs/pref_service.h" |
16 #include "components/variations/variations_associated_data.h" | 16 #include "components/variations/variations_associated_data.h" |
17 | 17 |
18 namespace ios { | 18 namespace ios { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 const char kNTPPromoFinchExperiment[] = "IOSNTPPromotion"; | 22 const char kNTPPromoFinchExperiment[] = "IOSNTPPromotion"; |
23 | 23 |
24 // The name of the preference that stores the promotion object. | 24 // The name of the preference that stores the promotion object. |
25 const char kPrefPromoObject[] = "ios.ntppromo"; | 25 const char kPrefPromoObject[] = "ios.ntppromo"; |
26 | 26 |
27 // Keys in the kPrefPromoObject dictionary; used only here. | 27 // Keys in the kPrefPromoObject dictionary; used only here. |
| 28 const char kPrefPromoID[] = "id"; |
28 const char kPrefPromoFirstViewTime[] = "first_view_time"; | 29 const char kPrefPromoFirstViewTime[] = "first_view_time"; |
29 const char kPrefPromoViews[] = "views"; | 30 const char kPrefPromoViews[] = "views"; |
30 const char kPrefPromoClosed[] = "closed"; | 31 const char kPrefPromoClosed[] = "closed"; |
31 | 32 |
32 } // namespace | 33 } // namespace |
33 | 34 |
34 NotificationPromo::NotificationPromo(PrefService* local_state) | 35 NotificationPromo::NotificationPromo(PrefService* local_state) |
35 : local_state_(local_state), | 36 : local_state_(local_state), |
36 promo_type_(NO_PROMO), | 37 promo_type_(NO_PROMO), |
37 promo_payload_(new base::DictionaryValue()), | 38 promo_payload_(new base::DictionaryValue()), |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 user_prefs::PrefRegistrySyncable* registry) { | 129 user_prefs::PrefRegistrySyncable* registry) { |
129 registry->RegisterDictionaryPref(kPrefPromoObject); | 130 registry->RegisterDictionaryPref(kPrefPromoObject); |
130 } | 131 } |
131 | 132 |
132 // static | 133 // static |
133 void NotificationPromo::MigrateUserPrefs(PrefService* user_prefs) { | 134 void NotificationPromo::MigrateUserPrefs(PrefService* user_prefs) { |
134 user_prefs->ClearPref(kPrefPromoObject); | 135 user_prefs->ClearPref(kPrefPromoObject); |
135 } | 136 } |
136 | 137 |
137 void NotificationPromo::WritePrefs() { | 138 void NotificationPromo::WritePrefs() { |
| 139 WritePrefs(promo_id_, first_view_time_, views_, closed_); |
| 140 } |
| 141 |
| 142 void NotificationPromo::WritePrefs(int promo_id, |
| 143 double first_view_time, |
| 144 int views, |
| 145 bool closed) { |
138 base::DictionaryValue* ntp_promo = new base::DictionaryValue; | 146 base::DictionaryValue* ntp_promo = new base::DictionaryValue; |
139 ntp_promo->SetDouble(kPrefPromoFirstViewTime, first_view_time_); | 147 ntp_promo->SetDouble(kPrefPromoFirstViewTime, first_view_time); |
140 ntp_promo->SetInteger(kPrefPromoViews, views_); | 148 ntp_promo->SetInteger(kPrefPromoViews, views); |
141 ntp_promo->SetBoolean(kPrefPromoClosed, closed_); | 149 ntp_promo->SetBoolean(kPrefPromoClosed, closed); |
142 | 150 |
143 base::DictionaryValue promo_dict; | 151 base::DictionaryValue promo_dict; |
144 promo_dict.MergeDictionary(local_state_->GetDictionary(kPrefPromoObject)); | 152 promo_dict.MergeDictionary(local_state_->GetDictionary(kPrefPromoObject)); |
145 promo_dict.Set(base::IntToString(promo_id_), ntp_promo); | 153 promo_dict.Set(base::IntToString(promo_id), ntp_promo); |
146 local_state_->Set(kPrefPromoObject, promo_dict); | 154 local_state_->Set(kPrefPromoObject, promo_dict); |
147 DVLOG(1) << "WritePrefs " << promo_dict; | 155 DVLOG(1) << "WritePrefs " << promo_dict; |
148 } | 156 } |
149 | 157 |
150 void NotificationPromo::InitFromPrefs(PromoType promo_type) { | 158 void NotificationPromo::InitFromPrefs(PromoType promo_type) { |
151 promo_type_ = promo_type; | 159 promo_type_ = promo_type; |
152 | 160 |
| 161 // Check if data is stored in the old prefs structure, and migrate it before |
| 162 // reading from prefs. |
| 163 MigrateOldPrefs(); |
| 164 |
153 // If |promo_id_| is not set, do nothing. | 165 // If |promo_id_| is not set, do nothing. |
154 if (promo_id_ == -1) | 166 if (promo_id_ == -1) |
155 return; | 167 return; |
156 | 168 |
157 const base::DictionaryValue* promo_dict = | 169 const base::DictionaryValue* promo_dict = |
158 local_state_->GetDictionary(kPrefPromoObject); | 170 local_state_->GetDictionary(kPrefPromoObject); |
159 if (!promo_dict) | 171 if (!promo_dict) |
160 return; | 172 return; |
161 | 173 |
162 const base::DictionaryValue* ntp_promo = NULL; | 174 const base::DictionaryValue* ntp_promo = NULL; |
163 promo_dict->GetDictionary(base::IntToString(promo_id_), &ntp_promo); | 175 promo_dict->GetDictionary(base::IntToString(promo_id_), &ntp_promo); |
164 if (!ntp_promo) | 176 if (!ntp_promo) |
165 return; | 177 return; |
166 | 178 |
167 ntp_promo->GetDouble(kPrefPromoFirstViewTime, &first_view_time_); | 179 ntp_promo->GetDouble(kPrefPromoFirstViewTime, &first_view_time_); |
168 ntp_promo->GetInteger(kPrefPromoViews, &views_); | 180 ntp_promo->GetInteger(kPrefPromoViews, &views_); |
169 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); | 181 ntp_promo->GetBoolean(kPrefPromoClosed, &closed_); |
170 } | 182 } |
171 | 183 |
| 184 void NotificationPromo::MigrateOldPrefs() { |
| 185 const base::DictionaryValue* promo_dict = |
| 186 local_state_->GetDictionary(kPrefPromoObject); |
| 187 if (!promo_dict) |
| 188 return; |
| 189 |
| 190 const base::ListValue* promo_list = NULL; |
| 191 promo_dict->GetList("mobile_ntp_whats_new_promo", &promo_list); |
| 192 if (!promo_list) |
| 193 return; |
| 194 |
| 195 const base::DictionaryValue* ntp_promo = NULL; |
| 196 promo_list->GetDictionary(0, &ntp_promo); |
| 197 if (!ntp_promo) { |
| 198 // If the list is saved but there is no promo dictionary, clear prefs to |
| 199 // delete the empty list. |
| 200 NotificationPromo::MigrateUserPrefs(local_state_); |
| 201 return; |
| 202 } |
| 203 |
| 204 int promo_id = -1; |
| 205 ntp_promo->GetInteger(kPrefPromoID, &promo_id); |
| 206 if (promo_id == -1) { |
| 207 // If there is no promo id saved in prefs, then data is corrupt and the |
| 208 // prefs can be discarded. |
| 209 NotificationPromo::MigrateUserPrefs(local_state_); |
| 210 return; |
| 211 } |
| 212 |
| 213 double first_view_time = 0; |
| 214 ntp_promo->GetDouble(kPrefPromoFirstViewTime, &first_view_time); |
| 215 int views = 0; |
| 216 ntp_promo->GetInteger(kPrefPromoViews, &views); |
| 217 bool closed = false; |
| 218 ntp_promo->GetBoolean(kPrefPromoClosed, &closed); |
| 219 |
| 220 // Clear prefs to discard the old structure before saving the data in the new |
| 221 // structure. |
| 222 NotificationPromo::MigrateUserPrefs(local_state_); |
| 223 WritePrefs(promo_id, first_view_time, views, closed); |
| 224 } |
| 225 |
172 bool NotificationPromo::CanShow() const { | 226 bool NotificationPromo::CanShow() const { |
173 return !closed_ && !promo_text_.empty() && !ExceedsMaxViews() && | 227 return !closed_ && !promo_text_.empty() && !ExceedsMaxViews() && |
174 !ExceedsMaxSeconds() && | 228 !ExceedsMaxSeconds() && |
175 base::Time::FromDoubleT(StartTime()) < base::Time::Now() && | 229 base::Time::FromDoubleT(StartTime()) < base::Time::Now() && |
176 base::Time::FromDoubleT(EndTime()) > base::Time::Now(); | 230 base::Time::FromDoubleT(EndTime()) > base::Time::Now(); |
177 } | 231 } |
178 | 232 |
179 void NotificationPromo::HandleClosed() { | 233 void NotificationPromo::HandleClosed() { |
180 if (!closed_) { | 234 if (!closed_) { |
181 closed_ = true; | 235 closed_ = true; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 281 |
228 double NotificationPromo::StartTime() const { | 282 double NotificationPromo::StartTime() const { |
229 return start_; | 283 return start_; |
230 } | 284 } |
231 | 285 |
232 double NotificationPromo::EndTime() const { | 286 double NotificationPromo::EndTime() const { |
233 return end_; | 287 return end_; |
234 } | 288 } |
235 | 289 |
236 } // namespace ios | 290 } // namespace ios |
OLD | NEW |