Refactoring of SessionService into a component part 3.
[chromium-blink-merge.git] / chrome / browser / sessions / base_session_service.cc
blob05d61bf7213b1a55a42df2c457d4335db8df9d81
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"
7 #include "base/bind.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 ---------------------------------------------------------
14 namespace {
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())
23 return;
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());
33 } else {
34 task_runner->PostTask(FROM_HERE,
35 base::Bind(callback, base::Passed(&commands)));
39 } // namespace
41 // Delay between when a command is received, and when we save it to the
42 // backend.
43 static const int kSaveDelayMS = 2500;
45 // static
46 const int BaseSessionService::max_persist_navigation_count = 6;
48 BaseSessionService::BaseSessionService(
49 SessionType type,
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()),
56 weak_factory_(this) {
57 backend_ = new SessionBackend(type, path);
58 DCHECK(backend_.get());
61 BaseSessionService::~BaseSessionService() {
64 void BaseSessionService::DeleteLastSession() {
65 RunTaskOnBackendThread(
66 FROM_HERE,
67 base::Bind(&SessionBackend::DeleteLastSession, backend()));
70 void BaseSessionService::ScheduleCommand(SessionCommand* command) {
71 DCHECK(command);
72 commands_since_reset_++;
73 pending_commands_.push_back(command);
74 StartSaveTimer();
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(
82 FROM_HERE,
83 base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()),
84 base::TimeDelta::FromMilliseconds(kSaveDelayMS));
88 void BaseSessionService::Save() {
89 DCHECK(backend());
91 if (pending_commands_.empty())
92 return;
94 RunTaskOnBackendThread(
95 FROM_HERE,
96 base::Bind(&SessionBackend::AppendCommands, backend(),
97 new std::vector<SessionCommand*>(pending_commands_),
98 pending_reset_));
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(
129 FROM_HERE,
130 base::Bind(&SessionBackend::ReadLastSessionCommands, backend(),
131 is_canceled, callback_runner));
132 return id;
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);
141 } else {
142 // Fall back to executing on the main thread if the sequence
143 // worker pool has been requested to shutdown (around shutdown
144 // time).
145 task.Run();