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.
5 #include "chrome/browser/sessions/base_session_service.h"
8 #include "base/threading/thread.h"
9 #include "chrome/browser/sessions/base_session_service_delegate.h"
10 #include "chrome/browser/sessions/session_backend.h"
12 // BaseSessionService ---------------------------------------------------------
16 // Helper used by ScheduleGetLastSessionCommands. It runs callback on TaskRunner
17 // thread if it's not canceled.
18 void RunIfNotCanceled(
19 const base::CancelableTaskTracker::IsCanceledCallback
& is_canceled
,
20 const BaseSessionService::InternalGetCommandsCallback
& callback
,
21 ScopedVector
<SessionCommand
> commands
) {
22 if (is_canceled
.Run())
24 callback
.Run(commands
.Pass());
27 void PostOrRunInternalGetCommandsCallback(
28 base::TaskRunner
* task_runner
,
29 const BaseSessionService::InternalGetCommandsCallback
& callback
,
30 ScopedVector
<SessionCommand
> commands
) {
31 if (task_runner
->RunsTasksOnCurrentThread()) {
32 callback
.Run(commands
.Pass());
34 task_runner
->PostTask(FROM_HERE
,
35 base::Bind(callback
, base::Passed(&commands
)));
41 // Delay between when a command is received, and when we save it to the
43 static const int kSaveDelayMS
= 2500;
46 const int BaseSessionService::max_persist_navigation_count
= 6;
48 BaseSessionService::BaseSessionService(
50 const base::FilePath
& path
,
51 scoped_ptr
<BaseSessionServiceDelegate
> delegate
)
52 : pending_reset_(false),
53 commands_since_reset_(0),
54 delegate_(delegate
.Pass()),
55 sequence_token_(delegate_
->GetBlockingPool()->GetSequenceToken()),
57 backend_
= new SessionBackend(type
, path
);
58 DCHECK(backend_
.get());
61 BaseSessionService::~BaseSessionService() {
64 void BaseSessionService::DeleteLastSession() {
65 RunTaskOnBackendThread(
67 base::Bind(&SessionBackend::DeleteLastSession
, backend()));
70 void BaseSessionService::ScheduleCommand(SessionCommand
* command
) {
72 commands_since_reset_
++;
73 pending_commands_
.push_back(command
);
77 void BaseSessionService::StartSaveTimer() {
78 // Don't start a timer when testing.
79 if (delegate_
->ShouldUseDelayedSave() && base::MessageLoop::current() &&
80 !weak_factory_
.HasWeakPtrs()) {
81 base::MessageLoop::current()->PostDelayedTask(
83 base::Bind(&BaseSessionService::Save
, weak_factory_
.GetWeakPtr()),
84 base::TimeDelta::FromMilliseconds(kSaveDelayMS
));
88 void BaseSessionService::Save() {
91 if (pending_commands_
.empty())
94 RunTaskOnBackendThread(
96 base::Bind(&SessionBackend::AppendCommands
, backend(),
97 new std::vector
<SessionCommand
*>(pending_commands_
),
100 // Backend took ownership of commands.
101 pending_commands_
.clear();
103 if (pending_reset_
) {
104 commands_since_reset_
= 0;
105 pending_reset_
= false;
109 bool BaseSessionService::ShouldTrackEntry(const GURL
& url
) {
110 return url
.is_valid() && delegate_
->ShouldTrackEntry(url
);
113 base::CancelableTaskTracker::TaskId
114 BaseSessionService::ScheduleGetLastSessionCommands(
115 const InternalGetCommandsCallback
& callback
,
116 base::CancelableTaskTracker
* tracker
) {
117 base::CancelableTaskTracker::IsCanceledCallback is_canceled
;
118 base::CancelableTaskTracker::TaskId id
=
119 tracker
->NewTrackedTaskId(&is_canceled
);
121 InternalGetCommandsCallback run_if_not_canceled
=
122 base::Bind(&RunIfNotCanceled
, is_canceled
, callback
);
124 InternalGetCommandsCallback callback_runner
=
125 base::Bind(&PostOrRunInternalGetCommandsCallback
,
126 base::MessageLoopProxy::current(), run_if_not_canceled
);
128 RunTaskOnBackendThread(
130 base::Bind(&SessionBackend::ReadLastSessionCommands
, backend(),
131 is_canceled
, callback_runner
));
135 void BaseSessionService::RunTaskOnBackendThread(
136 const tracked_objects::Location
& from_here
,
137 const base::Closure
& task
) {
138 base::SequencedWorkerPool
* pool
= delegate_
->GetBlockingPool();
139 if (!pool
->IsShutdownInProgress()) {
140 pool
->PostSequencedWorkerTask(sequence_token_
, from_here
, task
);
142 // Fall back to executing on the main thread if the sequence
143 // worker pool has been requested to shutdown (around shutdown