1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/functional/callback_helpers.h"
#include "base/gtest_prod_util.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit_observer.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit_source_observer.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit_state.mojom-forward.h"
#include "chrome/browser/resource_coordinator/tab_manager_features.h"
#include "chrome/browser/sessions/session_restore_observer.h"
#include "content/public/browser/navigation_throttle.h"
class GURL;
namespace content {
class WebContents;
} // namespace content
namespace resource_coordinator {
// TabManager is responsible for triggering tab lifecycle state transitions.
//
// Note that the browser tests are only active for platforms that use
// TabManager (CrOS only for now) and need to be adjusted accordingly if
// support for new platforms is added.
//
// Tabs are identified by a unique ID vended by this component. These IDs are
// not reused in a session. They are stable for a given conceptual tab, and will
// follow it through discards, reloads, tab strip operations, etc.
//
// TODO(fdoray): Rename to LifecycleManager. https://crbug.com/775644
class TabManager : public LifecycleUnitObserver,
public LifecycleUnitSourceObserver {
public:
// Forward declaration of resource coordinator signal observer.
class ResourceCoordinatorSignalObserver;
using TabDiscardDoneCB = base::ScopedClosureRunner;
TabManager();
TabManager(const TabManager&) = delete;
TabManager& operator=(const TabManager&) = delete;
~TabManager() override;
// Start the Tab Manager.
void Start();
// Returns the LifecycleUnits managed by this, sorted from less to most
// important to the user. It is unsafe to access a pointer in the returned
// vector after a LifecycleUnit has been destroyed.
LifecycleUnitVector GetSortedLifecycleUnits();
// Method used by the extensions API to discard tabs. If |contents| is null,
// discards the least important tab using DiscardTab(). Otherwise discards
// the given contents. Returns the new web_contents or null if no tab
// was discarded.
content::WebContents* DiscardTabByExtension(content::WebContents* contents);
private:
friend class TabManagerStatsCollectorTest;
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, AutoDiscardable);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, CanOnlyDiscardOnce);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ChildProcessNotifications);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, EnablePageAlmostIdleSignal);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, InvalidOrEmptyURL);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabDiscardDoneCallback);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, IsInternalPage);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, IsTabRestoredInForeground);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, OomPressureListener);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectDevToolsTabsFromDiscarding);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectPDFPages);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest,
ProtectRecentlyUsedTabsFromUrgentDiscarding);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, ProtectVideoTabs);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerBasics);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, TabManagerWasDiscarded);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest,
TabManagerWasDiscardedCrossSiteSubFrame);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest,
TrackingNumberOfLoadedLifecycleUnits);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, UrgentFastShutdownSharedTabProcess);
FRIEND_TEST_ALL_PREFIXES(TabManagerTestWithTwoTabs,
UrgentFastShutdownSingleTabProcess);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest,
UrgentFastShutdownWithBeforeunloadHandler);
FRIEND_TEST_ALL_PREFIXES(TabManagerTest, UrgentFastShutdownWithUnloadHandler);
// Returns true if the |url| represents an internal Chrome web UI page that
// can be easily reloaded and hence makes a good choice to discard.
static bool IsInternalPage(const GURL& url);
// Discards the less important LifecycleUnit that supports discarding under
// |reason|.
content::WebContents* DiscardTabImpl(
LifecycleUnitDiscardReason reason,
TabDiscardDoneCB tab_discard_done = TabDiscardDoneCB(base::DoNothing()));
void OnSessionRestoreStartedLoadingTabs();
void OnSessionRestoreFinishedLoadingTabs();
// Returns the number of tabs that are not pending load or discarded.
int GetNumAliveTabs() const;
// LifecycleUnitObserver:
void OnLifecycleUnitDestroyed(LifecycleUnit* lifecycle_unit) override;
// LifecycleUnitSourceObserver:
void OnLifecycleUnitCreated(LifecycleUnit* lifecycle_unit) override;
// LifecycleUnits managed by this.
LifecycleUnitSet lifecycle_units_;
// A listener to global memory pressure events.
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
// Weak pointer factory used for posting delayed tasks.
base::WeakPtrFactory<TabManager> weak_ptr_factory_{this};
};
} // namespace resource_coordinator
#endif // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_MANAGER_H_
|