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