File: navigation_entry_screenshot_manager.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (137 lines) | stat: -rw-r--r-- 5,471 bytes parent folder | download | duplicates (4)
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
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_TRANSITIONS_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_
#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_TRANSITIONS_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_

#include "base/containers/lru_cache.h"
#include "base/gtest_prod_util.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/safe_ref.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/content_export.h"
#include "ui/display/display_observer.h"

namespace display {
class Display;
}

namespace content {

class NavigationEntryScreenshotCacheEvictor;

// This class manages the metadata for all `NavigationEntryScreenshot`s captured
// for the backward and forward navigation entries per `FrameTree`. The
// screenshots are used to present users with previews of the previous pages
// when the users initiate back/forward-navigations. This class is owned by a
// `BrowserContext`. All primary `FrameTree`s sharing the same `BrowserContext`
// share the same manager. The manager should only be accessed by the
// `NavigationEntryScreenshotCache` and tests.
class CONTENT_EXPORT NavigationEntryScreenshotManager
    : public display::DisplayObserver {
 public:
  NavigationEntryScreenshotManager();
  NavigationEntryScreenshotManager(const NavigationEntryScreenshotManager&) =
      delete;
  NavigationEntryScreenshotManager& operator=(
      const NavigationEntryScreenshotManager&) = delete;
  ~NavigationEntryScreenshotManager() override;

  void OnDisplayAdded(const display::Display&) override;
  void OnDisplaysRemoved(const display::Displays&) override;
  void OnDisplayMetricsChanged(const display::Display&,
                               uint32_t metrics_changed) override;

  // Called when a screenshot is stashed into a `NavigationEntry`, or when a
  // screenshot is removed from the entry (for preview, or during the
  // destruction of the entry).
  void OnScreenshotCached(NavigationEntryScreenshotCacheEvictor* cache,
                          size_t size);
  void OnScreenshotRemoved(NavigationEntryScreenshotCacheEvictor* cache,
                           size_t size);
  void OnScreenshotCompressed(NavigationEntryScreenshotCacheEvictor* cache,
                              size_t old_size,
                              size_t new_size);
  void OnVisibilityChanged(NavigationEntryScreenshotCacheEvictor* cache);

  bool IsEmpty() const;

  // Returns the current time. Allows overriding for tests.
  base::TimeTicks Now() const;

  size_t GetCurrentCacheSize() const { return current_cache_size_in_bytes_; }
  size_t GetMaxCacheSize() const { return max_cache_size_in_bytes_; }

  // Allow tests to customize memory budget.
  void SetMemoryBudgetForTesting(size_t size) {
    max_cache_size_in_bytes_ = size;
  }
  void SetUITaskRunnerForTesting(
      scoped_refptr<base::SequencedTaskRunner> task_runner) {
    cleanup_task_.SetTaskRunner(std::move(task_runner));
  }
  void set_tick_clock_for_testing(base::TickClock* clock) {
    tick_clock_ = clock;
  }

  base::SafeRef<NavigationEntryScreenshotManager> GetSafeRef() const {
    return weak_factory_.GetSafeRef();
  }

 private:
  void RecalculateCacheSize();

  // Called when the first screenshot is cached into `cache`, and when the last
  // screenshot is removed from `cache`.
  void Register(NavigationEntryScreenshotCacheEvictor* cache);
  void Unregister(NavigationEntryScreenshotCacheEvictor* cache);

  void ScheduleCleanup(base::TimeTicks last_visible_time);
  void RunCleanup();

  // Called at the end of `OnScreenshotCached`.
  void EvictIfOutOfMemoryBudget();

  // Used by `listener_`. When the system memory is under critical pressure, all
  // screenshots under this `Profile` are purged.
  void OnMemoryPressure(
      base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
  FRIEND_TEST_ALL_PREFIXES(NavigationEntryScreenshotCacheTest,
                           OnMemoryPressureCritical);

  // Schedules recording the cache size in time intervals based on a Poisson
  // distribution.
  void RecordScreenshotCacheSizeAfterDelay();

  // Records memory usage by the captured screenshots and calls
  // `RecordScreenshotCacheSizeAfterDelay` to continue recording the memory
  // periodically.
  void RecordScreenshotCacheSize();

  size_t max_cache_size_in_bytes_;
  size_t current_cache_size_in_bytes_ = 0U;

  // The `listener_` monitors the system memory pressure, and calls
  // `NavigationEntryScreenshotManager::OnMemoryPressure` when the system
  // memory pressure level changes.
  std::unique_ptr<base::MemoryPressureListener> listener_;

  // The most recently used cache is stored at the front of the
  // `base::LRUCacheSet`. A limited interface to the tab's cache is used so that
  // this BrowserContext-wide manager does not have access to details like URLs
  // or pixels within each tab.
  base::LRUCacheSet<NavigationEntryScreenshotCacheEvictor*> managed_caches_;

  raw_ptr<const base::TickClock> tick_clock_;
  base::OneShotTimer cleanup_task_;
  const base::TimeDelta cleanup_delay_;

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<NavigationEntryScreenshotManager> weak_factory_{this};
};
}  // namespace content

#endif  // CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_TRANSITIONS_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_