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

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

Issue 11420056: Android WebView save/restoreState and backForardList Part 1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove outdated comment Created 8 years, 1 month 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "android_webview/native/state_serializer.h"
6
7 #include <string>
8
9 #include "base/memory/scoped_vector.h"
10 #include "base/pickle.h"
11 #include "base/time.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/web_contents.h"
15
16 // Reasons for not re-using TabNavigation under chrome/ as of 20121116:
17 // * Android WebView has different requirements for fields to store since
18 // we are the only ones using values like BaseURLForDataURL.
19 // * TabNavigation does unnecessary copying of data, which in Android
20 // WebView case, is undesired since save/restore is called in Android
21 // very frequently.
22 // * TabNavigation is tightly integrated with the rest of chrome session
23 // restore and sync code, and has other purpose in addition to serializing
24 // NavigationEntry.
25
26 using std::string;
27
28 namespace android_webview {
29
30 namespace {
31
32 // Sanity check value that we are restoring from a valid pickle.
33 // This can potentially used as an actual serialization version number in the
34 // future if we ever decide to support restoring from older versions.
35 const uint32 AW_STATE_VERSION = 20121116;
36
37 } // namespace
38
39 bool WriteToPickle(const content::WebContents& web_contents,
40 Pickle* pickle) {
41 DCHECK(pickle);
42
43 if (!internal::WriteHeaderToPickle(pickle))
44 return false;
45
46 const content::NavigationController& controller =
47 web_contents.GetController();
48 const int entry_count = controller.GetEntryCount();
49 const int selected_entry = controller.GetCurrentEntryIndex();
50 DCHECK(entry_count >= 0);
51 DCHECK(selected_entry >= -1); // -1 is valid
52 DCHECK(selected_entry < entry_count);
53
54 if (!pickle->WriteInt(entry_count))
55 return false;
56
57 if (!pickle->WriteInt(selected_entry))
58 return false;
59
60 for (int i = 0; i < entry_count; ++i) {
61 if (!internal::WriteNavigationEntryToPickle(*controller.GetEntryAtIndex(i),
62 pickle))
63 return false;
64 }
65
66 // Please update AW_STATE_VERSION if serialization format is changed.
67
68 return true;
69 }
70
71 bool RestoreFromPickle(PickleIterator* iterator,
72 content::WebContents* web_contents) {
73 DCHECK(iterator);
74 DCHECK(web_contents);
75
76 if (!internal::RestoreHeaderFromPickle(iterator))
77 return false;
78
79 int entry_count = -1;
80 int selected_entry = -2; // -1 is a valid value
81
82 if (!iterator->ReadInt(&entry_count))
83 return false;
84
85 if (!iterator->ReadInt(&selected_entry))
86 return false;
87
88 if (entry_count < 0)
89 return false;
90 if (selected_entry < -1)
91 return false;
92 if (selected_entry >= entry_count)
93 return false;
94
95 ScopedVector<content::NavigationEntry> restored_entries;
96 for (int i = 0; i < entry_count; ++i) {
97 restored_entries.push_back(content::NavigationEntry::Create());
98 if (!internal::RestoreNavigationEntryFromPickle(iterator,
99 restored_entries[i]))
100 return false;
101 }
102
103 // |web_contents| takes ownership of these entries after this call.
104 web_contents->GetController().Restore(
105 selected_entry,
106 content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY,
107 &restored_entries.get());
108 DCHECK_EQ(0u, restored_entries.size());
109
110 return true;
111 }
112
113 namespace internal {
114
115 bool WriteHeaderToPickle(Pickle* pickle) {
116 return pickle->WriteUInt32(AW_STATE_VERSION);
117 }
118
119 bool RestoreHeaderFromPickle(PickleIterator* iterator) {
120 uint32 state_version = -1;
121 if (!iterator->ReadUInt32(&state_version))
122 return false;
123
124 if (AW_STATE_VERSION != state_version)
125 return false;
126
127 return true;
128 }
129
130 bool WriteNavigationEntryToPickle(const content::NavigationEntry& entry,
131 Pickle* pickle) {
132 if (!pickle->WriteString(entry.GetURL().spec()))
133 return false;
134
135 if (!pickle->WriteString(entry.GetVirtualURL().spec()))
136 return false;
137
138 const content::Referrer& referrer = entry.GetReferrer();
139 if (!pickle->WriteString(referrer.url.spec()))
140 return false;
141 if (!pickle->WriteInt(static_cast<int>(referrer.policy)))
142 return false;
143
144 if (!pickle->WriteString16(entry.GetTitle()))
145 return false;
146
147 if (!pickle->WriteString(entry.GetContentState()))
148 return false;
149
150 if (!pickle->WriteBool(static_cast<int>(entry.GetHasPostData())))
151 return false;
152
153 if (!pickle->WriteString(entry.GetOriginalRequestURL().spec()))
154 return false;
155
156 if (!pickle->WriteBool(static_cast<int>(entry.GetIsOverridingUserAgent())))
157 return false;
158
159 if (!pickle->WriteInt64(entry.GetTimestamp().ToInternalValue()))
160 return false;
161
162 // Please update AW_STATE_VERSION if serialization format is changed.
163
164 return true;
165 }
166
167 bool RestoreNavigationEntryFromPickle(PickleIterator* iterator,
168 content::NavigationEntry* entry) {
169 {
170 string url;
171 if (!iterator->ReadString(&url))
172 return false;
173 entry->SetURL(GURL(url));
174 }
175
176 {
177 string virtual_url;
178 if (!iterator->ReadString(&virtual_url))
179 return false;
180 entry->SetVirtualURL(GURL(virtual_url));
181 }
182
183 {
184 content::Referrer referrer;
185 string referrer_url;
186 int policy;
187
188 if (!iterator->ReadString(&referrer_url))
189 return false;
190 if (!iterator->ReadInt(&policy))
191 return false;
192
193 referrer.url = GURL(referrer_url);
194 referrer.policy = static_cast<WebKit::WebReferrerPolicy>(policy);
195 entry->SetReferrer(referrer);
196 }
197
198 {
199 string16 title;
200 if (!iterator->ReadString16(&title))
201 return false;
202 entry->SetTitle(title);
203 }
204
205 {
206 string content_state;
207 if (!iterator->ReadString(&content_state))
208 return false;
209 entry->SetContentState(content_state);
210 }
211
212 {
213 bool has_post_data;
214 if (!iterator->ReadBool(&has_post_data))
215 return false;
216 entry->SetHasPostData(has_post_data);
217 }
218
219 {
220 string original_request_url;
221 if (!iterator->ReadString(&original_request_url))
222 return false;
223 entry->SetOriginalRequestURL(GURL(original_request_url));
224 }
225
226 {
227 bool is_overriding_user_agent;
228 if (!iterator->ReadBool(&is_overriding_user_agent))
229 return false;
230 entry->SetIsOverridingUserAgent(is_overriding_user_agent);
231 }
232
233 {
234 int64 timestamp;
235 if (!iterator->ReadInt64(&timestamp))
236 return false;
237 entry->SetTimestamp(base::Time::FromInternalValue(timestamp));
238 }
239
240 return true;
241 }
242
243 } // namespace internal
244
245 } // namespace android_webview
OLDNEW
« no previous file with comments | « android_webview/native/state_serializer.h ('k') | android_webview/native/state_serializer_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698