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

Side by Side Diff: android_webview/native/state_serializer.cc

Issue 1687853002: Make AW state_serializer handle restoring also legacy format (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix signed/unsigned int compile issue Created 4 years, 10 months 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
OLDNEW
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 "android_webview/native/state_serializer.h" 5 #include "android_webview/native/state_serializer.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/pickle.h" 9 #include "base/pickle.h"
10 #include "base/time/time.h" 10 #include "base/time/time.h"
(...skipping 13 matching lines...) Expand all
24 // * TabNavigation is tightly integrated with the rest of chrome session 24 // * TabNavigation is tightly integrated with the rest of chrome session
25 // restore and sync code, and has other purpose in addition to serializing 25 // restore and sync code, and has other purpose in addition to serializing
26 // NavigationEntry. 26 // NavigationEntry.
27 27
28 using std::string; 28 using std::string;
29 29
30 namespace android_webview { 30 namespace android_webview {
31 31
32 namespace { 32 namespace {
33 33
34 // Sanity check value that we are restoring from a valid pickle. 34 const uint32_t AW_STATE_VERSION_INITIAL = 20130814;
35 // This can potentially used as an actual serialization version number in the 35 const uint32_t AW_STATE_VERSION_DATA_URL = 20151204;
36 // future if we ever decide to support restoring from older versions. 36
37 const uint32_t AW_STATE_VERSION = 20151204; 37 const uint32_t AW_STATE_VERSION = AW_STATE_VERSION_DATA_URL;
38
39 const uint32_t SUPPORTED_VERSIONS[] = {
mnaganov (inactive) 2016/02/10 16:37:45 Do we really need an array? Since there just 2 pos
sbergner 2016/02/11 07:23:28 Sure, makes sense.
40 AW_STATE_VERSION_INITIAL,
41 AW_STATE_VERSION_DATA_URL
42 };
43 const uint32_t NUM_SUPPORTED_VERSIONS =
mnaganov (inactive) 2016/02/10 16:37:45 nit: there is `arraysize` in base/macros.h
44 sizeof(SUPPORTED_VERSIONS) / sizeof(SUPPORTED_VERSIONS[0]);
38 45
39 } // namespace 46 } // namespace
40 47
41 bool WriteToPickle(const content::WebContents& web_contents, 48 bool WriteToPickle(const content::WebContents& web_contents,
42 base::Pickle* pickle) { 49 base::Pickle* pickle) {
43 DCHECK(pickle); 50 DCHECK(pickle);
44 51
45 if (!internal::WriteHeaderToPickle(pickle)) 52 if (!internal::WriteHeaderToPickle(pickle))
46 return false; 53 return false;
47 54
(...skipping 10 matching lines...) Expand all
58 65
59 if (!pickle->WriteInt(selected_entry)) 66 if (!pickle->WriteInt(selected_entry))
60 return false; 67 return false;
61 68
62 for (int i = 0; i < entry_count; ++i) { 69 for (int i = 0; i < entry_count; ++i) {
63 if (!internal::WriteNavigationEntryToPickle(*controller.GetEntryAtIndex(i), 70 if (!internal::WriteNavigationEntryToPickle(*controller.GetEntryAtIndex(i),
64 pickle)) 71 pickle))
65 return false; 72 return false;
66 } 73 }
67 74
68 // Please update AW_STATE_VERSION if serialization format is changed. 75 // Please update AW_STATE_VERSION and SUPPORTED_VERSIONS if serialization
76 // format is changed.
77 // Make sure the serialization format is updated in a backwards compatible
78 // way.
69 79
70 return true; 80 return true;
71 } 81 }
72 82
73 bool RestoreFromPickle(base::PickleIterator* iterator, 83 bool RestoreFromPickle(base::PickleIterator* iterator,
74 content::WebContents* web_contents) { 84 content::WebContents* web_contents) {
75 DCHECK(iterator); 85 DCHECK(iterator);
76 DCHECK(web_contents); 86 DCHECK(web_contents);
77 87
78 if (!internal::RestoreHeaderFromPickle(iterator)) 88 uint32_t state_version = internal::RestoreHeaderFromPickle(iterator);
89 if (!state_version)
79 return false; 90 return false;
80 91
81 int entry_count = -1; 92 int entry_count = -1;
82 int selected_entry = -2; // -1 is a valid value 93 int selected_entry = -2; // -1 is a valid value
83 94
84 if (!iterator->ReadInt(&entry_count)) 95 if (!iterator->ReadInt(&entry_count))
85 return false; 96 return false;
86 97
87 if (!iterator->ReadInt(&selected_entry)) 98 if (!iterator->ReadInt(&selected_entry))
88 return false; 99 return false;
89 100
90 if (entry_count < 0) 101 if (entry_count < 0)
91 return false; 102 return false;
92 if (selected_entry < -1) 103 if (selected_entry < -1)
93 return false; 104 return false;
94 if (selected_entry >= entry_count) 105 if (selected_entry >= entry_count)
95 return false; 106 return false;
96 107
97 std::vector<scoped_ptr<content::NavigationEntry>> entries; 108 std::vector<scoped_ptr<content::NavigationEntry>> entries;
98 entries.reserve(entry_count); 109 entries.reserve(entry_count);
99 for (int i = 0; i < entry_count; ++i) { 110 for (int i = 0; i < entry_count; ++i) {
100 entries.push_back(content::NavigationEntry::Create()); 111 entries.push_back(content::NavigationEntry::Create());
101 if (!internal::RestoreNavigationEntryFromPickle(iterator, entries[i].get())) 112 if (!internal::RestoreNavigationEntryFromPickle(state_version, iterator,
113 entries[i].get()))
102 return false; 114 return false;
103 115
104 entries[i]->SetPageID(i); 116 entries[i]->SetPageID(i);
105 } 117 }
106 118
107 // |web_contents| takes ownership of these entries after this call. 119 // |web_contents| takes ownership of these entries after this call.
108 content::NavigationController& controller = web_contents->GetController(); 120 content::NavigationController& controller = web_contents->GetController();
109 controller.Restore( 121 controller.Restore(
110 selected_entry, 122 selected_entry,
111 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, 123 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
(...skipping 20 matching lines...) Expand all
132 144
133 return true; 145 return true;
134 } 146 }
135 147
136 namespace internal { 148 namespace internal {
137 149
138 bool WriteHeaderToPickle(base::Pickle* pickle) { 150 bool WriteHeaderToPickle(base::Pickle* pickle) {
139 return pickle->WriteUInt32(AW_STATE_VERSION); 151 return pickle->WriteUInt32(AW_STATE_VERSION);
140 } 152 }
141 153
142 bool RestoreHeaderFromPickle(base::PickleIterator* iterator) { 154 uint32_t RestoreHeaderFromPickle(base::PickleIterator* iterator) {
143 uint32_t state_version = -1; 155 uint32_t state_version = -1;
144 if (!iterator->ReadUInt32(&state_version)) 156 if (!iterator->ReadUInt32(&state_version))
145 return false; 157 return 0;
146 158
147 if (AW_STATE_VERSION != state_version) 159 if (IsSupportedVersion(state_version)) {
148 return false; 160 return state_version;
161 }
149 162
150 return true; 163 return 0;
164 }
165
166 bool IsSupportedVersion(uint32_t state_version) {
167 for (uint32_t version_index = 0; version_index < NUM_SUPPORTED_VERSIONS;
168 version_index++) {
169 if (state_version == SUPPORTED_VERSIONS[version_index])
170 return true;
171 }
172 return false;
151 } 173 }
152 174
153 bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry, 175 bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
154 base::Pickle* pickle) { 176 base::Pickle* pickle) {
177 return WriteNavigationEntryToPickle(AW_STATE_VERSION, entry, pickle);
178 }
179
180 bool WriteNavigationEntryToPickle(uint32_t state_version,
181 const content::NavigationEntry& entry,
182 base::Pickle* pickle) {
183 DCHECK(IsSupportedVersion(state_version));
155 if (!pickle->WriteString(entry.GetURL().spec())) 184 if (!pickle->WriteString(entry.GetURL().spec()))
156 return false; 185 return false;
157 186
158 if (!pickle->WriteString(entry.GetVirtualURL().spec())) 187 if (!pickle->WriteString(entry.GetVirtualURL().spec()))
159 return false; 188 return false;
160 189
161 const content::Referrer& referrer = entry.GetReferrer(); 190 const content::Referrer& referrer = entry.GetReferrer();
162 if (!pickle->WriteString(referrer.url.spec())) 191 if (!pickle->WriteString(referrer.url.spec()))
163 return false; 192 return false;
164 if (!pickle->WriteInt(static_cast<int>(referrer.policy))) 193 if (!pickle->WriteInt(static_cast<int>(referrer.policy)))
165 return false; 194 return false;
166 195
167 if (!pickle->WriteString16(entry.GetTitle())) 196 if (!pickle->WriteString16(entry.GetTitle()))
168 return false; 197 return false;
169 198
170 if (!pickle->WriteString(entry.GetPageState().ToEncodedData())) 199 if (!pickle->WriteString(entry.GetPageState().ToEncodedData()))
171 return false; 200 return false;
172 201
173 if (!pickle->WriteBool(static_cast<int>(entry.GetHasPostData()))) 202 if (!pickle->WriteBool(static_cast<int>(entry.GetHasPostData())))
174 return false; 203 return false;
175 204
176 if (!pickle->WriteString(entry.GetOriginalRequestURL().spec())) 205 if (!pickle->WriteString(entry.GetOriginalRequestURL().spec()))
177 return false; 206 return false;
178 207
179 if (!pickle->WriteString(entry.GetBaseURLForDataURL().spec())) 208 if (!pickle->WriteString(entry.GetBaseURLForDataURL().spec()))
180 return false; 209 return false;
181 210
182 { 211 if (state_version >= AW_STATE_VERSION_DATA_URL) {
183 const char* data = nullptr; 212 const char* data = nullptr;
184 size_t size = 0; 213 size_t size = 0;
185 scoped_refptr<const base::RefCountedString> s = entry.GetDataURLAsString(); 214 scoped_refptr<const base::RefCountedString> s = entry.GetDataURLAsString();
186 if (s) { 215 if (s) {
187 data = s->front_as<char>(); 216 data = s->front_as<char>();
188 size = s->size(); 217 size = s->size();
189 } 218 }
190 // Even when |entry.GetDataForDataURL()| is null we still need to write a 219 // Even when |entry.GetDataForDataURL()| is null we still need to write a
191 // zero-length entry to ensure the fields all line up when read back in. 220 // zero-length entry to ensure the fields all line up when read back in.
192 if (!pickle->WriteData(data, size)) 221 if (!pickle->WriteData(data, size))
193 return false; 222 return false;
194 } 223 }
195 224
196 if (!pickle->WriteBool(static_cast<int>(entry.GetIsOverridingUserAgent()))) 225 if (!pickle->WriteBool(static_cast<int>(entry.GetIsOverridingUserAgent())))
197 return false; 226 return false;
198 227
199 if (!pickle->WriteInt64(entry.GetTimestamp().ToInternalValue())) 228 if (!pickle->WriteInt64(entry.GetTimestamp().ToInternalValue()))
200 return false; 229 return false;
201 230
202 if (!pickle->WriteInt(entry.GetHttpStatusCode())) 231 if (!pickle->WriteInt(entry.GetHttpStatusCode()))
203 return false; 232 return false;
204 233
205 // Please update AW_STATE_VERSION if serialization format is changed. 234 // Please update AW_STATE_VERSION if serialization format is changed.
206 235
207 return true; 236 return true;
208 } 237 }
209 238
210 bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator, 239 bool RestoreNavigationEntryFromPickle(base::PickleIterator* iterator,
211 content::NavigationEntry* entry) { 240 content::NavigationEntry* entry) {
241 return RestoreNavigationEntryFromPickle(AW_STATE_VERSION, iterator, entry);
242 }
243
244 bool RestoreNavigationEntryFromPickle(uint32_t state_version,
245 base::PickleIterator* iterator,
246 content::NavigationEntry* entry) {
247 DCHECK(IsSupportedVersion(state_version));
212 { 248 {
213 string url; 249 string url;
214 if (!iterator->ReadString(&url)) 250 if (!iterator->ReadString(&url))
215 return false; 251 return false;
216 entry->SetURL(GURL(url)); 252 entry->SetURL(GURL(url));
217 } 253 }
218 254
219 { 255 {
220 string virtual_url; 256 string virtual_url;
221 if (!iterator->ReadString(&virtual_url)) 257 if (!iterator->ReadString(&virtual_url))
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 entry->SetOriginalRequestURL(GURL(original_request_url)); 303 entry->SetOriginalRequestURL(GURL(original_request_url));
268 } 304 }
269 305
270 { 306 {
271 string base_url_for_data_url; 307 string base_url_for_data_url;
272 if (!iterator->ReadString(&base_url_for_data_url)) 308 if (!iterator->ReadString(&base_url_for_data_url))
273 return false; 309 return false;
274 entry->SetBaseURLForDataURL(GURL(base_url_for_data_url)); 310 entry->SetBaseURLForDataURL(GURL(base_url_for_data_url));
275 } 311 }
276 312
277 { 313 if (state_version >= AW_STATE_VERSION_DATA_URL) {
278 const char* data; 314 const char* data;
279 int size; 315 int size;
280 if (!iterator->ReadData(&data, &size)) 316 if (!iterator->ReadData(&data, &size))
281 return false; 317 return false;
282 if (size > 0) { 318 if (size > 0) {
283 scoped_refptr<base::RefCountedString> ref = new base::RefCountedString(); 319 scoped_refptr<base::RefCountedString> ref = new base::RefCountedString();
284 ref->data().assign(data, size); 320 ref->data().assign(data, size);
285 entry->SetDataURLAsString(ref); 321 entry->SetDataURLAsString(ref);
286 } 322 }
287 } 323 }
(...skipping 18 matching lines...) Expand all
306 return false; 342 return false;
307 entry->SetHttpStatusCode(http_status_code); 343 entry->SetHttpStatusCode(http_status_code);
308 } 344 }
309 345
310 return true; 346 return true;
311 } 347 }
312 348
313 } // namespace internal 349 } // namespace internal
314 350
315 } // namespace android_webview 351 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698