Index: chrome/browser/sessions/base_session_service.cc |
diff --git a/chrome/browser/sessions/base_session_service.cc b/chrome/browser/sessions/base_session_service.cc |
index f85fc8f78faa8fb2a5c841eef7fcd03bd4b4ad76..f23fd1e6622dec7c4c26cdf91d95385873b168bf 100644 |
--- a/chrome/browser/sessions/base_session_service.cc |
+++ b/chrome/browser/sessions/base_session_service.cc |
@@ -5,35 +5,19 @@ |
#include "chrome/browser/sessions/base_session_service.h" |
#include "base/bind.h" |
-#include "base/pickle.h" |
#include "base/threading/thread.h" |
#include "chrome/browser/sessions/base_session_service_delegate.h" |
#include "chrome/browser/sessions/session_backend.h" |
-#include "chrome/browser/sessions/session_types.h" |
// BaseSessionService --------------------------------------------------------- |
namespace { |
-// Helper used by CreateUpdateTabNavigationCommand(). It writes |str| to |
-// |pickle|, if and only if |str| fits within (|max_bytes| - |*bytes_written|). |
-// |bytes_written| is incremented to reflect the data written. |
-void WriteStringToPickle(Pickle& pickle, int* bytes_written, int max_bytes, |
- const std::string& str) { |
- int num_bytes = str.size() * sizeof(char); |
- if (*bytes_written + num_bytes < max_bytes) { |
- *bytes_written += num_bytes; |
- pickle.WriteString(str); |
- } else { |
- pickle.WriteString(std::string()); |
- } |
-} |
- |
// Helper used by ScheduleGetLastSessionCommands. It runs callback on TaskRunner |
// thread if it's not canceled. |
void RunIfNotCanceled( |
const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, |
- const BaseSessionService::InternalGetCommandsCallback& callback, |
+ const BaseSessionService::GetCommandsCallback& callback, |
ScopedVector<SessionCommand> commands) { |
if (is_canceled.Run()) |
return; |
@@ -42,7 +26,7 @@ void RunIfNotCanceled( |
void PostOrRunInternalGetCommandsCallback( |
base::TaskRunner* task_runner, |
- const BaseSessionService::InternalGetCommandsCallback& callback, |
+ const BaseSessionService::GetCommandsCallback& callback, |
ScopedVector<SessionCommand> commands) { |
if (task_runner->RunsTasksOnCurrentThread()) { |
callback.Run(commands.Pass()); |
@@ -64,29 +48,22 @@ const int BaseSessionService::max_persist_navigation_count = 6; |
BaseSessionService::BaseSessionService( |
SessionType type, |
const base::FilePath& path, |
- scoped_ptr<BaseSessionServiceDelegate> delegate) |
+ BaseSessionServiceDelegate* delegate) |
: pending_reset_(false), |
commands_since_reset_(0), |
- delegate_(delegate.Pass()), |
+ delegate_(delegate), |
sequence_token_(delegate_->GetBlockingPool()->GetSequenceToken()), |
weak_factory_(this) { |
backend_ = new SessionBackend(type, path); |
DCHECK(backend_.get()); |
} |
-BaseSessionService::~BaseSessionService() { |
-} |
+BaseSessionService::~BaseSessionService() {} |
-void BaseSessionService::DeleteLastSession() { |
- RunTaskOnBackendThread( |
- FROM_HERE, |
- base::Bind(&SessionBackend::DeleteLastSession, backend())); |
-} |
- |
-void BaseSessionService::ScheduleCommand(SessionCommand* command) { |
+void BaseSessionService::ScheduleCommand(scoped_ptr<SessionCommand> command) { |
DCHECK(command); |
commands_since_reset_++; |
- pending_commands_.push_back(command); |
+ pending_commands_.push_back(command.release()); |
StartSaveTimer(); |
} |
@@ -96,174 +73,42 @@ void BaseSessionService::StartSaveTimer() { |
!weak_factory_.HasWeakPtrs()) { |
base::MessageLoop::current()->PostDelayedTask( |
FROM_HERE, |
- base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), |
+ base::Bind(&BaseSessionService::SaveInternal, |
+ weak_factory_.GetWeakPtr()), |
base::TimeDelta::FromMilliseconds(kSaveDelayMS)); |
} |
} |
-void BaseSessionService::Save() { |
- DCHECK(backend()); |
- |
- if (pending_commands_.empty()) |
- return; |
- |
+void BaseSessionService::DeleteLastSession() { |
RunTaskOnBackendThread( |
FROM_HERE, |
- base::Bind(&SessionBackend::AppendCommands, backend(), |
- new std::vector<SessionCommand*>(pending_commands_), |
- pending_reset_)); |
- |
- // Backend took ownership of commands. |
- pending_commands_.clear(); |
- |
- if (pending_reset_) { |
- commands_since_reset_ = 0; |
- pending_reset_ = false; |
- } |
-} |
- |
-SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( |
- SessionID::id_type command_id, |
- SessionID::id_type tab_id, |
- const sessions::SerializedNavigationEntry& navigation) { |
- // Use pickle to handle marshalling. |
- Pickle pickle; |
- pickle.WriteInt(tab_id); |
- // We only allow navigations up to 63k (which should be completely |
- // reasonable). |
- static const size_t max_state_size = |
- std::numeric_limits<SessionCommand::size_type>::max() - 1024; |
- navigation.WriteToPickle(max_state_size, &pickle); |
- return new SessionCommand(command_id, pickle); |
-} |
- |
-SessionCommand* BaseSessionService::CreateSetTabExtensionAppIDCommand( |
- SessionID::id_type command_id, |
- SessionID::id_type tab_id, |
- const std::string& extension_id) { |
- // Use pickle to handle marshalling. |
- Pickle pickle; |
- pickle.WriteInt(tab_id); |
- |
- // Enforce a max for ids. They should never be anywhere near this size. |
- static const SessionCommand::size_type max_id_size = |
- std::numeric_limits<SessionCommand::size_type>::max() - 1024; |
- |
- int bytes_written = 0; |
- |
- WriteStringToPickle(pickle, &bytes_written, max_id_size, extension_id); |
- |
- return new SessionCommand(command_id, pickle); |
-} |
- |
-SessionCommand* BaseSessionService::CreateSetTabUserAgentOverrideCommand( |
- SessionID::id_type command_id, |
- SessionID::id_type tab_id, |
- const std::string& user_agent_override) { |
- // Use pickle to handle marshalling. |
- Pickle pickle; |
- pickle.WriteInt(tab_id); |
- |
- // Enforce a max for the user agent length. They should never be anywhere |
- // near this size. |
- static const SessionCommand::size_type max_user_agent_size = |
- std::numeric_limits<SessionCommand::size_type>::max() - 1024; |
- |
- int bytes_written = 0; |
- |
- WriteStringToPickle(pickle, &bytes_written, max_user_agent_size, |
- user_agent_override); |
- |
- return new SessionCommand(command_id, pickle); |
-} |
- |
-SessionCommand* BaseSessionService::CreateSetWindowAppNameCommand( |
- SessionID::id_type command_id, |
- SessionID::id_type window_id, |
- const std::string& app_name) { |
- // Use pickle to handle marshalling. |
- Pickle pickle; |
- pickle.WriteInt(window_id); |
- |
- // Enforce a max for ids. They should never be anywhere near this size. |
- static const SessionCommand::size_type max_id_size = |
- std::numeric_limits<SessionCommand::size_type>::max() - 1024; |
- |
- int bytes_written = 0; |
- |
- WriteStringToPickle(pickle, &bytes_written, max_id_size, app_name); |
- |
- return new SessionCommand(command_id, pickle); |
-} |
- |
-bool BaseSessionService::RestoreUpdateTabNavigationCommand( |
- const SessionCommand& command, |
- sessions::SerializedNavigationEntry* navigation, |
- SessionID::id_type* tab_id) { |
- scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); |
- if (!pickle.get()) |
- return false; |
- PickleIterator iterator(*pickle); |
- return |
- pickle->ReadInt(&iterator, tab_id) && |
- navigation->ReadFromPickle(&iterator); |
-} |
- |
-bool BaseSessionService::RestoreSetTabExtensionAppIDCommand( |
- const SessionCommand& command, |
- SessionID::id_type* tab_id, |
- std::string* extension_app_id) { |
- scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); |
- if (!pickle.get()) |
- return false; |
- |
- PickleIterator iterator(*pickle); |
- return pickle->ReadInt(&iterator, tab_id) && |
- pickle->ReadString(&iterator, extension_app_id); |
-} |
- |
-bool BaseSessionService::RestoreSetTabUserAgentOverrideCommand( |
- const SessionCommand& command, |
- SessionID::id_type* tab_id, |
- std::string* user_agent_override) { |
- scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); |
- if (!pickle.get()) |
- return false; |
- |
- PickleIterator iterator(*pickle); |
- return pickle->ReadInt(&iterator, tab_id) && |
- pickle->ReadString(&iterator, user_agent_override); |
+ base::Bind(&SessionBackend::DeleteLastSession, backend())); |
} |
-bool BaseSessionService::RestoreSetWindowAppNameCommand( |
- const SessionCommand& command, |
- SessionID::id_type* window_id, |
- std::string* app_name) { |
- scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); |
- if (!pickle.get()) |
- return false; |
- |
- PickleIterator iterator(*pickle); |
- return pickle->ReadInt(&iterator, window_id) && |
- pickle->ReadString(&iterator, app_name); |
+void BaseSessionService::MoveCurrentSessionToLastSession() { |
+ SaveNow(); |
+ RunTaskOnBackendThread( |
+ FROM_HERE, base::Bind(&SessionBackend::MoveCurrentSessionToLastSession, |
+ backend())); |
} |
-bool BaseSessionService::ShouldTrackEntry(const GURL& url) { |
- return url.is_valid() && delegate_->ShouldTrackEntry(url); |
+void BaseSessionService::SaveNow() { |
+ if (backend()) |
+ SaveInternal(); |
} |
base::CancelableTaskTracker::TaskId |
BaseSessionService::ScheduleGetLastSessionCommands( |
- const InternalGetCommandsCallback& callback, |
+ const GetCommandsCallback& callback, |
base::CancelableTaskTracker* tracker) { |
base::CancelableTaskTracker::IsCanceledCallback is_canceled; |
base::CancelableTaskTracker::TaskId id = |
tracker->NewTrackedTaskId(&is_canceled); |
- InternalGetCommandsCallback run_if_not_canceled = |
+ GetCommandsCallback run_if_not_canceled = |
base::Bind(&RunIfNotCanceled, is_canceled, callback); |
- InternalGetCommandsCallback callback_runner = |
+ GetCommandsCallback callback_runner = |
base::Bind(&PostOrRunInternalGetCommandsCallback, |
base::MessageLoopProxy::current(), run_if_not_canceled); |
@@ -274,6 +119,39 @@ BaseSessionService::ScheduleGetLastSessionCommands( |
return id; |
} |
+bool BaseSessionService::ProcessedAnyCommandsForTest() { |
+ return backend()->inited() || !pending_commands().empty(); |
+} |
+ |
+void BaseSessionService::SaveInternal() { |
+ DCHECK(backend()); |
+ |
+ // Inform the delegate that we will save the commands now, giving it the |
+ // opportunity to append more commands. |
+ delegate_->OnWillSaveCommands(); |
+ |
+ if (pending_commands_.empty()) |
+ return; |
+ |
+ // We create a new ScopedVector which will receive all elements from the |
+ // current commands. This will also clear the current list. |
+ ScopedVector<SessionCommand>* passed = new ScopedVector<SessionCommand>(); |
+ passed->swap(pending_commands_); |
+ DCHECK(pending_commands_.empty()); |
+ RunTaskOnBackendThread( |
+ FROM_HERE, |
+ base::Bind(&SessionBackend::AppendCommands, backend(), |
+ passed, |
+ pending_reset_)); |
+ |
+ if (pending_reset_) { |
+ commands_since_reset_ = 0; |
+ pending_reset_ = false; |
+ } |
+ |
+ delegate_->OnSavedCommands(); |
+} |
+ |
void BaseSessionService::RunTaskOnBackendThread( |
const tracked_objects::Location& from_here, |
const base::Closure& task) { |