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

Side by Side Diff: chrome/browser/sessions/base_session_service.cc

Issue 672083002: Refactoring of SessionService to get componentized. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: One more self nit Created 6 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
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 "chrome/browser/sessions/base_session_service.h" 5 #include "chrome/browser/sessions/base_session_service.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/pickle.h"
9 #include "base/threading/thread.h" 8 #include "base/threading/thread.h"
10 #include "chrome/browser/sessions/base_session_service_delegate.h" 9 #include "chrome/browser/sessions/base_session_service_delegate.h"
11 #include "chrome/browser/sessions/session_backend.h" 10 #include "chrome/browser/sessions/session_backend.h"
12 #include "chrome/browser/sessions/session_types.h"
13 11
14 // BaseSessionService --------------------------------------------------------- 12 // BaseSessionService ---------------------------------------------------------
15 13
16 namespace { 14 namespace {
17 15
18 // Helper used by CreateUpdateTabNavigationCommand(). It writes |str| to
19 // |pickle|, if and only if |str| fits within (|max_bytes| - |*bytes_written|).
20 // |bytes_written| is incremented to reflect the data written.
21 void WriteStringToPickle(Pickle& pickle, int* bytes_written, int max_bytes,
22 const std::string& str) {
23 int num_bytes = str.size() * sizeof(char);
24 if (*bytes_written + num_bytes < max_bytes) {
25 *bytes_written += num_bytes;
26 pickle.WriteString(str);
27 } else {
28 pickle.WriteString(std::string());
29 }
30 }
31
32 // Helper used by ScheduleGetLastSessionCommands. It runs callback on TaskRunner 16 // Helper used by ScheduleGetLastSessionCommands. It runs callback on TaskRunner
33 // thread if it's not canceled. 17 // thread if it's not canceled.
34 void RunIfNotCanceled( 18 void RunIfNotCanceled(
35 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, 19 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled,
36 const BaseSessionService::InternalGetCommandsCallback& callback, 20 const BaseSessionService::GetCommandsCallback& callback,
37 ScopedVector<SessionCommand> commands) { 21 ScopedVector<SessionCommand> commands) {
38 if (is_canceled.Run()) 22 if (is_canceled.Run())
39 return; 23 return;
40 callback.Run(commands.Pass()); 24 callback.Run(commands.Pass());
41 } 25 }
42 26
43 void PostOrRunInternalGetCommandsCallback( 27 void PostOrRunInternalGetCommandsCallback(
44 base::TaskRunner* task_runner, 28 base::TaskRunner* task_runner,
45 const BaseSessionService::InternalGetCommandsCallback& callback, 29 const BaseSessionService::GetCommandsCallback& callback,
46 ScopedVector<SessionCommand> commands) { 30 ScopedVector<SessionCommand> commands) {
47 if (task_runner->RunsTasksOnCurrentThread()) { 31 if (task_runner->RunsTasksOnCurrentThread()) {
48 callback.Run(commands.Pass()); 32 callback.Run(commands.Pass());
49 } else { 33 } else {
50 task_runner->PostTask(FROM_HERE, 34 task_runner->PostTask(FROM_HERE,
51 base::Bind(callback, base::Passed(&commands))); 35 base::Bind(callback, base::Passed(&commands)));
52 } 36 }
53 } 37 }
54 38
55 } // namespace 39 } // namespace
56 40
57 // Delay between when a command is received, and when we save it to the 41 // Delay between when a command is received, and when we save it to the
58 // backend. 42 // backend.
59 static const int kSaveDelayMS = 2500; 43 static const int kSaveDelayMS = 2500;
60 44
61 // static 45 // static
62 const int BaseSessionService::max_persist_navigation_count = 6; 46 const int BaseSessionService::max_persist_navigation_count = 6;
63 47
64 BaseSessionService::BaseSessionService( 48 BaseSessionService::BaseSessionService(
65 SessionType type, 49 SessionType type,
66 const base::FilePath& path, 50 const base::FilePath& path,
67 scoped_ptr<BaseSessionServiceDelegate> delegate) 51 BaseSessionServiceDelegate* delegate)
68 : pending_reset_(false), 52 : pending_reset_(false),
69 commands_since_reset_(0), 53 commands_since_reset_(0),
70 delegate_(delegate.Pass()), 54 delegate_(delegate),
71 sequence_token_(delegate_->GetBlockingPool()->GetSequenceToken()), 55 sequence_token_(delegate_->GetBlockingPool()->GetSequenceToken()),
72 weak_factory_(this) { 56 weak_factory_(this) {
73 backend_ = new SessionBackend(type, path); 57 backend_ = new SessionBackend(type, path);
74 DCHECK(backend_.get()); 58 DCHECK(backend_.get());
75 } 59 }
76 60
77 BaseSessionService::~BaseSessionService() { 61 BaseSessionService::~BaseSessionService() {}
78 }
79 62
80 void BaseSessionService::DeleteLastSession() { 63 void BaseSessionService::ScheduleCommand(scoped_ptr<SessionCommand> command) {
81 RunTaskOnBackendThread(
82 FROM_HERE,
83 base::Bind(&SessionBackend::DeleteLastSession, backend()));
84 }
85
86 void BaseSessionService::ScheduleCommand(SessionCommand* command) {
87 DCHECK(command); 64 DCHECK(command);
88 commands_since_reset_++; 65 commands_since_reset_++;
89 pending_commands_.push_back(command); 66 pending_commands_.push_back(command.release());
90 StartSaveTimer(); 67 StartSaveTimer();
91 } 68 }
92 69
93 void BaseSessionService::StartSaveTimer() { 70 void BaseSessionService::StartSaveTimer() {
94 // Don't start a timer when testing. 71 // Don't start a timer when testing.
95 if (delegate_->ShouldUseDelayedSave() && base::MessageLoop::current() && 72 if (delegate_->ShouldUseDelayedSave() && base::MessageLoop::current() &&
96 !weak_factory_.HasWeakPtrs()) { 73 !weak_factory_.HasWeakPtrs()) {
97 base::MessageLoop::current()->PostDelayedTask( 74 base::MessageLoop::current()->PostDelayedTask(
98 FROM_HERE, 75 FROM_HERE,
99 base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), 76 base::Bind(&BaseSessionService::SaveInternal,
77 weak_factory_.GetWeakPtr()),
100 base::TimeDelta::FromMilliseconds(kSaveDelayMS)); 78 base::TimeDelta::FromMilliseconds(kSaveDelayMS));
101 } 79 }
102 } 80 }
103 81
104 void BaseSessionService::Save() { 82 void BaseSessionService::DeleteLastSession() {
105 DCHECK(backend());
106
107 if (pending_commands_.empty())
108 return;
109
110 RunTaskOnBackendThread( 83 RunTaskOnBackendThread(
111 FROM_HERE, 84 FROM_HERE,
112 base::Bind(&SessionBackend::AppendCommands, backend(), 85 base::Bind(&SessionBackend::DeleteLastSession, backend()));
113 new std::vector<SessionCommand*>(pending_commands_),
114 pending_reset_));
115
116 // Backend took ownership of commands.
117 pending_commands_.clear();
118
119 if (pending_reset_) {
120 commands_since_reset_ = 0;
121 pending_reset_ = false;
122 }
123 } 86 }
124 87
125 SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( 88 void BaseSessionService::MoveCurrentSessionToLastSession() {
126 SessionID::id_type command_id, 89 SaveNow();
127 SessionID::id_type tab_id, 90 RunTaskOnBackendThread(
128 const sessions::SerializedNavigationEntry& navigation) { 91 FROM_HERE, base::Bind(&SessionBackend::MoveCurrentSessionToLastSession,
129 // Use pickle to handle marshalling. 92 backend()));
130 Pickle pickle;
131 pickle.WriteInt(tab_id);
132 // We only allow navigations up to 63k (which should be completely
133 // reasonable).
134 static const size_t max_state_size =
135 std::numeric_limits<SessionCommand::size_type>::max() - 1024;
136 navigation.WriteToPickle(max_state_size, &pickle);
137 return new SessionCommand(command_id, pickle);
138 } 93 }
139 94
140 SessionCommand* BaseSessionService::CreateSetTabExtensionAppIDCommand( 95 void BaseSessionService::SaveNow() {
141 SessionID::id_type command_id, 96 if (backend())
142 SessionID::id_type tab_id, 97 SaveInternal();
143 const std::string& extension_id) {
144 // Use pickle to handle marshalling.
145 Pickle pickle;
146 pickle.WriteInt(tab_id);
147
148 // Enforce a max for ids. They should never be anywhere near this size.
149 static const SessionCommand::size_type max_id_size =
150 std::numeric_limits<SessionCommand::size_type>::max() - 1024;
151
152 int bytes_written = 0;
153
154 WriteStringToPickle(pickle, &bytes_written, max_id_size, extension_id);
155
156 return new SessionCommand(command_id, pickle);
157 }
158
159 SessionCommand* BaseSessionService::CreateSetTabUserAgentOverrideCommand(
160 SessionID::id_type command_id,
161 SessionID::id_type tab_id,
162 const std::string& user_agent_override) {
163 // Use pickle to handle marshalling.
164 Pickle pickle;
165 pickle.WriteInt(tab_id);
166
167 // Enforce a max for the user agent length. They should never be anywhere
168 // near this size.
169 static const SessionCommand::size_type max_user_agent_size =
170 std::numeric_limits<SessionCommand::size_type>::max() - 1024;
171
172 int bytes_written = 0;
173
174 WriteStringToPickle(pickle, &bytes_written, max_user_agent_size,
175 user_agent_override);
176
177 return new SessionCommand(command_id, pickle);
178 }
179
180 SessionCommand* BaseSessionService::CreateSetWindowAppNameCommand(
181 SessionID::id_type command_id,
182 SessionID::id_type window_id,
183 const std::string& app_name) {
184 // Use pickle to handle marshalling.
185 Pickle pickle;
186 pickle.WriteInt(window_id);
187
188 // Enforce a max for ids. They should never be anywhere near this size.
189 static const SessionCommand::size_type max_id_size =
190 std::numeric_limits<SessionCommand::size_type>::max() - 1024;
191
192 int bytes_written = 0;
193
194 WriteStringToPickle(pickle, &bytes_written, max_id_size, app_name);
195
196 return new SessionCommand(command_id, pickle);
197 }
198
199 bool BaseSessionService::RestoreUpdateTabNavigationCommand(
200 const SessionCommand& command,
201 sessions::SerializedNavigationEntry* navigation,
202 SessionID::id_type* tab_id) {
203 scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
204 if (!pickle.get())
205 return false;
206 PickleIterator iterator(*pickle);
207 return
208 pickle->ReadInt(&iterator, tab_id) &&
209 navigation->ReadFromPickle(&iterator);
210 }
211
212 bool BaseSessionService::RestoreSetTabExtensionAppIDCommand(
213 const SessionCommand& command,
214 SessionID::id_type* tab_id,
215 std::string* extension_app_id) {
216 scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
217 if (!pickle.get())
218 return false;
219
220 PickleIterator iterator(*pickle);
221 return pickle->ReadInt(&iterator, tab_id) &&
222 pickle->ReadString(&iterator, extension_app_id);
223 }
224
225 bool BaseSessionService::RestoreSetTabUserAgentOverrideCommand(
226 const SessionCommand& command,
227 SessionID::id_type* tab_id,
228 std::string* user_agent_override) {
229 scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
230 if (!pickle.get())
231 return false;
232
233 PickleIterator iterator(*pickle);
234 return pickle->ReadInt(&iterator, tab_id) &&
235 pickle->ReadString(&iterator, user_agent_override);
236 }
237
238 bool BaseSessionService::RestoreSetWindowAppNameCommand(
239 const SessionCommand& command,
240 SessionID::id_type* window_id,
241 std::string* app_name) {
242 scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
243 if (!pickle.get())
244 return false;
245
246 PickleIterator iterator(*pickle);
247 return pickle->ReadInt(&iterator, window_id) &&
248 pickle->ReadString(&iterator, app_name);
249 }
250
251 bool BaseSessionService::ShouldTrackEntry(const GURL& url) {
252 return url.is_valid() && delegate_->ShouldTrackEntry(url);
253 } 98 }
254 99
255 base::CancelableTaskTracker::TaskId 100 base::CancelableTaskTracker::TaskId
256 BaseSessionService::ScheduleGetLastSessionCommands( 101 BaseSessionService::ScheduleGetLastSessionCommands(
257 const InternalGetCommandsCallback& callback, 102 const GetCommandsCallback& callback,
258 base::CancelableTaskTracker* tracker) { 103 base::CancelableTaskTracker* tracker) {
259 base::CancelableTaskTracker::IsCanceledCallback is_canceled; 104 base::CancelableTaskTracker::IsCanceledCallback is_canceled;
260 base::CancelableTaskTracker::TaskId id = 105 base::CancelableTaskTracker::TaskId id =
261 tracker->NewTrackedTaskId(&is_canceled); 106 tracker->NewTrackedTaskId(&is_canceled);
262 107
263 InternalGetCommandsCallback run_if_not_canceled = 108 GetCommandsCallback run_if_not_canceled =
264 base::Bind(&RunIfNotCanceled, is_canceled, callback); 109 base::Bind(&RunIfNotCanceled, is_canceled, callback);
265 110
266 InternalGetCommandsCallback callback_runner = 111 GetCommandsCallback callback_runner =
267 base::Bind(&PostOrRunInternalGetCommandsCallback, 112 base::Bind(&PostOrRunInternalGetCommandsCallback,
268 base::MessageLoopProxy::current(), run_if_not_canceled); 113 base::MessageLoopProxy::current(), run_if_not_canceled);
269 114
270 RunTaskOnBackendThread( 115 RunTaskOnBackendThread(
271 FROM_HERE, 116 FROM_HERE,
272 base::Bind(&SessionBackend::ReadLastSessionCommands, backend(), 117 base::Bind(&SessionBackend::ReadLastSessionCommands, backend(),
273 is_canceled, callback_runner)); 118 is_canceled, callback_runner));
274 return id; 119 return id;
275 } 120 }
276 121
122 bool BaseSessionService::ProcessedAnyCommandsForTest() {
123 return backend()->inited() || !pending_commands().empty();
124 }
125
126 void BaseSessionService::SaveInternal() {
127 DCHECK(backend());
128
129 // Inform the delegate that we will save the commands now, giving it the
130 // opportunity to append more commands.
131 delegate_->OnWillSaveCommands();
132
133 if (pending_commands_.empty())
134 return;
135
136 // We create a new ScopedVector which will receive all elements from the
137 // current commands. This will also clear the current list.
138 ScopedVector<SessionCommand>* passed = new ScopedVector<SessionCommand>();
139 passed->swap(pending_commands_);
140 DCHECK(pending_commands_.empty());
141 RunTaskOnBackendThread(
142 FROM_HERE,
143 base::Bind(&SessionBackend::AppendCommands, backend(),
144 passed,
145 pending_reset_));
146
147 if (pending_reset_) {
148 commands_since_reset_ = 0;
149 pending_reset_ = false;
150 }
151
152 delegate_->OnSavedCommands();
153 }
154
277 void BaseSessionService::RunTaskOnBackendThread( 155 void BaseSessionService::RunTaskOnBackendThread(
278 const tracked_objects::Location& from_here, 156 const tracked_objects::Location& from_here,
279 const base::Closure& task) { 157 const base::Closure& task) {
280 base::SequencedWorkerPool* pool = delegate_->GetBlockingPool(); 158 base::SequencedWorkerPool* pool = delegate_->GetBlockingPool();
281 if (!pool->IsShutdownInProgress()) { 159 if (!pool->IsShutdownInProgress()) {
282 pool->PostSequencedWorkerTask(sequence_token_, from_here, task); 160 pool->PostSequencedWorkerTask(sequence_token_, from_here, task);
283 } else { 161 } else {
284 // Fall back to executing on the main thread if the sequence 162 // Fall back to executing on the main thread if the sequence
285 // worker pool has been requested to shutdown (around shutdown 163 // worker pool has been requested to shutdown (around shutdown
286 // time). 164 // time).
287 task.Run(); 165 task.Run();
288 } 166 }
289 } 167 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698