base_session_service.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/referrer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/glue/webkit_glue.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( 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const 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) ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_(false), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands_since_reset_(0) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should never be created when incognito. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!profile->IsOffTheRecord()); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_ = new SessionBackend(type, profile_ ? profile_->GetPath() : path); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend_.get()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SessionBackend::Init() cannot be scheduled to be called here. There are 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service processes which create the BaseSessionService, but they should not 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize the backend. If they do, the backend will cycle the session 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // restore files. That in turn prevents the session restore from working when 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the normal chromium process is launched. Normally, the backend will be 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialized before it's actually used. However, if we're running as a part 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of a test, it must be initialized now. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!RunningInProduction()) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->Init(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BaseSessionService::~BaseSessionService() { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::DeleteLastSession() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::DeleteLastSession, backend())); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::ScheduleCommand(SessionCommand* command) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands_since_reset_++; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_commands_.push_back(command); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartSaveTimer(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::StartSaveTimer() { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't start a timer when testing (profile == NULL or 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MessageLoop::current() is NULL). 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MessageLoop::current() && profile() && !weak_factory_.HasWeakPtrs()) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->PostDelayedTask( 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&BaseSessionService::Save, weak_factory_.GetWeakPtr()), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kSaveDelayMS)); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BaseSessionService::Save() { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_commands_.empty()) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::AppendCommands, backend(), 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new std::vector<SessionCommand*>(pending_commands_), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Backend took ownership of commands. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_commands_.clear(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_reset_) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) commands_since_reset_ = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_reset_ = false; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateUpdateTabNavigationCommand( 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabNavigation& navigation) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) navigation.WriteToPickle(&pickle); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetTabExtensionAppIDCommand( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for ids. They should never be anywhere near this size. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_id_size = 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_id_size, extension_id); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetTabUserAgentOverrideCommand( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type tab_id, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent_override) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(tab_id); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for the user agent length. They should never be anywhere 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // near this size. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_user_agent_size = 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_user_agent_size, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_agent_override); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SessionCommand* BaseSessionService::CreateSetWindowAppNameCommand( 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type command_id, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type window_id, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_name) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use pickle to handle marshalling. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(window_id); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enforce a max for ids. They should never be anywhere near this size. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SessionCommand::size_type max_id_size = 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::numeric_limits<SessionCommand::size_type>::max() - 1024; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStringToPickle(pickle, &bytes_written, max_id_size, app_name); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new SessionCommand(command_id, pickle); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreUpdateTabNavigationCommand( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabNavigation* navigation, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadInt(&iterator, tab_id) && 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) navigation->ReadFromPickle(&iterator); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetTabExtensionAppIDCommand( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* extension_app_id) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, tab_id) && 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, extension_app_id); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetTabUserAgentOverrideCommand( 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* tab_id, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* user_agent_override) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, tab_id) && 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, user_agent_override); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RestoreSetWindowAppNameCommand( 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionCommand& command, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type* window_id, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* app_name) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Pickle> pickle(command.PayloadAsPickle()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pickle.get()) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iterator(*pickle); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pickle->ReadInt(&iterator, window_id) && 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle->ReadString(&iterator, app_name); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::ShouldTrackEntry(const GURL& url) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url.is_valid(); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CancelableTaskTracker::TaskId 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BaseSessionService::ScheduleGetLastSessionCommands( 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InternalGetCommandsCallback& callback, 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker* tracker) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker::IsCanceledCallback is_canceled; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker::TaskId id = tracker->NewTrackedTaskId(&is_canceled); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InternalGetCommandsCallback run_if_not_canceled = 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&RunIfNotCanceled, is_canceled, callback); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InternalGetCommandsCallback callback_runner = 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PostOrRunInternalGetCommandsCallback, 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::MessageLoopProxy::current(), run_if_not_canceled); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTaskOnBackendThread( 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&SessionBackend::ReadLastSessionCommands, backend(), 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_canceled, callback_runner)); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return id; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RunTaskOnBackendThread( 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile_ && BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BrowserThread::PostTask(BrowserThread::FILE, from_here, task); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fall back to executing on the main thread if the file thread 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has gone away (around shutdown time) or if we're running as 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // part of a unit test that does not set profile_. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task.Run(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BaseSessionService::RunningInProduction() const { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_ && BrowserThread::IsMessageLoopValid(BrowserThread::FILE); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 312