1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights
3  * reserved.
4  * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
5  * (http://www.torchmobile.com/)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_H_
24 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_H_
25 
26 #include <memory>
27 
28 #include "base/macros.h"
29 #include "third_party/blink/public/common/page/page_visibility_state.h"
30 #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h"
31 #include "third_party/blink/public/platform/web_text_autosizer_page_info.h"
32 #include "third_party/blink/public/web/web_window_features.h"
33 #include "third_party/blink/renderer/core/core_export.h"
34 #include "third_party/blink/renderer/core/css/vision_deficiency.h"
35 #include "third_party/blink/renderer/core/frame/deprecation.h"
36 #include "third_party/blink/renderer/core/frame/settings_delegate.h"
37 #include "third_party/blink/renderer/core/page/page_animator.h"
38 #include "third_party/blink/renderer/core/page/page_visibility_observer.h"
39 #include "third_party/blink/renderer/core/page/viewport_description.h"
40 #include "third_party/blink/renderer/platform/heap/handle.h"
41 #include "third_party/blink/renderer/platform/heap/persistent.h"
42 #include "third_party/blink/renderer/platform/heap_observer_list.h"
43 #include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
44 #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
45 #include "third_party/blink/renderer/platform/supplementable.h"
46 #include "third_party/blink/renderer/platform/wtf/forward.h"
47 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
48 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
49 
50 namespace cc {
51 class AnimationHost;
52 }
53 
54 namespace blink {
55 class AgentMetricsCollector;
56 class AutoscrollController;
57 class BrowserControls;
58 class ChromeClient;
59 class ConsoleMessageStorage;
60 class InspectorIssueStorage;
61 class ContextMenuController;
62 class Document;
63 class DragCaret;
64 class DragController;
65 class FocusController;
66 class Frame;
67 class LinkHighlight;
68 class LocalFrame;
69 class LocalFrameView;
70 class MediaFeatureOverrides;
71 class OverscrollController;
72 struct PageScaleConstraints;
73 class PageScaleConstraintsSet;
74 class PluginData;
75 class PluginsChangedObserver;
76 class PointerLockController;
77 class ScopedPagePauser;
78 class ScrollingCoordinator;
79 class ScrollbarTheme;
80 class SecurityOrigin;
81 class Settings;
82 class SpatialNavigationController;
83 class TopDocumentRootScrollerController;
84 class ValidationMessageClient;
85 class VisualViewport;
86 
87 typedef uint64_t LinkHash;
88 
89 float DeviceScaleFactorDeprecated(LocalFrame*);
90 
91 class CORE_EXPORT Page final : public GarbageCollected<Page>,
92                                public Supplementable<Page>,
93                                public SettingsDelegate,
94                                public PageScheduler::Delegate {
95   USING_GARBAGE_COLLECTED_MIXIN(Page);
96   friend class Settings;
97 
98  public:
99   // It is up to the platform to ensure that non-null clients are provided where
100   // required.
101   struct CORE_EXPORT PageClients final {
102     STACK_ALLOCATED();
103 
104    public:
105     PageClients();
106 
107     ChromeClient* chrome_client;
108     DISALLOW_COPY_AND_ASSIGN(PageClients);
109   };
110 
111   // Any pages not owned by a web view should be created using this method.
112   static Page* CreateNonOrdinary(PageClients& pages_clients);
113 
114   // An "ordinary" page is a fully-featured page owned by a web view.
115   static Page* CreateOrdinary(PageClients&, Page* opener);
116 
117   explicit Page(PageClients&);
118   ~Page() override;
119 
120   void CloseSoon();
IsClosing()121   bool IsClosing() const { return is_closing_; }
122 
123   using PageSet = HeapHashSet<WeakMember<Page>>;
124 
125   // Return the current set of full-fledged, ordinary pages.
126   // Each created and owned by a WebView.
127   //
128   // This set does not include Pages created for other, internal purposes
129   // (SVGImages, inspector overlays, page popups etc.)
130   static PageSet& OrdinaryPages();
131   static void InsertOrdinaryPageForTesting(Page*);
132 
133   // Returns pages related to the current browsing context (excluding the
134   // current page).  See also
135   // https://html.spec.whatwg.org/C/#unit-of-related-browsing-contexts
136   HeapVector<Member<Page>> RelatedPages();
137 
138   static void PlatformColorsChanged();
139   static void ColorSchemeChanged();
140 
141   void InitialStyleChanged();
142   void UpdateAcceleratedCompositingSettings();
143 
144   ViewportDescription GetViewportDescription() const;
145 
146   // Returns the plugin data associated with |main_frame_origin|.
147   PluginData* GetPluginData(const SecurityOrigin* main_frame_origin);
148 
149   // Resets the plugin data for all pages in the renderer process and notifies
150   // PluginsChangedObservers.
151   static void ResetPluginData();
152 
153   // When this method is called, page_scheduler_->SetIsMainFrameLocal should
154   // also be called to update accordingly.
155   // TODO(npm): update the |page_scheduler_| directly in this method.
156   void SetMainFrame(Frame*);
MainFrame()157   Frame* MainFrame() const { return main_frame_; }
158   // Escape hatch for existing code that assumes that the root frame is
159   // always a LocalFrame. With OOPI, this is not always the case. Code that
160   // depends on this will generally have to be rewritten to propagate any
161   // necessary state through all renderer processes for that page and/or
162   // coordinate/rely on the browser process to help dispatch/coordinate work.
163   LocalFrame* DeprecatedLocalMainFrame() const;
164 
165   void DocumentDetached(Document*);
166 
167   bool OpenedByDOM() const;
168   void SetOpenedByDOM();
169 
Animator()170   PageAnimator& Animator() { return *animator_; }
GetChromeClient()171   ChromeClient& GetChromeClient() const {
172     DCHECK(chrome_client_) << "No chrome client";
173     return *chrome_client_;
174   }
GetAutoscrollController()175   AutoscrollController& GetAutoscrollController() const {
176     return *autoscroll_controller_;
177   }
GetDragCaret()178   DragCaret& GetDragCaret() const { return *drag_caret_; }
GetDragController()179   DragController& GetDragController() const { return *drag_controller_; }
GetFocusController()180   FocusController& GetFocusController() const { return *focus_controller_; }
181   SpatialNavigationController& GetSpatialNavigationController();
GetContextMenuController()182   ContextMenuController& GetContextMenuController() const {
183     return *context_menu_controller_;
184   }
GetPointerLockController()185   PointerLockController& GetPointerLockController() const {
186     return *pointer_lock_controller_;
187   }
GetValidationMessageClient()188   ValidationMessageClient& GetValidationMessageClient() const {
189     return *validation_message_client_;
190   }
GetAgentMetricsCollector()191   AgentMetricsCollector* GetAgentMetricsCollector() const {
192     return agent_metrics_collector_.Get();
193   }
194   void SetValidationMessageClientForTesting(ValidationMessageClient*);
195 
196   ScrollingCoordinator* GetScrollingCoordinator();
197 
GetSettings()198   Settings& GetSettings() const { return *settings_; }
199 
GetDeprecation()200   Deprecation& GetDeprecation() { return deprecation_; }
201 
SetWindowFeatures(const WebWindowFeatures & features)202   void SetWindowFeatures(const WebWindowFeatures& features) {
203     window_features_ = features;
204   }
GetWindowFeatures()205   const WebWindowFeatures& GetWindowFeatures() const {
206     return window_features_;
207   }
208 
209   PageScaleConstraintsSet& GetPageScaleConstraintsSet();
210   const PageScaleConstraintsSet& GetPageScaleConstraintsSet() const;
211 
212   BrowserControls& GetBrowserControls();
213   const BrowserControls& GetBrowserControls() const;
214 
215   ConsoleMessageStorage& GetConsoleMessageStorage();
216   const ConsoleMessageStorage& GetConsoleMessageStorage() const;
217 
218   InspectorIssueStorage& GetInspectorIssueStorage();
219   const InspectorIssueStorage& GetInspectorIssueStorage() const;
220 
221   TopDocumentRootScrollerController& GlobalRootScrollerController() const;
222 
223   VisualViewport& GetVisualViewport();
224   const VisualViewport& GetVisualViewport() const;
225 
226   LinkHighlight& GetLinkHighlight();
227 
228   OverscrollController& GetOverscrollController();
229   const OverscrollController& GetOverscrollController() const;
230 
SetTabKeyCyclesThroughElements(bool b)231   void SetTabKeyCyclesThroughElements(bool b) {
232     tab_key_cycles_through_elements_ = b;
233   }
TabKeyCyclesThroughElements()234   bool TabKeyCyclesThroughElements() const {
235     return tab_key_cycles_through_elements_;
236   }
237 
238   // Pausing is used to implement the "Optionally, pause while waiting for
239   // the user to acknowledge the message" step of simple dialog processing:
240   // https://html.spec.whatwg.org/C/#simple-dialogs
241   //
242   // Per https://html.spec.whatwg.org/C/#pause, no loads
243   // are allowed to start/continue in this state, and all background processing
244   // is also paused.
Paused()245   bool Paused() const { return paused_; }
246   void SetPaused(bool);
247 
248   void SetPageScaleFactor(float);
249   float PageScaleFactor() const;
250 
251   // Corresponds to pixel density of the device where this Page is
252   // being displayed. In multi-monitor setups this can vary between pages.
253   // This value does not account for Page zoom, use LocalFrame::devicePixelRatio
254   // instead.  This is to be deprecated. Use this with caution.
255   // 1) If you need to scale the content per device scale factor, this is still
256   //    valid.  In use-zoom-for-dsf mode, this is always 1, and will be remove
257   //    when transition is complete.
258   // 2) If you want to compute the device related measure (such as device pixel
259   //    height, or the scale factor for drag image), use
260   //    ChromeClient::screenInfo() instead.
DeviceScaleFactorDeprecated()261   float DeviceScaleFactorDeprecated() const { return device_scale_factor_; }
262   void SetDeviceScaleFactorDeprecated(float);
263 
264   static void AllVisitedStateChanged(bool invalidate_visited_link_hashes);
265   static void VisitedStateChanged(LinkHash visited_hash);
266 
267   void SetVisibilityState(PageVisibilityState visibility_state,
268                           bool is_initial_state);
269   PageVisibilityState GetVisibilityState() const;
270   bool IsPageVisible() const;
271 
272   PageLifecycleState LifecycleState() const;
273 
274   bool IsCursorVisible() const;
SetIsCursorVisible(bool is_visible)275   void SetIsCursorVisible(bool is_visible) { is_cursor_visible_ = is_visible; }
276 
277   // Don't allow more than a certain number of frames in a page.
278   // This seems like a reasonable upper bound, and otherwise mutually
279   // recursive frameset pages can quickly bring the program to its knees
280   // with exponential growth in the number of frames.
281   static const int kMaxNumberOfFrames = 1000;
IncrementSubframeCount()282   void IncrementSubframeCount() { ++subframe_count_; }
DecrementSubframeCount()283   void DecrementSubframeCount() {
284     DCHECK_GT(subframe_count_, 0);
285     --subframe_count_;
286   }
287   int SubframeCount() const;
288 
289   void SetDefaultPageScaleLimits(float min_scale, float max_scale);
290   void SetUserAgentPageScaleConstraints(
291       const PageScaleConstraints& new_constraints);
292 
293 #if DCHECK_IS_ON()
SetIsPainting(bool painting)294   void SetIsPainting(bool painting) { is_painting_ = painting; }
IsPainting()295   bool IsPainting() const { return is_painting_; }
296 #endif
297 
298   void DidCommitLoad(LocalFrame*);
299 
300   void AcceptLanguagesChanged();
301 
302   void Trace(Visitor*) override;
303 
304   void AnimationHostInitialized(cc::AnimationHost&, LocalFrameView*);
305   void WillCloseAnimationHost(LocalFrameView*);
306 
307   void WillBeDestroyed();
308 
309   void RegisterPluginsChangedObserver(PluginsChangedObserver*);
310 
311   ScrollbarTheme& GetScrollbarTheme() const;
312 
313   PageScheduler* GetPageScheduler() const;
314 
315   // PageScheduler::Delegate implementation.
316   bool IsOrdinary() const override;
317   void ReportIntervention(const String& message) override;
318   bool RequestBeginMainFrameNotExpected(bool new_state) override;
319   void SetLifecycleState(PageLifecycleState) override;
320   bool LocalMainFrameNetworkIsAlmostIdle() const override;
321 
322   void AddAutoplayFlags(int32_t flags);
323   void ClearAutoplayFlags();
324 
325   int32_t AutoplayFlags() const;
326 
327   void SetInsidePortal(bool inside_portal);
328   bool InsidePortal() const;
329 
SetTextAutosizerPageInfo(const WebTextAutosizerPageInfo & page_info)330   void SetTextAutosizerPageInfo(const WebTextAutosizerPageInfo& page_info) {
331     web_text_autosizer_page_info_ = page_info;
332   }
TextAutosizerPageInfo()333   const WebTextAutosizerPageInfo& TextAutosizerPageInfo() const {
334     return web_text_autosizer_page_info_;
335   }
336 
337   void SetMediaFeatureOverride(const AtomicString& media_feature,
338                                const String& value);
GetMediaFeatureOverrides()339   const MediaFeatureOverrides* GetMediaFeatureOverrides() const {
340     return media_feature_overrides_.get();
341   }
342   void ClearMediaFeatureOverrides();
343 
344   void SetVisionDeficiency(VisionDeficiency new_vision_deficiency);
GetVisionDeficiency()345   VisionDeficiency GetVisionDeficiency() const { return vision_deficiency_; }
346 
HistoryNavigationVirtualTimePauser()347   WebScopedVirtualTimePauser& HistoryNavigationVirtualTimePauser() {
348     return history_navigation_virtual_time_pauser_;
349   }
350 
PageVisibilityObserverList()351   HeapObserverList<PageVisibilityObserver>& PageVisibilityObserverList() {
352     return page_visibility_observer_list_;
353   }
354 
355   static void PrepareForLeakDetection();
356 
357  private:
358   friend class ScopedPagePauser;
359 
360   void InitGroup();
361 
362   // SettingsDelegate overrides.
363   void SettingsChanged(SettingsDelegate::ChangeType) override;
364 
365   // Notify |plugins_changed_observers_| that plugins have changed.
366   void NotifyPluginsChanged() const;
367 
368   void SetPageScheduler(std::unique_ptr<PageScheduler>);
369 
370   void InvalidateColorScheme();
371   void InvalidatePaint();
372   // Typically, the main frame and Page should both be owned by the embedder,
373   // which must call Page::willBeDestroyed() prior to destroying Page. This
374   // call detaches the main frame and clears this pointer, thus ensuring that
375   // this field only references a live main frame.
376   //
377   // However, there are several locations (InspectorOverlay, SVGImage, and
378   // WebPagePopupImpl) which don't hold a reference to the main frame at all
379   // after creating it. These are still safe because they always create a
380   // Frame with a LocalFrameView. LocalFrameView and Frame hold references to
381   // each other, thus keeping each other alive. The call to willBeDestroyed()
382   // breaks this cycle, so the frame is still properly destroyed once no
383   // longer needed.
384   Member<Frame> main_frame_;
385 
386   Member<PageAnimator> animator_;
387   const Member<AutoscrollController> autoscroll_controller_;
388   Member<ChromeClient> chrome_client_;
389   const Member<DragCaret> drag_caret_;
390   const Member<DragController> drag_controller_;
391   const Member<FocusController> focus_controller_;
392   const Member<ContextMenuController> context_menu_controller_;
393   const Member<PageScaleConstraintsSet> page_scale_constraints_set_;
394   HeapObserverList<PageVisibilityObserver> page_visibility_observer_list_;
395   const Member<PointerLockController> pointer_lock_controller_;
396   Member<ScrollingCoordinator> scrolling_coordinator_;
397   const Member<BrowserControls> browser_controls_;
398   const Member<ConsoleMessageStorage> console_message_storage_;
399   const Member<InspectorIssueStorage> inspector_issue_storage_;
400   const Member<TopDocumentRootScrollerController>
401       global_root_scroller_controller_;
402   const Member<VisualViewport> visual_viewport_;
403   const Member<OverscrollController> overscroll_controller_;
404   const Member<LinkHighlight> link_highlight_;
405   Member<SpatialNavigationController> spatial_navigation_controller_;
406 
407   Member<PluginData> plugin_data_;
408 
409   Member<ValidationMessageClient> validation_message_client_;
410 
411   // Stored only for ordinary pages to avoid adding metrics from things like
412   // overlays, popups and SVG.
413   Member<AgentMetricsCollector> agent_metrics_collector_;
414 
415   Deprecation deprecation_;
416   WebWindowFeatures window_features_;
417 
418   bool opened_by_dom_;
419   // Set to true when window.close() has been called and the Page will be
420   // destroyed. The browsing contexts in this page should no longer be
421   // discoverable via JS.
422   // TODO(dcheng): Try to remove |DOMWindow::m_windowIsClosing| in favor of
423   // this. However, this depends on resolving https://crbug.com/674641
424   bool is_closing_;
425 
426   bool tab_key_cycles_through_elements_;
427   bool paused_;
428 
429   float device_scale_factor_;
430 
431   PageVisibilityState visibility_state_;
432 
433   bool is_ordinary_;
434 
435   PageLifecycleState page_lifecycle_state_;
436 
437   bool is_cursor_visible_;
438 
439 #if DCHECK_IS_ON()
440   bool is_painting_ = false;
441 #endif
442 
443   int subframe_count_;
444 
445   HeapHashSet<WeakMember<PluginsChangedObserver>> plugins_changed_observers_;
446 
447   // A circular, double-linked list of pages that are related to the current
448   // browsing context.  See also RelatedPages method.
449   Member<Page> next_related_page_;
450   Member<Page> prev_related_page_;
451 
452   // A handle to notify the scheduler whether this page has other related
453   // pages or not.
454   FrameScheduler::SchedulingAffectingFeatureHandle has_related_pages_;
455 
456   std::unique_ptr<PageScheduler> page_scheduler_;
457 
458   // Overrides for various media features, set from DevTools.
459   std::unique_ptr<MediaFeatureOverrides> media_feature_overrides_;
460 
461   // Emulated vision deficiency, set from DevTools.
462   VisionDeficiency vision_deficiency_ = VisionDeficiency::kNoVisionDeficiency;
463 
464   int32_t autoplay_flags_;
465 
466   // Accessed by frames to determine whether to expose the PortalHost object.
467   bool inside_portal_ = false;
468 
469   WebTextAutosizerPageInfo web_text_autosizer_page_info_;
470 
471   WebScopedVirtualTimePauser history_navigation_virtual_time_pauser_;
472 
473   DISALLOW_COPY_AND_ASSIGN(Page);
474 };
475 
476 extern template class CORE_EXTERN_TEMPLATE_EXPORT Supplement<Page>;
477 
478 class CORE_EXPORT InternalSettingsPageSupplementBase : public Supplement<Page> {
479  public:
480   using Supplement<Page>::Supplement;
481   static const char kSupplementName[];
482 };
483 
484 }  // namespace blink
485 
486 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAGE_PAGE_H_
487