1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sessions/base_session_service.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/pickle.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sessions/session_backend.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sessions/session_types.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// InternalGetCommandsRequest -------------------------------------------------
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseSessionService::InternalGetCommandsRequest::~InternalGetCommandsRequest() {
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&commands);
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BaseSessionService ---------------------------------------------------------
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper used by CreateUpdateTabNavigationCommand(). It writes |str| to
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |pickle|, if and only if |str| fits within (|max_bytes| - |*bytes_written|).
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// |bytes_written| is incremented to reflect the data written.
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WriteStringToPickle(Pickle& pickle, int* bytes_written, int max_bytes,
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         const std::string& str) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int num_bytes = str.size() * sizeof(char);
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (*bytes_written + num_bytes < max_bytes) {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *bytes_written += num_bytes;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pickle.WriteString(str);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pickle.WriteString(std::string());
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// string16 version of WriteStringToPickle.
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WriteString16ToPickle(Pickle& pickle, int* bytes_written, int max_bytes,
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const string16& str) {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int num_bytes = str.size() * sizeof(char16);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (*bytes_written + num_bytes < max_bytes) {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *bytes_written += num_bytes;
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pickle.WriteString16(str);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pickle.WriteString16(string16());
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Delay between when a command is received, and when we save it to the
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// backend.
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kSaveDelayMS = 2500;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int BaseSessionService::max_persist_navigation_count = 6;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseSessionService::BaseSessionService(SessionType type,
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       Profile* profile,
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const FilePath& path)
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : profile_(profile),
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      path_(path),
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      backend_thread_(NULL),
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(save_factory_(this)),
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pending_reset_(false),
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      commands_since_reset_(0) {
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile) {
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // We should never be created when incognito.
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(!profile->IsOffTheRecord());
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_ = new SessionBackend(type,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_ ? profile_->GetPath() : path_);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(backend_.get());
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  backend_thread_ = g_browser_process->file_thread();
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_thread_)
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_->Init();
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If backend_thread is non-null, backend will init itself as appropriate.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseSessionService::~BaseSessionService() {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BaseSessionService::DeleteLastSession() {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_thread()) {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend()->DeleteLastSession();
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        backend(), &SessionBackend::DeleteLastSession));
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BaseSessionService::ScheduleCommand(SessionCommand* command) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(command);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  commands_since_reset_++;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_commands_.push_back(command);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StartSaveTimer();
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BaseSessionService::StartSaveTimer() {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't start a timer when testing (profile == NULL or
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // MessageLoop::current() is NULL).
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (MessageLoop::current() && profile() && save_factory_.empty()) {
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostDelayedTask(FROM_HERE,
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        save_factory_.NewRunnableMethod(&BaseSessionService::Save),
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        kSaveDelayMS);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BaseSessionService::Save() {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(backend());
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pending_commands_.empty())
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!backend_thread()) {
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend()->AppendCommands(
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new std::vector<SessionCommand*>(pending_commands_), pending_reset_);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        backend(), &SessionBackend::AppendCommands,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new std::vector<SessionCommand*>(pending_commands_),
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        pending_reset_));
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Backend took ownership of commands.
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_commands_.clear();
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pending_reset_) {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    commands_since_reset_ = 0;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pending_reset_ = false;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand(
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type command_id,
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type tab_id,
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int index,
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NavigationEntry& entry) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use pickle to handle marshalling.
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Pickle pickle;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(tab_id);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(index);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only allow navigations up to 63k (which should be completely
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // reasonable). On the off chance we get one that is too big, try to
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // keep the url.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bound the string data (which is variable length) to
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |max_state_size bytes| bytes.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const SessionCommand::size_type max_state_size =
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::numeric_limits<SessionCommand::size_type>::max() - 1024;
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int bytes_written = 0;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WriteStringToPickle(pickle, &bytes_written, max_state_size,
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      entry.virtual_url().spec());
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WriteString16ToPickle(pickle, &bytes_written, max_state_size, entry.title());
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (entry.has_post_data()) {
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Remove the form data, it may contain sensitive information.
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WriteStringToPickle(pickle, &bytes_written, max_state_size,
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        webkit_glue::RemoveFormDataFromHistoryState(entry.content_state()));
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WriteStringToPickle(pickle, &bytes_written, max_state_size,
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        entry.content_state());
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(entry.transition_type());
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int type_mask = entry.has_post_data() ? TabNavigation::HAS_POST_DATA : 0;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(type_mask);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WriteStringToPickle(pickle, &bytes_written, max_state_size,
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry.referrer().is_valid() ? entry.referrer().spec() : std::string());
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Adding more data? Be sure and update TabRestoreService too.
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new SessionCommand(command_id, pickle);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSessionCommand* BaseSessionService::CreateSetTabExtensionAppIDCommand(
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type command_id,
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type tab_id,
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& extension_id) {
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use pickle to handle marshalling.
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Pickle pickle;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(tab_id);
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Enforce a max for ids. They should never be anywhere near this size.
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const SessionCommand::size_type max_id_size =
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::numeric_limits<SessionCommand::size_type>::max() - 1024;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int bytes_written = 0;
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WriteStringToPickle(pickle, &bytes_written, max_id_size, extension_id);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new SessionCommand(command_id, pickle);
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BaseSessionService::RestoreUpdateTabNavigationCommand(
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const SessionCommand& command,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabNavigation* navigation,
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type* tab_id) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pickle.get())
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void* iterator = NULL;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string url_spec;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pickle->ReadInt(&iterator, tab_id) ||
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pickle->ReadInt(&iterator, &(navigation->index_)) ||
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pickle->ReadString(&iterator, &url_spec) ||
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pickle->ReadString16(&iterator, &(navigation->title_)) ||
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pickle->ReadString(&iterator, &(navigation->state_)) ||
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !pickle->ReadInt(&iterator,
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       reinterpret_cast<int*>(&(navigation->transition_))))
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // type_mask did not always exist in the written stream. As such, we
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // don't fail if it can't be read.
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool has_type_mask = pickle->ReadInt(&iterator, &(navigation->type_mask_));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (has_type_mask) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the "referrer" property was added after type_mask to the written
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // stream. As such, we don't fail if it can't be read.
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string referrer_spec;
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pickle->ReadString(&iterator, &referrer_spec);
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!referrer_spec.empty())
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      navigation->referrer_ = GURL(referrer_spec);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  navigation->virtual_url_ = GURL(url_spec);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BaseSessionService::RestoreSetTabExtensionAppIDCommand(
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const SessionCommand& command,
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionID::id_type* tab_id,
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string* extension_app_id) {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<Pickle> pickle(command.PayloadAsPickle());
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pickle.get())
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void* iterator = NULL;
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return pickle->ReadInt(&iterator, tab_id) &&
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      pickle->ReadString(&iterator, extension_app_id);
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BaseSessionService::ShouldTrackEntry(const NavigationEntry& entry) {
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return entry.virtual_url().is_valid();
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BaseSessionService::ShouldTrackEntry(const TabNavigation& navigation) {
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return navigation.virtual_url().is_valid();
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseSessionService::Handle BaseSessionService::ScheduleGetLastSessionCommands(
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InternalGetCommandsRequest* request,
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelableRequestConsumerBase* consumer) {
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<InternalGetCommandsRequest> request_wrapper(request);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddRequest(request, consumer);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backend_thread()) {
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        backend(), &SessionBackend::ReadLastSessionCommands, request_wrapper));
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend()->ReadLastSessionCommands(request);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return request->handle();
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBaseSessionService::Handle
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    BaseSessionService::ScheduleGetCurrentSessionCommands(
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        InternalGetCommandsRequest* request,
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CancelableRequestConsumerBase* consumer) {
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<InternalGetCommandsRequest> request_wrapper(request);
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddRequest(request, consumer);
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (backend_thread()) {
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend_thread()->message_loop()->PostTask(FROM_HERE,
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(backend(),
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          &SessionBackend::ReadCurrentSessionCommands,
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          request_wrapper));
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    backend()->ReadCurrentSessionCommands(request);
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return request->handle();
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
287