• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Embedded Framework Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_
6 #define CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_
7 #pragma once
8 
9 #include <memory>
10 
11 #include "libcef/browser/frame_host_impl.h"
12 
13 #include "base/callback_list.h"
14 #include "base/observer_list.h"
15 #include "content/public/browser/notification_observer.h"
16 #include "content/public/browser/notification_registrar.h"
17 #include "content/public/browser/web_contents_delegate.h"
18 #include "content/public/browser/web_contents_observer.h"
19 
20 class CefBrowser;
21 class CefBrowserInfo;
22 class CefBrowserPlatformDelegate;
23 class CefClient;
24 
25 // Flags that represent which states have changed.
26 enum class CefBrowserContentsState : uint8_t {
27   kNone = 0,
28   kNavigation = (1 << 0),
29   kDocument = (1 << 1),
30   kFullscreen = (1 << 2),
31   kFocusedFrame = (1 << 3),
32 };
33 
34 constexpr inline CefBrowserContentsState operator&(
35     CefBrowserContentsState lhs,
36     CefBrowserContentsState rhs) {
37   return static_cast<CefBrowserContentsState>(static_cast<int>(lhs) &
38                                               static_cast<int>(rhs));
39 }
40 
41 constexpr inline CefBrowserContentsState operator|(
42     CefBrowserContentsState lhs,
43     CefBrowserContentsState rhs) {
44   return static_cast<CefBrowserContentsState>(static_cast<int>(lhs) |
45                                               static_cast<int>(rhs));
46 }
47 
48 // Tracks state and executes client callbacks based on WebContents callbacks.
49 // Includes functionality that is shared by the alloy and chrome runtimes.
50 // Only accessed on the UI thread.
51 class CefBrowserContentsDelegate : public content::WebContentsDelegate,
52                                    public content::WebContentsObserver,
53                                    public content::NotificationObserver {
54  public:
55   using State = CefBrowserContentsState;
56 
57   // Interface to implement for observers that wish to be informed of changes
58   // to the delegate. All methods will be called on the UI thread.
59   class Observer : public base::CheckedObserver {
60    public:
61     // Called after state has changed and before the associated CefClient
62     // callback is executed.
63     virtual void OnStateChanged(State state_changed) = 0;
64 
65     // Called when the associated WebContents is destroyed.
66     virtual void OnWebContentsDestroyed(content::WebContents* web_contents) = 0;
67 
68    protected:
~Observer()69     ~Observer() override {}
70   };
71 
72   explicit CefBrowserContentsDelegate(
73       scoped_refptr<CefBrowserInfo> browser_info);
74 
75   CefBrowserContentsDelegate(const CefBrowserContentsDelegate&) = delete;
76   CefBrowserContentsDelegate& operator=(const CefBrowserContentsDelegate&) =
77       delete;
78 
79   void ObserveWebContents(content::WebContents* new_contents);
80 
81   // Manage observer objects. The observer must either outlive this object or
82   // be removed before destruction.
83   void AddObserver(Observer* observer);
84   void RemoveObserver(Observer* observer);
85 
86   // WebContentsDelegate methods:
87   content::WebContents* OpenURLFromTab(
88       content::WebContents* source,
89       const content::OpenURLParams& params) override;
90   void LoadingStateChanged(content::WebContents* source,
91                            bool should_show_loading_ui) override;
92   void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
93   bool DidAddMessageToConsole(content::WebContents* source,
94                               blink::mojom::ConsoleMessageLevel log_level,
95                               const std::u16string& message,
96                               int32_t line_no,
97                               const std::u16string& source_id) override;
98   void DidNavigatePrimaryMainFramePostCommit(
99       content::WebContents* web_contents) override;
100   void EnterFullscreenModeForTab(
101       content::RenderFrameHost* requesting_frame,
102       const blink::mojom::FullscreenOptions& options) override;
103   void ExitFullscreenModeForTab(content::WebContents* web_contents) override;
104   content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
105       content::WebContents* source,
106       const content::NativeWebKeyboardEvent& event) override;
107   bool HandleKeyboardEvent(
108       content::WebContents* source,
109       const content::NativeWebKeyboardEvent& event) override;
110 
111   // WebContentsObserver methods:
112   void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
113   void RenderFrameHostChanged(content::RenderFrameHost* old_host,
114                               content::RenderFrameHost* new_host) override;
115   void RenderFrameHostStateChanged(
116       content::RenderFrameHost* host,
117       content::RenderFrameHost::LifecycleState old_state,
118       content::RenderFrameHost::LifecycleState new_state) override;
119   void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
120   void RenderViewReady() override;
121   void PrimaryMainFrameRenderProcessGone(
122       base::TerminationStatus status) override;
123   void OnFrameFocused(content::RenderFrameHost* render_frame_host) override;
124   void DocumentAvailableInMainFrame(
125       content::RenderFrameHost* render_frame_host) override;
126   void LoadProgressChanged(double progress) override;
127   void DidStopLoading() override;
128   void DidFinishNavigation(
129       content::NavigationHandle* navigation_handle) override;
130   void DidFailLoad(content::RenderFrameHost* render_frame_host,
131                    const GURL& validated_url,
132                    int error_code) override;
133   void TitleWasSet(content::NavigationEntry* entry) override;
134   void PluginCrashed(const base::FilePath& plugin_path,
135                      base::ProcessId plugin_pid) override;
136   void DidUpdateFaviconURL(
137       content::RenderFrameHost* render_frame_host,
138       const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
139   void OnWebContentsFocused(
140       content::RenderWidgetHost* render_widget_host) override;
141   void OnFocusChangedInPage(content::FocusedNodeDetails* details) override;
142   void WebContentsDestroyed() override;
143 
144   // NotificationObserver methods.
145   void Observe(int type,
146                const content::NotificationSource& source,
147                const content::NotificationDetails& details) override;
148 
149   // Accessors for state information. Changes will be signaled to
150   // Observer::OnStateChanged.
is_loading()151   bool is_loading() const { return is_loading_; }
can_go_back()152   bool can_go_back() const { return can_go_back_; }
can_go_forward()153   bool can_go_forward() const { return can_go_forward_; }
has_document()154   bool has_document() const { return has_document_; }
is_fullscreen()155   bool is_fullscreen() const { return is_fullscreen_; }
focused_frame()156   CefRefPtr<CefFrameHostImpl> focused_frame() const { return focused_frame_; }
157 
158   // Helpers for executing client callbacks.
159   // TODO(cef): Make this private if/when possible.
160   void OnLoadEnd(CefRefPtr<CefFrame> frame,
161                  const GURL& url,
162                  int http_status_code);
163   bool OnSetFocus(cef_focus_source_t source);
164 
165  private:
166   CefRefPtr<CefClient> client() const;
167   CefRefPtr<CefBrowser> browser() const;
168   CefBrowserPlatformDelegate* platform_delegate() const;
169 
170   // Helpers for executing client callbacks.
171   void OnAddressChange(const GURL& url);
172   void OnLoadStart(CefRefPtr<CefFrame> frame,
173                    ui::PageTransition transition_type);
174   void OnLoadError(CefRefPtr<CefFrame> frame, const GURL& url, int error_code);
175   void OnTitleChange(const std::u16string& title);
176   void OnFullscreenModeChange(bool fullscreen);
177 
178   void OnStateChanged(State state_changed);
179 
180   scoped_refptr<CefBrowserInfo> browser_info_;
181 
182   bool is_loading_ = false;
183   bool can_go_back_ = false;
184   bool can_go_forward_ = false;
185   bool has_document_ = false;
186   bool is_fullscreen_ = false;
187 
188   // The currently focused frame, or nullptr if the main frame is focused.
189   CefRefPtr<CefFrameHostImpl> focused_frame_;
190 
191   // True if currently in the OnSetFocus callback.
192   bool is_in_onsetfocus_ = false;
193 
194   // Observers that want to be notified of changes to this object.
195   base::ObserverList<Observer> observers_;
196 
197   // Used for managing notification subscriptions.
198   std::unique_ptr<content::NotificationRegistrar> registrar_;
199 
200   // True if the focus is currently on an editable field on the page.
201   bool focus_on_editable_field_ = false;
202 };
203 
204 #endif  // CEF_LIBCEF_BROWSER_BROWSER_CONTENTS_DELEGATE_H_
205