| 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) {
|
|
|