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/session_restore.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/performance_monitor/startup_timer.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_service.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_service_factory.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_types.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabrestore.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/cancelable_task_tracker.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/dom_storage_context.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/session_storage_namespace.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/storage_partition.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/util/win8_util.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionRestoreImpl; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabLoader; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabLoader* shared_tab_loader = NULL; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pointers to SessionRestoreImpls which are currently restoring the session. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::set<SessionRestoreImpl*>* active_session_restorers = NULL; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabLoader ------------------------------------------------------------------ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initial delay (see class decription for details). 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kInitialDelayTimerMS = 100; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabLoader is responsible for loading tabs after session restore creates 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tabs. New tabs are loaded after the current tab finishes loading, or a delay 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is reached (initially kInitialDelayTimerMS). If the delay is reached before 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a tab finishes loading a new tab is loaded and the time of the delay 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doubled. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabLoader keeps a reference to itself when it's loading. When it has finished 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// loading, it drops the reference. If another profile is restored while the 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabLoader is loading, it will schedule its tabs to get loaded by the same 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabLoader. When doing the scheduling, it holds a reference to the TabLoader. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is not part of SessionRestoreImpl so that synchronous destruction 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of SessionRestoreImpl doesn't have timing problems. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TabLoader : public content::NotificationObserver, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public net::NetworkChangeNotifier::ConnectionTypeObserver, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::RefCounted<TabLoader> { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieves a pointer to the TabLoader instance shared between profiles, or 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // creates a new TabLoader if it doesn't exist. If a TabLoader is created, its 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting timestamp is set to |restore_started|. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TabLoader* GetTabLoader(base::TimeTicks restore_started); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a tab for loading. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleLoad(NavigationController* controller); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notifies the loader that a tab has been scheduled for loading through 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some other mechanism. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TabIsLoading(NavigationController* controller); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invokes |LoadNextTab| to load a tab. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must be invoked once to start loading. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartLoading(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<TabLoader>; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<NavigationController*> TabsLoading; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<NavigationController*> TabsToLoad; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<RenderWidgetHost*> RenderWidgetHostSet; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TabLoader(base::TimeTicks restore_started); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TabLoader(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads the next tab. If there are no more tabs to load this deletes itself, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise |force_load_timer_| is restarted. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LoadNextTab(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NotificationObserver method. Removes the specified tab and loads the next 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tab. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // net::NetworkChangeNotifier::ConnectionTypeObserver overrides. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnConnectionTypeChanged( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes the listeners from the specified tab and removes the tab from 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the set of tabs to load and list of tabs we're waiting to get a load 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveTab(NavigationController* tab); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoked from |force_load_timer_|. Doubles |force_load_delay_| and invokes 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |LoadNextTab| to load the next tab 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ForceLoadTimerFired(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the RenderWidgetHost associated with a tab if there is one, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL otherwise. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static RenderWidgetHost* GetRenderWidgetHost(NavigationController* tab); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Register for necessary notifications on a tab navigation controller. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RegisterForNotifications(NavigationController* controller); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a tab goes away or a load completes. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleTabClosedOrLoaded(NavigationController* controller); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Current delay before a new tab is loaded. See class description for 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // details. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 force_load_delay_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Has Load been invoked? 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool loading_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have we recorded the times for a tab paint? 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool got_first_paint_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The set of tabs we've initiated loading on. This does NOT include the 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // selected tabs. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabsLoading tabs_loading_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The tabs we need to load. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabsToLoad tabs_to_load_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The renderers we have started loading into. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHostSet render_widget_hosts_loading_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The renderers we have loaded and are waiting on to paint. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHostSet render_widget_hosts_to_paint_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of tabs that have been restored. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_count_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OneShotTimer<TabLoader> force_load_timer_; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time the restore process started. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks restore_started_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Max number of tabs that were loaded in parallel (for metrics). 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_parallel_tab_loads_; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For keeping TabLoader alive while it's loading even if no 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SessionRestoreImpls reference it. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TabLoader> this_retainer_; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TabLoader); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabLoader* TabLoader::GetTabLoader(base::TimeTicks restore_started) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!shared_tab_loader) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_tab_loader = new TabLoader(restore_started); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return shared_tab_loader; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::ScheduleLoad(NavigationController* controller) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(controller); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(find(tabs_to_load_.begin(), tabs_to_load_.end(), controller) == 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_to_load_.end()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_to_load_.push_back(controller); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterForNotifications(controller); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::TabIsLoading(NavigationController* controller) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(controller); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(find(tabs_loading_.begin(), tabs_loading_.end(), controller) == 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.end()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.insert(controller); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHost* render_widget_host = GetRenderWidgetHost(controller); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(render_widget_host); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_loading_.insert(render_widget_host); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterForNotifications(controller); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::StartLoading() { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When multiple profiles are using the same TabLoader, another profile might 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already have started loading. In that case, the tabs scheduled for loading 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by this profile are already in the loading queue, and they will get loaded 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eventually. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loading_) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add( 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_retainer_ = this; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!net::NetworkChangeNotifier::IsOffline()) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_ = true; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextTab(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_ = true; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextTab(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabLoader::TabLoader(base::TimeTicks restore_started) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : force_load_delay_(kInitialDelayTimerMS), 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_(false), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_paint_(false), 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_count_(0), 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_started_(restore_started), 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_parallel_tab_loads_(0) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabLoader::~TabLoader() { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.empty() && tabs_to_load_.empty()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_tab_loader = NULL; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::LoadNextTab() { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tabs_to_load_.empty()) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* tab = tabs_to_load_.front(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.insert(tab); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tabs_loading_.size() > max_parallel_tab_loads_) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_parallel_tab_loads_ = tabs_loading_.size(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_to_load_.pop_front(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->LoadIfNecessary(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* contents = tab->GetWebContents(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(contents); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser && 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents() != contents) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // By default tabs are marked as visible. As only the active tab is 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visible we need to explicitly tell non-active tabs they are hidden. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Without this call non-active tabs are not marked as backgrounded. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: We need to do this here rather than when the tab is added to 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the Browser as at that time not everything has been created, so that 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the call would do nothing. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->WasHidden(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tabs_to_load_.empty()) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_load_timer_.Stop(); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each time we load a tab we also set a timer to force us to start loading 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the next tab if this one doesn't load quickly enough. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_load_timer_.Start(FROM_HERE, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(force_load_delay_), 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, &TabLoader::ForceLoadTimerFired); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // When the session restore is done synchronously, notification is sent from 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // SessionRestoreImpl::Restore . 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (tabs_to_load_.empty() && !SessionRestore::IsRestoringSynchronously()) { 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::NotificationService::current()->Notify( 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome::NOTIFICATION_SESSION_RESTORE_DONE, 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::NotificationService::AllSources(), 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::NotificationService::NoDetails()); 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::Observe(int type, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_LOAD_START: { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add this render_widget_host to the set of those we're waiting for 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // paints on. We want to only record stats for paints that occur after 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a load has finished. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* tab = 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(source).ptr(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHost* render_widget_host = GetRenderWidgetHost(tab); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(render_widget_host); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_loading_.insert(render_widget_host); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = content::Source<WebContents>(source).ptr(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!got_first_paint_) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHost* render_widget_host = 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRenderWidgetHost(&web_contents->GetController()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_loading_.erase(render_widget_host); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleTabClosedOrLoaded(&web_contents->GetController()); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_LOAD_STOP: { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* tab = 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(source).ptr(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_to_paint_.insert(GetRenderWidgetHost(tab)); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleTabClosedOrLoaded(tab); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE: { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderWidgetHost* render_widget_host = 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<RenderWidgetHost>(source).ptr(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!got_first_paint_ && render_widget_host->GetView() && 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_host->GetView()->IsShowing()) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (render_widget_hosts_to_paint_.find(render_widget_host) != 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_to_paint_.end()) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Got a paint for one of our renderers, so record time. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_paint_ = true; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_to_paint = 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - restore_started_; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore.FirstTabPainted", 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_paint, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(100), 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record a time for the number of tabs, to help track down 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contention. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string time_for_count = 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("SessionRestore.FirstTabPainted_%d", 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_count_); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase* counter_for_count = 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Histogram::FactoryTimeGet( 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_for_count, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(100), 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Histogram::kUmaTargetedHistogramFlag); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter_for_count->AddTime(time_to_paint); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (render_widget_hosts_loading_.find(render_widget_host) == 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_widget_hosts_loading_.end()) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a host for a tab we're not loading some other tab 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has rendered and there's no point tracking the time. This could 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happen because the user opened a different tab or restored tabs 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to an already existing browser and an existing tab painted. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_paint_ = true; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unknown notification received:" << type; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete ourselves when we're not waiting for any more notifications. If this 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was not the last reference, a SessionRestoreImpl holding a reference will 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // eventually call StartLoading (which assigns this_retainer_), or drop the 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference without initiating a load. 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((got_first_paint_ || render_widget_hosts_to_paint_.empty()) && 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.empty() && tabs_to_load_.empty()) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this_retainer_ = NULL; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::OnConnectionTypeChanged( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType type) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type != net::NetworkChangeNotifier::CONNECTION_NONE) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!loading_) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_ = true; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextTab(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_ = false; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::RemoveTab(NavigationController* tab) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<WebContents>(tab->GetWebContents())); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(tab)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Remove(this, content::NOTIFICATION_LOAD_START, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(tab)); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabsLoading::iterator i = tabs_loading_.find(tab); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != tabs_loading_.end()) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_loading_.erase(i); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabsToLoad::iterator j = 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) find(tabs_to_load_.begin(), tabs_to_load_.end(), tab); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j != tabs_to_load_.end()) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabs_to_load_.erase(j); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::ForceLoadTimerFired() { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_load_delay_ *= 2; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextTab(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderWidgetHost* TabLoader::GetRenderWidgetHost(NavigationController* tab) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = tab->GetWebContents(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (web_contents) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderWidgetHostView* render_widget_host_view = 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents->GetRenderWidgetHostView(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (render_widget_host_view) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return render_widget_host_view->GetRenderWidgetHost(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::RegisterForNotifications(NavigationController* controller) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<WebContents>(controller->GetWebContents())); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(controller)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_LOAD_START, 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>(controller)); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++tab_count_; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabLoader::HandleTabClosedOrLoaded(NavigationController* tab) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveTab(tab); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loading_) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadNextTab(); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tabs_loading_.empty() && tabs_to_load_.empty()) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_to_load = 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - restore_started_; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) performance_monitor::StartupTimer::SetElapsedSessionRestoreTime( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_load); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore.AllTabsLoaded", 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_load, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(100), 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record a time for the number of tabs, to help track down contention. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string time_for_count = 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf("SessionRestore.AllTabsLoaded_%d", tab_count_); 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase* counter_for_count = 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Histogram::FactoryTimeGet( 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_for_count, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(100), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Histogram::kUmaTargetedHistogramFlag); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter_for_count->AddTime(time_to_load); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("SessionRestore.ParallelTabLoads", 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_parallel_tab_loads_); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionRestoreImpl --------------------------------------------------------- 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionRestoreImpl is responsible for fetching the set of tabs to create 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from SessionService. SessionRestoreImpl deletes itself when done. 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SessionRestoreImpl : public content::NotificationObserver { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionRestoreImpl(Profile* profile, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool synchronous, 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool clobber_existing_tab, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool always_create_tabbed_browser, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& urls_to_open) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser), 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_desktop_type_(host_desktop_type), 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) synchronous_(synchronous), 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clobber_existing_tab_(clobber_existing_tab), 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) always_create_tabbed_browser_(always_create_tabbed_browser), 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_to_open_(urls_to_open), 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_window_id_(0), 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_started_(base::TimeTicks::Now()), 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_shown_(false) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // For sanity's sake, if |browser| is non-null: force |host_desktop_type| to 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be the same as |browser|'s desktop type. 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!browser || browser->host_desktop_type() == host_desktop_type); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_session_restorers == NULL) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_session_restorers = new std::set<SessionRestoreImpl*>(); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one SessionRestoreImpl should be operating on the profile at the 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same time. 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<SessionRestoreImpl*>::const_iterator it; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (it = active_session_restorers->begin(); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != active_session_restorers->end(); ++it) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->profile_ == profile) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it == active_session_restorers->end()); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_session_restorers->insert(this); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When asynchronous its possible for there to be no windows. To make sure 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome doesn't prematurely exit AddRef the process. We'll release in the 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destructor when restore is done. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->AddRefModule(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool synchronous() const { return synchronous_; } 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* Restore() { 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionService* session_service = 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionServiceFactory::GetForProfile(profile_); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(session_service); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_service->GetLastSession( 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SessionRestoreImpl::OnGotSession, base::Unretained(this)), 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &cancelable_task_tracker_); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (synchronous_) { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::ScopedNestableTaskAllower allow( 55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()); 55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = ProcessSessionWindows(&windows_, active_window_id_); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::current()->Notify( 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NOTIFICATION_SESSION_RESTORE_DONE, 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllSources(), 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::NoDetails()); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_) { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED, 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Browser>(browser_)); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5703240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // Restore window(s) from a foreign session. Returns newly created Browsers. 5713240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::vector<Browser*> RestoreForeignSession( 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const SessionWindow*>::const_iterator begin, 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const SessionWindow*>::const_iterator end) { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTabCreation(); 5753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::vector<Browser*> browsers; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a browser instance to put the restored tabs in. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<const SessionWindow*>::const_iterator i = begin; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != end; ++i) { 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = CreateRestoredBrowser( 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<Browser::Type>((*i)->type), 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->bounds, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->show_state, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->app_name); 5843240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch browsers.push_back(browser); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore and show the browser. 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int initial_tab_count = 0; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_tab_index = std::max( 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min((*i)->selected_tab_index, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>((*i)->tabs.size()) - 1)); 59290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RestoreTabsToBrowser(*(*i), browser, initial_tab_count, 59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) selected_tab_index); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifySessionServiceOfRestoredTabs(browser, initial_tab_count); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always create in a new window 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FinishedTabCreation(true, true); 5993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return browsers; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore a single tab from a foreign session. 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Opens in the tab in the last active browser, unless disposition is 6043240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // NEW_WINDOW, in which case the tab will be opened in a new browser. Returns 6053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch // the WebContents of the restored tab. 6063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents* RestoreForeignTab(const SessionTab& tab, 6073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WindowOpenDisposition disposition) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!tab.navigations.empty()); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_index = tab.current_navigation_index; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_index = std::max( 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(selected_index, 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(tab.navigations.size() - 1))); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_new_window = disposition == NEW_WINDOW; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = use_new_window ? 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Browser(Browser::CreateParams(profile_, host_desktop_type_)) : 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunchForTab(browser, tab, selected_index); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents* web_contents; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == CURRENT_TAB) { 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!use_new_window); 6263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents = chrome::ReplaceRestoredTab(browser, 6273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.navigations, 6283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch selected_index, 6293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch true, 6303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.extension_app_id, 6313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch NULL, 6323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.user_agent_override); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index = 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) use_new_window ? 0 : browser->tab_strip_model()->active_index() + 1; 6363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents = chrome::AddRestoredTab( 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser, 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.navigations, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_index, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.extension_app_id, 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disposition == NEW_FOREGROUND_TAB, // selected 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.pinned, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.user_agent_override); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start loading the tab immediately. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents->GetController().LoadIfNecessary(); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_new_window) { 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->ActivateTabAt(0, true); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Show(); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifySessionServiceOfRestoredTabs(browser, 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->count()); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since FinishedTabCreation() is not called here, |this| will leak if we 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are not in sychronous mode. 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(synchronous_); 6613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return web_contents; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SessionRestoreImpl() { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&windows_); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_session_restorers->erase(this); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_session_restorers->empty()) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete active_session_restorers; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_session_restorers = NULL; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->ReleaseModule(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::NotificationDetails& details) OVERRIDE { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_BROWSER_CLOSED: 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile() { return profile_; } 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoked when beginning to create new tabs. Resets the tab_loader_. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartTabCreation() { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_loader_ = TabLoader::GetTabLoader(restore_started_); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoked when done with creating all the tabs/browsers. 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |created_tabbed_browser| indicates whether a tabbed browser was created, 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or we used an existing tabbed browser. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If successful, this begins loading tabs and deletes itself when all tabs 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have been loaded. 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the Browser that was created, if any. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* FinishedTabCreation(bool succeeded, bool created_tabbed_browser) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = NULL; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!created_tabbed_browser && always_create_tabbed_browser_) { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile_, 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host_desktop_type_)); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urls_to_open_.empty()) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No tab browsers were created and no URLs were supplied on the command 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // line. Add an empty URL, which is treated as opening the users home 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // page. 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_to_open_.push_back(GURL()); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendURLsToBrowser(browser, urls_to_open_); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Show(); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (succeeded) { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_loader_.get()); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TabLoader deletes itself when done loading. 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_loader_->StartLoading(); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_loader_ = NULL; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!synchronous_) { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're not synchronous we need to delete ourself. 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: we must use DeleteLater here as most likely we're in a callback 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the history service which doesn't deal well with deleting the 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // object it is notifying. 73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The delete may take a while and at this point we no longer care about 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // if the browser is deleted. Don't listen to anything. This avoid a 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // possible double delete too (if browser is closed before DeleteSoon() is 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // processed). 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) registrar_.RemoveAll(); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-End", false); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnGotSession(ScopedVector<SessionWindow> windows, 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type active_window_id) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_to_got_sessions = 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - restore_started_; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore.TimeToGotSessions", 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_got_sessions, 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(1000), 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-GotSession", false); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (synchronous_) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See comment above windows_ as to why we don't process immediately. 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) windows_.swap(windows.get()); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_window_id_ = active_window_id; 76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->QuitNow(); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProcessSessionWindows(&windows.get(), active_window_id); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* ProcessSessionWindows(std::vector<SessionWindow*>* windows, 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type active_window_id) { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "ProcessSessionWindows " << windows->size(); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_to_process_sessions = 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - restore_started_; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore.TimeToProcessSessions", 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_process_sessions, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(1000), 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (windows->empty()) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore was unsuccessful. The DOM storage system can also delete its 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data, since no session restore will happen at a later point in time. 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext::GetDefaultStoragePartition(profile_)-> 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDOMStorageContext()->StartScavengingUnusedSessionStorage(); 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FinishedTabCreation(false, false); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-CreatingTabs-Start", false); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTabCreation(); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After the for loop this contains the last TABBED_BROWSER. Is null if no 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tabbed browsers exist. 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* last_browser = NULL; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_tabbed_browser = false; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After the for loop, this contains the browser to activate, if one of the 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // windows has the same id as specified in active_window_id. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser_to_activate = NULL; 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_tab_to_activate = -1; 81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determine if there is a visible window. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_visible_browser = false; 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SessionWindow*>::iterator i = windows->begin(); 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != windows->end(); ++i) { 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->show_state != ui::SHOW_STATE_MINIMIZED) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_visible_browser = true; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<SessionWindow*>::iterator i = windows->begin(); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != windows->end(); ++i) { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser = NULL; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_tabbed_browser && (*i)->type == Browser::TYPE_TABBED) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_tabbed_browser = true; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == windows->begin() && (*i)->type == Browser::TYPE_TABBED && 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_ && browser_->is_type_tabbed() && 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !browser_->profile()->IsOffTheRecord()) { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first set of tabs is added to the existing browser. 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser = browser_; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-CreateRestoredBrowser-Start", false); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Show the first window if none are visible. 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::WindowShowState show_state = (*i)->show_state; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!has_visible_browser) { 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_state = ui::SHOW_STATE_NORMAL; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) has_visible_browser = true; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser = NULL; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (win8::IsSingleWindowMetroMode()) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't want to add tabs to the off the record browser. 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_ && !browser_->profile()->IsOffTheRecord()) { 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser = browser_; 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser = last_browser; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // last_browser should never be off the record either. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't set browser higher above when browser_ is offtherecord, 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and CreateRestoredBrowser below, is never created offtherecord. 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!browser || !browser->profile()->IsOffTheRecord()); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Metro should only have tabbed browsers. 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It never creates any non-tabbed browser, and thus should never 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // restore non-tabbed items... 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!browser || browser->is_type_tabbed()); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK((*i)->type == Browser::TYPE_TABBED); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser = CreateRestoredBrowser( 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<Browser::Type>((*i)->type), 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->bounds, 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_state, 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->app_name); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-CreateRestoredBrowser-End", false); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->type == Browser::TYPE_TABBED) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_browser = browser; 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* active_tab = 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int initial_tab_count = browser->tab_strip_model()->count(); 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool close_active_tab = clobber_existing_tab_ && 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) i == windows->begin() && 88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (*i)->type == Browser::TYPE_TABBED && 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) active_tab && browser == browser_ && 88390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (*i)->tabs.size() > 0; 88490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (close_active_tab) 88590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) --initial_tab_count; 88690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int selected_tab_index = 88790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) initial_tab_count > 0 ? browser->tab_strip_model()->active_index() 88890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : std::max(0, 88990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::min((*i)->selected_tab_index, 89090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<int>((*i)->tabs.size()) - 1)); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->window_id.id() == active_window_id) { 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_to_activate = browser; 89390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_tab_to_activate = selected_tab_index; 89590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 89790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RestoreTabsToBrowser(*(*i), browser, initial_tab_count, 89890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) selected_tab_index); 89990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NotifySessionServiceOfRestoredTabs(browser, initial_tab_count); 90090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This needs to be done after restore because closing the last tab will 90190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // close the whole window. 90290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (close_active_tab) 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::CloseWebContents(browser, active_tab, true); 90490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_tab_to_activate = -1; 90690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_to_activate && browser_to_activate->is_type_tabbed()) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_browser = browser_to_activate; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_browser && !urls_to_open_.empty()) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppendURLsToBrowser(last_browser, urls_to_open_); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-CreatingTabs-End", false); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_to_activate) { 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_to_activate->window()->Activate(); 92090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_WIN) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Win8 Metro, we merge all browsers together, so if we need to 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // activate one of the previously separated window, we need to activate 92390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the tab. Also, selected_tab_to_activate can be -1 if we clobbered the 92490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tab that would have been activated. 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In that case we'll leave activation to last tab. 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The only current usage of clobber is for crash recovery, so it's fine. 92790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (win8::IsSingleWindowMetroMode() && selected_tab_to_activate != -1) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowBrowser(browser_to_activate, selected_tab_to_activate); 92990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If last_browser is NULL and urls_to_open_ is non-empty, 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FinishedTabCreation will create a new TabbedBrowser and add the urls to 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it. 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* finished_browser = FinishedTabCreation(true, has_tabbed_browser); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (finished_browser) 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_browser = finished_browser; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sessionStorages needed for the session restore have now been recreated 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by RestoreTab. Now it's safe for the DOM storage system to start 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleting leftover data. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext::GetDefaultStoragePartition(profile_)-> 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDOMStorageContext()->StartScavengingUnusedSessionStorage(); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return last_browser; 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Record an app launch event (if appropriate) for a tab which is about to 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be restored. Callers should ensure that selected_index is within the 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bounds of tab.navigations before calling. 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RecordAppLaunchForTab(Browser* browser, 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionTab& tab, 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_index) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(selected_index >= 0 && 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_index < static_cast<int>(tab.navigations.size())); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = tab.navigations[selected_index].virtual_url(); 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser->profile()->GetExtensionService()) { 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension* extension = 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->profile()->GetExtensionService()->GetInstalledApp(url); 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) { 960558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CoreAppLauncherHandler::RecordAppLaunchType( 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::APP_LAUNCH_SESSION_RESTORE, 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType()); 9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 96790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Adds the tabs from |window| to |browser|. Normal tabs go after the existing 96890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tabs but pinned tabs will be pushed in front. 96990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If there are no existing tabs, the tab at |selected_tab_index| will be 97090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // selected. Otherwise, the tab selection will remain untouched. 97190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void RestoreTabsToBrowser(const SessionWindow& window, 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 97390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int initial_tab_count, 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_tab_index) { 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "RestoreTabsToBrowser " << window.tabs.size(); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!window.tabs.empty()); 97790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (initial_tab_count == 0) { 97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < static_cast<int>(window.tabs.size()); ++i) { 97990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SessionTab& tab = *(window.tabs[i]); 98090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Loads are scheduled for each restored tab unless the tab is going to 98190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // be selected as ShowBrowser() will load the selected tab. 98290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (i == selected_tab_index) { 98390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ShowBrowser(browser, 98490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser->tab_strip_model()->GetIndexOfWebContents( 98590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RestoreTab(tab, i, browser, false))); 98690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tab_loader_->TabIsLoading( 98790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &browser->tab_strip_model()->GetActiveWebContents()-> 98890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetController()); 98990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 99090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RestoreTab(tab, i, browser, true); 99190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 99290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 99390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 99490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If the browser already has tabs, we want to restore the new ones after 99590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the existing ones. E.g. this happens in Win8 Metro where we merge 99690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // windows or when launching a hosted app from the app launcher. 99790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int tab_index_offset = initial_tab_count; 99890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int i = 0; i < static_cast<int>(window.tabs.size()); ++i) { 99990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SessionTab& tab = *(window.tabs[i]); 100090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Always schedule loads as we will not be calling ShowBrowser(). 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestoreTab(tab, tab_index_offset + i, browser, true); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |tab_index| is ignored for pinned tabs which will always be pushed behind 100790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the last existing pinned tab. 100890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |schedule_load| will let |tab_loader_| know that it should schedule this 100990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // tab for loading. 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* RestoreTab(const SessionTab& tab, 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int tab_index, 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool schedule_load) { 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible (particularly for foreign sessions) to receive a tab 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without valid navigations. In that case, just skip it. 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See crbug.com/154129. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab.navigations.empty()) 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_index = tab.current_navigation_index; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_index = std::max( 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(selected_index, 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(tab.navigations.size() - 1))); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunchForTab(browser, tab, selected_index); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Associate sessionStorage (if any) to the restored tab. 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<content::SessionStorageNamespace> session_storage_namespace; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab.session_storage_persistent_id.empty()) { 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_storage_namespace = 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserContext::GetDefaultStoragePartition(profile_)-> 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDOMStorageContext()->RecreateSessionStorage( 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.session_storage_persistent_id); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::AddRestoredTab(browser, 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.navigations, 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index, 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_index, 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.extension_app_id, 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false, // select 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.pinned, 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) session_storage_namespace.get(), 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab.user_agent_override); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Regression check: check that the tab didn't start loading right away. The 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focused tab will be loaded by Browser, and TabLoader will load the rest. 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents->GetController().NeedsReload()); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the file access rights for the selected navigation entry. 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int id = web_contents->GetRenderProcessHost()->GetID(); 105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const content::PageState& page_state = 105490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tab.navigations.at(selected_index).page_state(); 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<base::FilePath>& file_paths = 105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) page_state.GetReferencedFiles(); 10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<base::FilePath>::const_iterator file = file_paths.begin(); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file != file_paths.end(); ++file) { 10597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch content::ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(id, 10607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *file); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (schedule_load) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_loader_->ScheduleLoad(&web_contents->GetController()); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return web_contents; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* CreateRestoredBrowser(Browser::Type type, 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds, 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::WindowShowState show_state, 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& app_name) { 10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser::CreateParams params(type, profile_, host_desktop_type_); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.app_name = app_name; 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.initial_bounds = bounds; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.initial_show_state = show_state; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.is_session_restore = true; 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new Browser(params); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ShowBrowser(Browser* browser, int selected_tab_index) { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(browser->tab_strip_model()->count()); 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->ActivateTabAt(selected_tab_index, true); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_ == browser) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent the auto window management for this window on show. 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ash::wm::SetUserHasChangedWindowPositionOrSize( 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->GetNativeWindow(), true); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Show(); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ash::wm::SetUserHasChangedWindowPositionOrSize( 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->GetNativeWindow(), false); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->set_is_session_restore(false); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jcampan): http://crbug.com/8123 we should not need to set the 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initial focus explicitly. 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents()-> 11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetView()->SetInitialFocus(); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_shown_) { 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_shown_ = true; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_to_first_show = 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - restore_started_; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore.TimeToFirstShow", 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_to_first_show, 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(1000), 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Appends the urls in |urls| to |browser|. 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AppendURLsToBrowser(Browser* browser, 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<GURL>& urls) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < urls.size(); ++i) { 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int add_types = TabStripModel::ADD_FORCE_INDEX; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == 0) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_types |= TabStripModel::ADD_ACTIVE; 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NavigateParams params(browser, urls[i], 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_AUTO_TOPLEVEL); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = i == 0 ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.tabstrip_add_types = add_types; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invokes TabRestored on the SessionService for all tabs in browser after 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initial_count. 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifySessionServiceOfRestoredTabs(Browser* browser, int initial_count) { 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionService* session_service = 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionServiceFactory::GetForProfile(profile_); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!session_service) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = initial_count; i < tab_strip->count(); ++i) 11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_service->TabRestored(tab_strip->GetWebContentsAt(i), 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip->IsTabPinned(i)); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The profile to create the sessions for. 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile_; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first browser to restore to, may be null. 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser_; 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The desktop on which all new browsers should be created (browser_, if it is 11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // not NULL, must be of this desktop type as well). 11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type_; 11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether or not restore is synchronous. 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool synchronous_; 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See description of CLOBBER_CURRENT_TAB. 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool clobber_existing_tab_; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true and there is an error or there are no windows to restore, we 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // create a tabbed browser anyway. This is used on startup to make sure at 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at least one window is created. 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool always_create_tabbed_browser_; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set of URLs to open in addition to those restored from the session. 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> urls_to_open_; 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to get the session. 11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CancelableTaskTracker cancelable_task_tracker_; 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Responsible for loading the tabs. 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TabLoader> tab_loader_; 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When synchronous we run a nested message loop. To avoid creating windows 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the nested message loop (which can make exiting the nested message 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loop take a while) we cache the SessionWindows here and create the actual 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // windows when the nested message loop exits. 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SessionWindow*> windows_; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type active_window_id_; 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time we started the restore. 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks restore_started_; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to true after the first browser is shown. 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool browser_shown_; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SessionRestoreImpl); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SessionRestore ------------------------------------------------------------- 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Browser* SessionRestore::RestoreSession( 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile, 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser, 12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 behavior, 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<GURL>& urls_to_open) { 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chromeos::BootTimesLoader::Get()->AddLoginTimeMarker( 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SessionRestore-Start", false); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always restore from the original profile (incognito profiles have no 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // session service). 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile = profile->GetOriginalProfile(); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SessionServiceFactory::GetForProfile(profile)) { 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->set_restored_last_session(true); 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SessionRestoreImpl takes care of deleting itself when done. 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionRestoreImpl* restorer = new SessionRestoreImpl( 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile, browser, host_desktop_type, (behavior & SYNCHRONOUS) != 0, 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (behavior & CLOBBER_CURRENT_TAB) != 0, 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (behavior & ALWAYS_CREATE_TABBED_BROWSER) != 0, 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urls_to_open); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return restorer->Restore(); 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 12283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::vector<Browser*> SessionRestore::RestoreForeignSessionWindows( 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const SessionWindow*>::const_iterator begin, 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const SessionWindow*>::const_iterator end) { 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> gurls; 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionRestoreImpl restorer(profile, 12352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<Browser*>(NULL), host_desktop_type, true, false, true, gurls); 12363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return restorer.RestoreForeignSession(begin, end); 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 12403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochWebContents* SessionRestore::RestoreForeignSessionTab( 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* source_web_contents, 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SessionTab& tab, 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition) { 12442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(source_web_contents); 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = browser->profile(); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<GURL> gurls; 12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SessionRestoreImpl restorer(profile, browser, browser->host_desktop_type(), 12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, false, false, gurls); 12493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return restorer.RestoreForeignTab(tab, disposition); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SessionRestore::IsRestoring(const Profile* profile) { 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (active_session_restorers == NULL) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<SessionRestoreImpl*>::const_iterator it = 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_session_restorers->begin(); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != active_session_restorers->end(); ++it) { 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->profile() == profile) 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SessionRestore::IsRestoringSynchronously() { 12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!active_session_restorers) 12682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 12692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<SessionRestoreImpl*>::const_iterator it = 12702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_session_restorers->begin(); 12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != active_session_restorers->end(); ++it) { 12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*it)->synchronous()) 12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1277