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