File: tab_lifecycle_unit.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (200 lines) | stat: -rw-r--r-- 8,721 bytes parent folder | download | duplicates (5)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright 2017 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_LIFECYCLE_UNIT_H_
#define CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_

#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "chrome/browser/resource_coordinator/lifecycle_unit_base.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h"
#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h"
#include "chrome/browser/resource_coordinator/time.h"
#include "components/performance_manager/public/mojom/lifecycle.mojom-forward.h"
#include "content/public/browser/visibility.h"
#include "content/public/browser/web_contents_observer.h"

class TabStripModel;

namespace content {
class WebContents;
}  // namespace content

namespace resource_coordinator {

// Time during which backgrounded tabs are protected from urgent discarding
// (not on ChromeOS).
inline constexpr base::TimeDelta kBackgroundUrgentProtectionTime =
    base::Minutes(10);

// Time during which a tab cannot be discarded after having played audio.
inline constexpr base::TimeDelta kTabAudioProtectionTime = base::Minutes(1);

// Represents a tab.
class TabLifecycleUnitSource::TabLifecycleUnit
    : public LifecycleUnitBase,
      public TabLifecycleUnitExternal,
      public content::WebContentsObserver {
 public:
  // |observers| is a list of observers to notify when the discarded state or
  // the auto-discardable state of this tab changes. It can be modified outside
  // of this TabLifecycleUnit, but only on the sequence on which this
  // constructor is invoked. |web_contents| and |tab_strip_model| are the
  // WebContents and TabStripModel associated with this tab. The |source| is
  // optional and may be nullptr.
  TabLifecycleUnit(TabLifecycleUnitSource* source,
                   content::WebContents* web_contents,
                   TabStripModel* tab_strip_model);

  TabLifecycleUnit(const TabLifecycleUnit&) = delete;
  TabLifecycleUnit& operator=(const TabLifecycleUnit&) = delete;

  ~TabLifecycleUnit() override;

  // Sets the TabStripModel associated with this tab. The source that created
  // this TabLifecycleUnit is responsible for calling this when the tab is
  // removed from a TabStripModel or inserted into a new TabStripModel.
  void SetTabStripModel(TabStripModel* tab_strip_model);

  // Sets the WebContents associated with this tab. The source that created this
  // TabLifecycleUnit is responsible for calling this when the tab's WebContents
  // changes (e.g. when the tab is discarded or when prerendered or distilled
  // content is displayed).
  void SetWebContents(content::WebContents* web_contents);

  // Invoked when the tab gains or loses focus.
  void SetFocused(bool focused);

  // Sets the "recently audible" state of this tab. A tab is "recently audible"
  // if a speaker icon is displayed next to it in the tab strip. The source that
  // created this TabLifecycleUnit is responsible for calling this when the
  // "recently audible" state of the tab changes.
  void SetRecentlyAudible(bool recently_audible);

  // Updates the tab's lifecycle state when changed outside the tab
  // lifecycle unit.
  void UpdateLifecycleState(performance_manager::mojom::LifecycleState state);

  // LifecycleUnit:
  TabLifecycleUnitExternal* AsTabLifecycleUnitExternal() override;
  base::TimeTicks GetLastFocusedTimeTicks() const override;
  SortKey GetSortKey() const override;
  LifecycleUnitLoadingState GetLoadingState() const override;
  bool Load() override;
  bool CanDiscard(LifecycleUnitDiscardReason reason,
                  DecisionDetails* decision_details) const override;
  LifecycleUnitDiscardReason GetDiscardReason() const override;
  bool Discard(LifecycleUnitDiscardReason discard_reason,
               uint64_t memory_footprint_estimate) override;

  // TabLifecycleUnitExternal:
  content::WebContents* GetWebContents() const override;
  bool IsAutoDiscardable() const override;
  void SetAutoDiscardable(bool auto_discardable) override;
  bool DiscardTab(mojom::LifecycleUnitDiscardReason reason,
                  uint64_t memory_footprint_estimate) override;
  mojom::LifecycleUnitState GetTabState() const override;

  // LifecycleUnit and TabLifecycleUnitExternal:
  base::Time GetLastFocusedTime() const override;

  base::TimeTicks GetWallTimeWhenHiddenForTesting() const {
    return wall_time_when_hidden_;
  }

 protected:
  friend class TabManagerTest;

  // TabLifecycleUnitSource needs to update the state when a external lifecycle
  // state change is observed.
  friend class TabLifecycleUnitSource;

 private:
  void RecomputeLifecycleUnitState(LifecycleUnitStateChangeReason reason);

  // Same as GetSource, but cast to the most derived type.
  TabLifecycleUnitSource* GetTabSource() const;

  // Updates |decision_details| based on media usage by the tab.
  void CheckMediaUsage(DecisionDetails* decision_details) const;

  // Creates or updates the existing PreDiscardResourceUsage tab helper for the
  // tab's `web_contents` with `discard_reason` and
  // `tab_resident_set_size_estimate`.
  void UpdatePreDiscardResourceUsage(content::WebContents* web_contents,
                                     LifecycleUnitDiscardReason discard_reason,
                                     uint64_t tab_resident_set_size_estimate);

  // Finishes a tab discard, invoked by Discard().
  void FinishDiscard(LifecycleUnitDiscardReason discard_reason,
                     uint64_t tab_resident_set_size_estimate);

  // Finishes a tab discard and preserves the associated web contents. Used only
  // when kWebContentsDiscard is enabled.
  void FinishDiscardAndPreserveWebContents(
      LifecycleUnitDiscardReason discard_reason,
      uint64_t tab_resident_set_size_estimate);

  // Attempts to fast kill the process hosting the main frame of `web_contents`
  // if only hosting the main frame.
  void AttemptFastKillForDiscard(content::WebContents* web_contents,
                                 LifecycleUnitDiscardReason discard_reason);

  // content::WebContentsObserver:
  void DidStartLoading() override;
  void OnVisibilityChanged(content::Visibility visibility) override;

  // Updates |decision_details| based on device usage by the tab (USB or
  // Bluetooth).
  void CheckDeviceUsage(DecisionDetails* decision_details) const;

  // TabStripModel to which this tab belongs.
  raw_ptr<TabStripModel, DanglingUntriaged> tab_strip_model_;

  // Last time ticks at which this tab was focused, or TimeTicks::Max() if it is
  // currently focused. For tabs that aren't currently focused this is
  // initialized using WebContents::GetLastActiveTimeTicks, which causes use
  // times from previous browsing sessions to persist across session restore
  // events.
  // TODO(chrisha): Migrate |last_active_time| to actually track focus time,
  // instead of the time that focus was lost. This is a more meaninful number
  // for all of the clients of |last_active_time|.
  base::TimeTicks last_focused_time_ticks_;

  // Last time ticks at which this tab was focused, or Time::Max() if it is
  // currently focused. For tabs that aren't currently focused this is
  // initialized using WebContents::GetLastActiveTime, which causes use times
  // from previous browsing sessions to persist across session restore
  // events.
  base::Time last_focused_time_;

  // When this is false, CanDiscard() always returns false.
  bool auto_discardable_ = true;

  // Maintains the most recent LifecycleUnitDiscardReason that was passed into
  // Discard().
  LifecycleUnitDiscardReason discard_reason_ =
      LifecycleUnitDiscardReason::EXTERNAL;

  // TimeTicks::Max() if the tab is currently "recently audible", null
  // TimeTicks() if the tab was never "recently audible", last time at which the
  // tab was "recently audible" otherwise.
  base::TimeTicks recently_audible_time_;

  // The wall time when this LifecycleUnit was last hidden, or TimeDelta::Max()
  // if this LifecycleUnit is currently visible.
  base::TimeTicks wall_time_when_hidden_;

  // `page_lifecycle_state_` is the lifecycle state of the associated `PageNode`
  // (`kFrozen` if all frames are frozen, `kActive` otherwise). `is_discarded_`
  // indicates whether the tab is discarded. Together, these properties fully
  // determine the `LifecycleUnitState`.
  performance_manager::mojom::LifecycleState page_lifecycle_state_ =
      performance_manager::mojom::LifecycleState::kRunning;
  bool is_discarded_ = false;
};

}  // namespace resource_coordinator

#endif  // CHROME_BROWSER_RESOURCE_COORDINATOR_TAB_LIFECYCLE_UNIT_H_