File: offscreen_tab.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 (181 lines) | stat: -rw-r--r-- 7,424 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
// Copyright 2015 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_MEDIA_OFFSCREEN_TAB_H_
#define CHROME_BROWSER_MEDIA_OFFSCREEN_TAB_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/gfx/geometry/size.h"

namespace media_router {
class NavigationPolicy;
}  // namespace media_router

namespace content {
class BrowserContext;
}  // namespace content

// Owns and controls a sandboxed WebContents instance hosting the rendering
// engine for an offscreen tab.  Since the offscreen tab does not interact with
// the user in any direct way, the WebContents is not attached to any Browser
// window/UI, and any input and focusing capabilities are blocked.
//
// An OffscreenTab instance is shut down one of the three ways:
//
//   1. When WebContents::IsBeingCaptured() returns false, indicating there are
//      no more consumers of its captured content (e.g., when all MediaStreams
//      have been closed).  OffscreenTab will auto-detect this case and
//      self-destruct.
//   2. By the renderer, where the WebContents implementation will invoke the
//      WebContentsDelegate::CloseContents() override.  This occurs, for
//      example, when a page calls window.close().
//   3. Automatically, when the associated profile is destroyed.
//
// This class operates exclusively on the UI thread and so is not thread-safe.
class OffscreenTab final : public ProfileObserver,
                           protected content::WebContentsDelegate,
                           protected content::WebContentsObserver {
 public:
  // TODO(crbug.com/40781745): Hold the OffscreenTab by a WeakPtr, then Owner
  // can be deleted.
  class Owner {
   public:
    virtual ~Owner() = default;

    // |tab| is no longer valid after this call.
    virtual void DestroyTab(OffscreenTab* tab) = 0;
  };

  OffscreenTab(Owner* owner, content::BrowserContext* context);

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

  ~OffscreenTab() final;

  // The WebContents instance hosting the rendering engine for this
  // OffscreenTab.
  content::WebContents* web_contents() const {
    return offscreen_tab_web_contents_.get();
  }

  // Creates the WebContents instance containing the offscreen tab's page,
  // configures it for offscreen rendering at the given |initial_size|, and
  // navigates it to |start_url|.  This is invoked once after construction.
  void Start(const GURL& start_url,
             const gfx::Size& initial_size,
             const std::string& optional_presentation_id);

  // Closes the underlying WebContents.
  void Close();

 private:
#if defined(USE_AURA)
  class WindowAdoptionAgent;
#endif  // defined(USE_AURA)

  // content::WebContentsDelegate overrides to provide the desired behaviors.
  void CloseContents(content::WebContents* source) final;
  bool ShouldSuppressDialogs(content::WebContents* source) final;
  bool ShouldFocusLocationBarByDefault(content::WebContents* source) final;
  bool ShouldFocusPageAfterCrash(content::WebContents* source) final;
  void CanDownload(const GURL& url,
                   const std::string& request_method,
                   base::OnceCallback<void(bool)> callback) final;
  bool HandleContextMenu(content::RenderFrameHost& render_frame_host,
                         const content::ContextMenuParams& params) final;
  content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
      content::WebContents* source,
      const input::NativeWebKeyboardEvent& event) final;
  bool PreHandleGestureEvent(content::WebContents* source,
                             const blink::WebGestureEvent& event) final;
  bool CanDragEnter(content::WebContents* source,
                    const content::DropData& data,
                    blink::DragOperationsMask operations_allowed) final;
  bool IsWebContentsCreationOverridden(
      content::RenderFrameHost* opener,
      content::SiteInstance* source_site_instance,
      content::mojom::WindowContainerType window_container_type,
      const GURL& opener_url,
      const std::string& frame_name,
      const GURL& target_url) final;
  void EnterFullscreenModeForTab(
      content::RenderFrameHost* requesting_frame,
      const blink::mojom::FullscreenOptions& options) final;
  void ExitFullscreenModeForTab(content::WebContents* contents) final;
  bool IsFullscreenForTabOrPending(const content::WebContents* contents) final;
  blink::mojom::DisplayMode GetDisplayMode(
      const content::WebContents* contents) final;
  void RequestMediaAccessPermission(
      content::WebContents* contents,
      const content::MediaStreamRequest& request,
      content::MediaResponseCallback callback) final;
  bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
                                  const url::Origin& security_origin,
                                  blink::mojom::MediaStreamType type) final;

  // content::WebContentsObserver overrides
  void DidStartNavigation(content::NavigationHandle* navigation_handle) final;

  bool in_fullscreen_mode() const { return !non_fullscreen_size_.IsEmpty(); }

  // Called by |capture_poll_timer_| to automatically destroy this OffscreenTab
  // when the capturer count returns to zero.
  void DieIfContentCaptureEnded();

  // Called if OTR profile is being destroyed and |this| therefore needs to be
  // destroyed also.
  // ProfileObserver:
  void OnProfileWillBeDestroyed(Profile* profile) override;

  const raw_ptr<Owner> owner_;  // Outlives this class.

  // The initial navigation URL, which may or may not match the current URL if
  // page-initiated navigations have occurred.
  GURL start_url_;

  // A non-shared off-the-record profile based on the profile of the extension
  // background page.
  raw_ptr<Profile> otr_profile_;

  // The WebContents containing the off-screen tab's page.
  std::unique_ptr<content::WebContents> offscreen_tab_web_contents_;

  // The time at which Start() finished creating |offscreen_tab_web_contents_|.
  base::TimeTicks start_time_;

  // Set to the original size of the renderer just before entering fullscreen
  // mode.  When not in fullscreen mode, this is an empty size.
  gfx::Size non_fullscreen_size_;

  // Poll timer to monitor the capturer count on |offscreen_tab_web_contents_|.
  // When the capturer count returns to zero, this OffscreenTab is automatically
  // destroyed.
  // TODO(crbug.com/41207731): add a method to WebContentsObserver to
  // report capturer count and get rid of this polling-based approach.
  base::OneShotTimer capture_poll_timer_;

  // This is false until after the Start() method is called, and capture of the
  // |offscreen_tab_web_contents_| is first detected.
  bool content_capture_was_detected_;

  // Object consulted to determine which offscreen tab navigations are allowed.
  std::unique_ptr<media_router::NavigationPolicy> navigation_policy_;

#if defined(USE_AURA)
  std::unique_ptr<WindowAdoptionAgent> window_agent_;
#endif  // defined(USE_AURA)
};

#endif  // CHROME_BROWSER_MEDIA_OFFSCREEN_TAB_H_