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
content / browser / renderer_host / navigation_transitions / navigation_entry_screenshot.h [blame]
// 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_H_
#define CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_TRANSITIONS_NAVIGATION_ENTRY_SCREENSHOT_H_
#include "base/supports_user_data.h"
#include "cc/resources/ui_resource_bitmap.h"
#include "cc/resources/ui_resource_client.h"
#include "content/common/content_export.h"
class SkBitmap;
namespace content {
class NavigationEntryScreenshotCache;
// Wraps around a `cc::UIResourceBitmap`, which is used to show the user a
// preview of the previous page. This class is stored as user data on
// `NavigationEntry`.
//
// The screenshot is captured for the leaving page when the navigation is about
// to commit (see `CommitDeferringCondition`), subsequently stashed into the
// `NavigationEntry` that this screenshot is captured for. The capture is done
// in the browser process. The pixel data includes sensitive cross-origin data,
// so it must never be leaked to a renderer process.
//
// The screenshot is taken out of the `NavigationEntry` when it will be used for
// an animated transition for a gestured navigation.
// - If the screenshot ends up being used, or deemed invalid (i.e. mismatches
// with the current viewport size) for a preview, the caller is responsible
// for destroying the screenshot.
// - If the screenshot is not used for a preview but still valid (e.g. user
// gesture cancels the animation thus no navigation, or the user initiates a
// gesture to go back to multiple entries), the caller is responsible for
// putting the screenshot back into the `NavigationEntryScreenshotCache`.
//
// If the user clears the navigation history, the screenshot is deleted when
// its owning `NavigationEntry` is destroyed. The screenshot is never recreated
// or cloned even when its `NavigationEntry` is cloned (tab clone) or restored
// (i.e., by restoring the last closed tab), because
// `base::SupportsUserData::Data::Clone()` is not implemented by
// `NavigationEntryScreenshot`.
class CONTENT_EXPORT NavigationEntryScreenshot
: public cc::UIResourceClient,
public base::SupportsUserData::Data {
public:
const static void* const kUserDataKey;
static void SetDisableCompressionForTesting(bool disable);
NavigationEntryScreenshot(const SkBitmap& bitmap,
int navigation_entry_id,
bool supports_etc_non_power_of_two);
NavigationEntryScreenshot(const NavigationEntryScreenshot&) = delete;
NavigationEntryScreenshot& operator=(const NavigationEntryScreenshot&) =
delete;
~NavigationEntryScreenshot() override;
// `cc::UIResourceClient`:
cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid,
bool resource_lost) override;
// Sets the `cache` managing the memory for this screenshot. When set, the
// screenshot is stored on its associated NavigationEntry and is guaranteed to
// not be displayed in the UI.
//
// Returns the memory occupied by the bitmap in bytes.
size_t SetCache(NavigationEntryScreenshotCache* cache);
// Returns true if the screenshot is being managed by a cache. This is not the
// case when it's being displayed in the UI.
bool is_cached() const { return cache_ != nullptr; }
// Returns the bounds of the uncompressed bitmap.
gfx::Size dimensions_without_compression() const {
return dimensions_without_compression_;
}
int navigation_entry_id() const { return navigation_entry_id_; }
SkBitmap GetBitmapForTesting() const;
size_t CompressedSizeForTesting() const;
private:
void OnCompressionFinished(sk_sp<SkPixelRef> compressed_bitmap);
void StartCompression(const SkBitmap& bitmap,
bool supports_etc_non_power_of_two);
const cc::UIResourceBitmap& GetBitmap() const;
// The uncompressed bitmap cached when navigating away from this navigation
// entry.
std::optional<cc::UIResourceBitmap> bitmap_;
// The compressed bitmap generated on a worker thread. `bitmap_` is discarded
// when the compressed bitmap is available and this screenshot is no longer
// being displayed in the UI.
std::optional<cc::UIResourceBitmap> compressed_bitmap_;
// Set if this screenshot is being tracked by the `cache_`. The cache is
// guaranteed to outlive the screenshot, if the screenshot is tracked.
//
// Since `this` is never restored/cloned (unlike its owning `NavigationEntry`,
// per the class-level comments), we will never have a screenshot tracked in a
// cache from a different `NavigationController`.
raw_ptr<NavigationEntryScreenshotCache> cache_ = nullptr;
// This screenshot is cached for the navigation entry of
// `navigation_entry_id_`.
const int navigation_entry_id_;
const gfx::Size dimensions_without_compression_;
base::WeakPtrFactory<NavigationEntryScreenshot> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_NAVIGATION_TRANSITIONS_NAVIGATION_ENTRY_SCREENSHOT_H_