15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/base_session_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_backend.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_types.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/common/url_constants.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/referrer.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BaseSessionService --------------------------------------------------------- 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper used by CreateUpdateTabNavigationCommand(). It writes |str| to 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |pickle|, if and only if |str| fits within (|max_bytes| - |*bytes_written|). 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |bytes_written| is incremented to reflect the data written. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WriteStringToPickle(Pickle& pickle, int* bytes_written, int max_bytes, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& str) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_bytes = str.size() * sizeof(char); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*bytes_written + num_bytes < max_bytes) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_written += num_bytes; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteString(str); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteString(std::string()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Helper used by ScheduleGetLastSessionCommands. It runs callback on TaskRunner 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread if it's not canceled. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RunIfNotCanceled( 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::CancelableTaskTracker::IsCanceledCallback& is_canceled, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BaseSessionService::InternalGetCommandsCallback& callback, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<SessionCommand> commands) { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_canceled.Run()) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(commands.Pass()); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PostOrRunInternalGetCommandsCallback( 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TaskRunner* task_runner, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const BaseSessionService::InternalGetCommandsCallback& callback, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedVector<SessionCommand> commands) { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (task_runner->RunsTasksOnCurrentThread()) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(commands.Pass()); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_runner->PostTask(FROM_HERE, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(callback, base::Passed(&commands))); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delay between when a command is received, and when we save it to the 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backend. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSaveDelayMS = 2500; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int BaseSessionService::max_persist_navigation_count = 6; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseSessionService::BaseSessionService(SessionType type, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_(false), 80c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch commands_since_reset_(0), 81c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch sequence_token_( 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::BrowserThread::GetBlockingPool()->GetSequenceToken()), 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should never be created when incognito. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile->IsOffTheRecord()); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_ = new SessionBackend(type, profile_ ? profile_->GetPath() : path); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend_.get()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseSessionService::~BaseSessionService() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::DeleteLastSession() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::DeleteLastSession, backend())); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::ScheduleCommand(SessionCommand* command) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands_since_reset_++; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_commands_.push_back(command); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartSaveTimer(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::StartSaveTimer() { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't start a timer when testing (profile == NULL or 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageLoop::current() is NULL). 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (base::MessageLoop::current() && profile() && 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !weak_factory_.HasWeakPtrs()) { 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kSaveDelayMS)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::Save() { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_commands_.empty()) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::AppendCommands, backend(), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new std::vector<SessionCommand*>(pending_commands_), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Backend took ownership of commands. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_commands_.clear(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_reset_) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands_since_reset_ = 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_ = false; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const sessions::SerializedNavigationEntry& navigation) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We only allow navigations up to 63k (which should be completely 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // reasonable). 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const size_t max_state_size = 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) navigation.WriteToPickle(max_state_size, &pickle); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetTabExtensionAppIDCommand( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for ids. They should never be anywhere near this size. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_id_size = 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_id_size, extension_id); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetTabUserAgentOverrideCommand( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent_override) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for the user agent length. They should never be anywhere 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // near this size. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_user_agent_size = 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_user_agent_size, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_agent_override); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetWindowAppNameCommand( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type window_id, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_name) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(window_id); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for ids. They should never be anywhere near this size. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_id_size = 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_id_size, app_name); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreUpdateTabNavigationCommand( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sessions::SerializedNavigationEntry* navigation, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadInt(&iterator, tab_id) && 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) navigation->ReadFromPickle(&iterator); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetTabExtensionAppIDCommand( 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* extension_app_id) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, tab_id) && 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, extension_app_id); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetTabUserAgentOverrideCommand( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* user_agent_override) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, tab_id) && 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, user_agent_override); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetWindowAppNameCommand( 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* window_id, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* app_name) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, window_id) && 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, app_name); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::ShouldTrackEntry(const GURL& url) { 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Blacklist chrome://quit and chrome://restart to avoid quit or restart 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // loops. 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return url.is_valid() && !(url.SchemeIs(content::kChromeUIScheme) && 271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (url.host() == chrome::kChromeUIQuitHost || 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) url.host() == chrome::kChromeUIRestartHost)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::CancelableTaskTracker::TaskId 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BaseSessionService::ScheduleGetLastSessionCommands( 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InternalGetCommandsCallback& callback, 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker* tracker) { 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker::IsCanceledCallback is_canceled; 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::CancelableTaskTracker::TaskId id = 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tracker->NewTrackedTaskId(&is_canceled); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InternalGetCommandsCallback run_if_not_canceled = 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&RunIfNotCanceled, is_canceled, callback); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InternalGetCommandsCallback callback_runner = 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PostOrRunInternalGetCommandsCallback, 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current(), run_if_not_canceled); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::ReadLastSessionCommands, backend(), 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_canceled, callback_runner)); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BaseSessionService::RunTaskOnBackendThread( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) { 300c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 301c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 302c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!pool->IsShutdownInProgress()) { 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pool->PostSequencedWorkerTask(sequence_token_, from_here, task); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 305c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // Fall back to executing on the main thread if the sequence 306c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // worker pool has been requested to shutdown (around shutdown 307c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch // time). 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task.Run(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 311