OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" | 8 #include "base/pickle.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
13 #include "chrome/browser/sessions/session_backend.h" | 13 #include "chrome/browser/sessions/session_backend.h" |
14 #include "chrome/browser/sessions/session_types.h" | 14 #include "chrome/browser/sessions/session_types.h" |
15 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
16 #include "content/browser/tab_contents/navigation_entry.h" | 16 #include "content/browser/tab_contents/navigation_entry.h" |
| 17 #include "content/public/browser/browser_thread.h" |
17 #include "content/public/common/referrer.h" | 18 #include "content/public/common/referrer.h" |
18 #include "webkit/glue/webkit_glue.h" | 19 #include "webkit/glue/webkit_glue.h" |
19 | 20 |
| 21 using content::BrowserThread; |
20 using WebKit::WebReferrerPolicy; | 22 using WebKit::WebReferrerPolicy; |
21 | 23 |
22 // InternalGetCommandsRequest ------------------------------------------------- | 24 // InternalGetCommandsRequest ------------------------------------------------- |
23 | 25 |
24 BaseSessionService::InternalGetCommandsRequest::~InternalGetCommandsRequest() { | 26 BaseSessionService::InternalGetCommandsRequest::~InternalGetCommandsRequest() { |
25 STLDeleteElements(&commands); | 27 STLDeleteElements(&commands); |
26 } | 28 } |
27 | 29 |
28 // BaseSessionService --------------------------------------------------------- | 30 // BaseSessionService --------------------------------------------------------- |
29 | 31 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 static const int kSaveDelayMS = 2500; | 64 static const int kSaveDelayMS = 2500; |
63 | 65 |
64 // static | 66 // static |
65 const int BaseSessionService::max_persist_navigation_count = 6; | 67 const int BaseSessionService::max_persist_navigation_count = 6; |
66 | 68 |
67 BaseSessionService::BaseSessionService(SessionType type, | 69 BaseSessionService::BaseSessionService(SessionType type, |
68 Profile* profile, | 70 Profile* profile, |
69 const FilePath& path) | 71 const FilePath& path) |
70 : profile_(profile), | 72 : profile_(profile), |
71 path_(path), | 73 path_(path), |
72 backend_thread_(NULL), | |
73 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 74 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
74 pending_reset_(false), | 75 pending_reset_(false), |
75 commands_since_reset_(0) { | 76 commands_since_reset_(0) { |
76 if (profile) { | 77 if (profile) { |
77 // We should never be created when incognito. | 78 // We should never be created when incognito. |
78 DCHECK(!profile->IsOffTheRecord()); | 79 DCHECK(!profile->IsOffTheRecord()); |
79 } | 80 } |
80 backend_ = new SessionBackend(type, | 81 backend_ = new SessionBackend(type, |
81 profile_ ? profile_->GetPath() : path_); | 82 profile_ ? profile_->GetPath() : path_); |
82 DCHECK(backend_.get()); | 83 DCHECK(backend_.get()); |
83 backend_thread_ = g_browser_process->file_thread(); | 84 |
84 if (!backend_thread_) | 85 RunTaskOnBackendThread(FROM_HERE, |
85 backend_->Init(); | 86 base::Bind(&SessionBackend::Init, backend_)); |
86 // If backend_thread is non-null, backend will init itself as appropriate. | |
87 } | 87 } |
88 | 88 |
89 BaseSessionService::~BaseSessionService() { | 89 BaseSessionService::~BaseSessionService() { |
90 } | 90 } |
91 | 91 |
92 void BaseSessionService::DeleteLastSession() { | 92 void BaseSessionService::DeleteLastSession() { |
93 if (!backend_thread()) { | 93 RunTaskOnBackendThread( |
94 backend()->DeleteLastSession(); | 94 FROM_HERE, |
95 } else { | 95 base::Bind(&SessionBackend::DeleteLastSession, backend())); |
96 backend_thread()->message_loop()->PostTask( | |
97 FROM_HERE, base::Bind(&SessionBackend::DeleteLastSession, backend())); | |
98 } | |
99 } | 96 } |
100 | 97 |
101 void BaseSessionService::ScheduleCommand(SessionCommand* command) { | 98 void BaseSessionService::ScheduleCommand(SessionCommand* command) { |
102 DCHECK(command); | 99 DCHECK(command); |
103 commands_since_reset_++; | 100 commands_since_reset_++; |
104 pending_commands_.push_back(command); | 101 pending_commands_.push_back(command); |
105 StartSaveTimer(); | 102 StartSaveTimer(); |
106 } | 103 } |
107 | 104 |
108 void BaseSessionService::StartSaveTimer() { | 105 void BaseSessionService::StartSaveTimer() { |
109 // Don't start a timer when testing (profile == NULL or | 106 // Don't start a timer when testing (profile == NULL or |
110 // MessageLoop::current() is NULL). | 107 // MessageLoop::current() is NULL). |
111 if (MessageLoop::current() && profile() && !weak_factory_.HasWeakPtrs()) { | 108 if (MessageLoop::current() && profile() && !weak_factory_.HasWeakPtrs()) { |
112 MessageLoop::current()->PostDelayedTask( | 109 MessageLoop::current()->PostDelayedTask( |
113 FROM_HERE, | 110 FROM_HERE, |
114 base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), | 111 base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), |
115 kSaveDelayMS); | 112 kSaveDelayMS); |
116 } | 113 } |
117 } | 114 } |
118 | 115 |
119 void BaseSessionService::Save() { | 116 void BaseSessionService::Save() { |
120 DCHECK(backend()); | 117 DCHECK(backend()); |
121 | 118 |
122 if (pending_commands_.empty()) | 119 if (pending_commands_.empty()) |
123 return; | 120 return; |
124 | 121 |
125 if (!backend_thread()) { | 122 RunTaskOnBackendThread( |
126 backend()->AppendCommands( | 123 FROM_HERE, |
127 new std::vector<SessionCommand*>(pending_commands_), pending_reset_); | 124 base::Bind(&SessionBackend::AppendCommands, backend(), |
128 } else { | 125 new std::vector<SessionCommand*>(pending_commands_), |
129 backend_thread()->message_loop()->PostTask( | 126 pending_reset_)); |
130 FROM_HERE, | 127 |
131 base::Bind(&SessionBackend::AppendCommands, backend(), | |
132 new std::vector<SessionCommand*>(pending_commands_), | |
133 pending_reset_)); | |
134 } | |
135 // Backend took ownership of commands. | 128 // Backend took ownership of commands. |
136 pending_commands_.clear(); | 129 pending_commands_.clear(); |
137 | 130 |
138 if (pending_reset_) { | 131 if (pending_reset_) { |
139 commands_since_reset_ = 0; | 132 commands_since_reset_ = 0; |
140 pending_reset_ = false; | 133 pending_reset_ = false; |
141 } | 134 } |
142 } | 135 } |
143 | 136 |
144 SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( | 137 SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 // NOTE: Do not track print preview tab because re-opening that page will | 261 // NOTE: Do not track print preview tab because re-opening that page will |
269 // just display a non-functional print preview page. | 262 // just display a non-functional print preview page. |
270 return url.is_valid() && url != GURL(chrome::kChromeUIPrintURL); | 263 return url.is_valid() && url != GURL(chrome::kChromeUIPrintURL); |
271 } | 264 } |
272 | 265 |
273 BaseSessionService::Handle BaseSessionService::ScheduleGetLastSessionCommands( | 266 BaseSessionService::Handle BaseSessionService::ScheduleGetLastSessionCommands( |
274 InternalGetCommandsRequest* request, | 267 InternalGetCommandsRequest* request, |
275 CancelableRequestConsumerBase* consumer) { | 268 CancelableRequestConsumerBase* consumer) { |
276 scoped_refptr<InternalGetCommandsRequest> request_wrapper(request); | 269 scoped_refptr<InternalGetCommandsRequest> request_wrapper(request); |
277 AddRequest(request, consumer); | 270 AddRequest(request, consumer); |
278 if (backend_thread()) { | 271 RunTaskOnBackendThread( |
279 backend_thread()->message_loop()->PostTask( | 272 FROM_HERE, |
280 FROM_HERE, | 273 base::Bind(&SessionBackend::ReadLastSessionCommands, backend(), |
281 base::Bind(&SessionBackend::ReadLastSessionCommands, backend(), | 274 request_wrapper)); |
282 request_wrapper)); | |
283 } else { | |
284 backend()->ReadLastSessionCommands(request); | |
285 } | |
286 return request->handle(); | 275 return request->handle(); |
287 } | 276 } |
288 | 277 |
289 BaseSessionService::Handle | 278 BaseSessionService::Handle |
290 BaseSessionService::ScheduleGetCurrentSessionCommands( | 279 BaseSessionService::ScheduleGetCurrentSessionCommands( |
291 InternalGetCommandsRequest* request, | 280 InternalGetCommandsRequest* request, |
292 CancelableRequestConsumerBase* consumer) { | 281 CancelableRequestConsumerBase* consumer) { |
293 scoped_refptr<InternalGetCommandsRequest> request_wrapper(request); | 282 scoped_refptr<InternalGetCommandsRequest> request_wrapper(request); |
294 AddRequest(request, consumer); | 283 AddRequest(request, consumer); |
295 if (backend_thread()) { | 284 RunTaskOnBackendThread( |
296 backend_thread()->message_loop()->PostTask( | 285 FROM_HERE, |
297 FROM_HERE, | 286 base::Bind(&SessionBackend::ReadCurrentSessionCommands, backend(), |
298 base::Bind(&SessionBackend::ReadCurrentSessionCommands, backend(), | 287 request_wrapper)); |
299 request_wrapper)); | |
300 } else { | |
301 backend()->ReadCurrentSessionCommands(request); | |
302 } | |
303 return request->handle(); | 288 return request->handle(); |
304 } | 289 } |
| 290 |
| 291 bool BaseSessionService::RunTaskOnBackendThread( |
| 292 const tracked_objects::Location& from_here, |
| 293 const base::Closure& task) { |
| 294 if (profile_ && BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) { |
| 295 return BrowserThread::PostTask(BrowserThread::FILE, from_here, task); |
| 296 } else { |
| 297 // Fall back to executing on the main thread if the file thread |
| 298 // has gone away (around shutdown time) or if we're running as |
| 299 // part of a unit test that does not set profile_. |
| 300 task.Run(); |
| 301 return true; |
| 302 } |
| 303 } |
OLD | NEW |