1 // Copyright 2018 The Chromium 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 FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ 6 #define FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ 7 8 #include <fuchsia/web/cpp/fidl.h> 9 #include <lib/fidl/cpp/binding_set.h> 10 #include <lib/ui/scenic/cpp/view_ref_pair.h> 11 #include <lib/zx/channel.h> 12 13 #include <list> 14 #include <map> 15 #include <memory> 16 #include <string> 17 #include <utility> 18 #include <vector> 19 20 #include "base/macros.h" 21 #include "base/memory/read_only_shared_memory_region.h" 22 #include "base/optional.h" 23 #include "components/media_control/browser/media_blocker.h" 24 #include "components/on_load_script_injector/browser/on_load_script_injector_host.h" 25 #include "content/public/browser/web_contents_delegate.h" 26 #include "content/public/browser/web_contents_observer.h" 27 #include "fuchsia/engine/browser/accessibility_bridge.h" 28 #include "fuchsia/engine/browser/event_filter.h" 29 #include "fuchsia/engine/browser/frame_permission_controller.h" 30 #include "fuchsia/engine/browser/navigation_controller_impl.h" 31 #include "fuchsia/engine/browser/theme_manager.h" 32 #include "fuchsia/engine/browser/url_request_rewrite_rules_manager.h" 33 #include "ui/aura/window_tree_host.h" 34 #include "ui/wm/core/focus_controller.h" 35 #include "url/gurl.h" 36 37 namespace content { 38 class FromRenderFrameHost; 39 } // namespace content 40 41 class CastStreamingSessionClient; 42 class ContextImpl; 43 class FrameWindowTreeHost; 44 class FrameLayoutManager; 45 class MediaPlayerImpl; 46 class NavigationPolicyHandler; 47 48 // Implementation of fuchsia.web.Frame based on content::WebContents. 49 class FrameImpl : public fuchsia::web::Frame, 50 public content::WebContentsObserver, 51 public content::WebContentsDelegate { 52 public: 53 // Returns FrameImpl that owns the |web_contents| or nullptr if the 54 // |web_contents| is nullptr. 55 static FrameImpl* FromWebContents(content::WebContents* web_contents); 56 57 // Returns FrameImpl that owns the |render_frame_host| or nullptr if the 58 // |render_frame_host| is nullptr. 59 static FrameImpl* FromRenderFrameHost( 60 content::RenderFrameHost* render_frame_host); 61 62 // |params_for_popups| is saved and applied to popups created by content 63 // running in this Frame. 64 FrameImpl(std::unique_ptr<content::WebContents> web_contents, 65 ContextImpl* context, 66 fuchsia::web::CreateFrameParams params_for_popups, 67 fidl::InterfaceRequest<fuchsia::web::Frame> frame_request); 68 ~FrameImpl() override; 69 70 FrameImpl(const FrameImpl&) = delete; 71 FrameImpl& operator=(const FrameImpl&) = delete; 72 media_session_id()73 uint64_t media_session_id() const { return media_session_id_; } 74 permission_controller()75 FramePermissionController* permission_controller() { 76 return &permission_controller_; 77 } 78 url_request_rewrite_rules_manager()79 UrlRequestRewriteRulesManager* url_request_rewrite_rules_manager() { 80 return &url_request_rewrite_rules_manager_; 81 } 82 navigation_policy_handler()83 NavigationPolicyHandler* navigation_policy_handler() { 84 return navigation_policy_handler_.get(); 85 } 86 87 zx::unowned_channel GetBindingChannelForTest() const; web_contents_for_test()88 content::WebContents* web_contents_for_test() const { 89 return web_contents_.get(); 90 } has_view_for_test()91 bool has_view_for_test() const { return window_tree_host_ != nullptr; } accessibility_bridge_for_test()92 AccessibilityBridge* accessibility_bridge_for_test() const { 93 return accessibility_bridge_.get(); 94 } set_semantics_manager_for_test(fuchsia::accessibility::semantics::SemanticsManager * semantics_manager)95 void set_semantics_manager_for_test( 96 fuchsia::accessibility::semantics::SemanticsManager* semantics_manager) { 97 semantics_manager_for_test_ = semantics_manager; 98 } cast_streaming_session_client_for_test()99 CastStreamingSessionClient* cast_streaming_session_client_for_test() { 100 return cast_streaming_session_client_.get(); 101 } 102 103 // Enables explicit sites filtering and set the error page. If |error_page| is 104 // empty, the default error page will be used. 105 void EnableExplicitSitesFilter(std::string error_page); 106 explicit_sites_filter_error_page()107 const base::Optional<std::string>& explicit_sites_filter_error_page() const { 108 return explicit_sites_filter_error_page_; 109 } 110 111 private: 112 FRIEND_TEST_ALL_PREFIXES(FrameImplTest, DelayedNavigationEventAck); 113 FRIEND_TEST_ALL_PREFIXES(FrameImplTest, NavigationObserverDisconnected); 114 FRIEND_TEST_ALL_PREFIXES(FrameImplTest, NoNavigationObserverAttached); 115 FRIEND_TEST_ALL_PREFIXES(FrameImplTest, ReloadFrame); 116 FRIEND_TEST_ALL_PREFIXES(FrameImplTest, Stop); 117 118 aura::Window* root_window() const; 119 120 // Shared implementation for the ExecuteJavaScript[NoResult]() APIs. 121 void ExecuteJavaScriptInternal(std::vector<std::string> origins, 122 fuchsia::mem::Buffer script, 123 ExecuteJavaScriptCallback callback, 124 bool need_result); 125 126 // Sends the next entry in |pending_popups_| to |popup_listener_|. 127 void MaybeSendPopup(); 128 129 void OnPopupListenerDisconnected(zx_status_t status); 130 131 // Cleans up the MediaPlayerImpl on disconnect. 132 void OnMediaPlayerDisconnect(); 133 134 // An error handler for |accessibility_bridge_|. 135 void OnAccessibilityError(zx_status_t error); 136 137 // Initializes WindowTreeHost for the view with the specified |view_token|. 138 // |view_token| may be uninitialized in headless mode. 139 void InitWindowTreeHost(fuchsia::ui::views::ViewToken view_token, 140 scenic::ViewRefPair view_ref_pair); 141 142 // Destroys the WindowTreeHost along with its view or other associated 143 // resources. 144 void DestroyWindowTreeHost(); 145 146 // Destroys |this| and sends the FIDL |error| to the client. 147 void CloseAndDestroyFrame(zx_status_t error); 148 149 // Determines whether |message| is a Cast Streaming message and if so, handles 150 // it. Returns whether it handled the message, regardless of whether that was 151 // successful. If true is returned, |callback| has been called. Returns false 152 // immediately if Cast Streaming support is not enabled. Called by 153 // PostMessage(). 154 bool MaybeHandleCastStreamingMessage(std::string* origin, 155 fuchsia::web::WebMessage* message, 156 PostMessageCallback* callback); 157 158 void MaybeStartCastStreaming(content::NavigationHandle* navigation_handle); 159 160 // fuchsia::web::Frame implementation. 161 void CreateView(fuchsia::ui::views::ViewToken view_token) override; 162 void CreateViewWithViewRef(fuchsia::ui::views::ViewToken view_token, 163 fuchsia::ui::views::ViewRefControl control_ref, 164 fuchsia::ui::views::ViewRef view_ref) override; 165 void GetMediaPlayer(fidl::InterfaceRequest<fuchsia::media::sessions2::Player> 166 player) override; 167 void GetNavigationController( 168 fidl::InterfaceRequest<fuchsia::web::NavigationController> controller) 169 override; 170 void ExecuteJavaScript(std::vector<std::string> origins, 171 fuchsia::mem::Buffer script, 172 ExecuteJavaScriptCallback callback) override; 173 void ExecuteJavaScriptNoResult( 174 std::vector<std::string> origins, 175 fuchsia::mem::Buffer script, 176 ExecuteJavaScriptNoResultCallback callback) override; 177 void AddBeforeLoadJavaScript( 178 uint64_t id, 179 std::vector<std::string> origins, 180 fuchsia::mem::Buffer script, 181 AddBeforeLoadJavaScriptCallback callback) override; 182 void RemoveBeforeLoadJavaScript(uint64_t id) override; 183 void PostMessage(std::string origin, 184 fuchsia::web::WebMessage message, 185 fuchsia::web::Frame::PostMessageCallback callback) override; 186 void SetNavigationEventListener( 187 fidl::InterfaceHandle<fuchsia::web::NavigationEventListener> listener) 188 override; 189 void SetJavaScriptLogLevel(fuchsia::web::ConsoleLogLevel level) override; 190 void ConfigureInputTypes(fuchsia::web::InputTypes types, 191 fuchsia::web::AllowInputState allow) override; 192 void SetPopupFrameCreationListener( 193 fidl::InterfaceHandle<fuchsia::web::PopupFrameCreationListener> listener) 194 override; 195 void SetUrlRequestRewriteRules( 196 std::vector<fuchsia::web::UrlRequestRewriteRule> rules, 197 SetUrlRequestRewriteRulesCallback callback) override; 198 void EnableHeadlessRendering() override; 199 void DisableHeadlessRendering() override; 200 void SetMediaSessionId(uint64_t session_id) override; 201 void ForceContentDimensions( 202 std::unique_ptr<fuchsia::ui::gfx::vec2> web_dips) override; 203 void SetPermissionState(fuchsia::web::PermissionDescriptor permission, 204 std::string web_origin, 205 fuchsia::web::PermissionState state) override; 206 void SetBlockMediaLoading(bool blocked) override; 207 void MediaStartedPlaying(const MediaPlayerInfo& video_type, 208 const content::MediaPlayerId& id) override; 209 void MediaStoppedPlaying( 210 const MediaPlayerInfo& video_type, 211 const content::MediaPlayerId& id, 212 WebContentsObserver::MediaStoppedReason reason) override; 213 void GetPrivateMemorySize(GetPrivateMemorySizeCallback callback) override; 214 void SetNavigationPolicyProvider( 215 fuchsia::web::NavigationPolicyProviderParams params, 216 fidl::InterfaceHandle<fuchsia::web::NavigationPolicyProvider> provider) 217 override; 218 void SetPreferredTheme(fuchsia::settings::ThemeType theme) override; 219 220 // content::WebContentsDelegate implementation. 221 void CloseContents(content::WebContents* source) override; 222 bool DidAddMessageToConsole(content::WebContents* source, 223 blink::mojom::ConsoleMessageLevel log_level, 224 const base::string16& message, 225 int32_t line_no, 226 const base::string16& source_id) override; 227 bool IsWebContentsCreationOverridden( 228 content::SiteInstance* source_site_instance, 229 content::mojom::WindowContainerType window_container_type, 230 const GURL& opener_url, 231 const std::string& frame_name, 232 const GURL& target_url) override; 233 void WebContentsCreated(content::WebContents* source_contents, 234 int opener_render_process_id, 235 int opener_render_frame_id, 236 const std::string& frame_name, 237 const GURL& target_url, 238 content::WebContents* new_contents) override; 239 void AddNewContents(content::WebContents* source, 240 std::unique_ptr<content::WebContents> new_contents, 241 const GURL& target_url, 242 WindowOpenDisposition disposition, 243 const gfx::Rect& initial_rect, 244 bool user_gesture, 245 bool* was_blocked) override; 246 void RequestMediaAccessPermission( 247 content::WebContents* web_contents, 248 const content::MediaStreamRequest& request, 249 content::MediaResponseCallback callback) override; 250 bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host, 251 const GURL& security_origin, 252 blink::mojom::MediaStreamType type) override; 253 254 // content::WebContentsObserver implementation. 255 void ReadyToCommitNavigation( 256 content::NavigationHandle* navigation_handle) override; 257 void DidFinishLoad(content::RenderFrameHost* render_frame_host, 258 const GURL& validated_url) override; 259 void RenderViewCreated(content::RenderViewHost* render_view_host) override; 260 void RenderViewReady() override; 261 void DidFirstVisuallyNonEmptyPaint() override; 262 void ResourceLoadComplete( 263 content::RenderFrameHost* render_frame_host, 264 const content::GlobalRequestID& request_id, 265 const blink::mojom::ResourceLoadInfo& resource_load_info) override; 266 267 const std::unique_ptr<content::WebContents> web_contents_; 268 ContextImpl* const context_; 269 270 // Parameters applied to popups created by content running in this Frame. 271 const fuchsia::web::CreateFrameParams params_for_popups_; 272 273 std::unique_ptr<FrameWindowTreeHost> window_tree_host_; 274 275 std::unique_ptr<wm::FocusController> focus_controller_; 276 277 // Owned via |window_tree_host_|. 278 FrameLayoutManager* layout_manager_ = nullptr; 279 280 std::unique_ptr<AccessibilityBridge> accessibility_bridge_; 281 fuchsia::accessibility::semantics::SemanticsManager* 282 semantics_manager_for_test_ = nullptr; 283 284 EventFilter event_filter_; 285 NavigationControllerImpl navigation_controller_; 286 logging::LogSeverity log_level_; 287 UrlRequestRewriteRulesManager url_request_rewrite_rules_manager_; 288 FramePermissionController permission_controller_; 289 std::unique_ptr<NavigationPolicyHandler> navigation_policy_handler_; 290 291 // Session ID to use for fuchsia.media.AudioConsumer. Set with 292 // SetMediaSessionId(). 293 uint64_t media_session_id_ = 0; 294 295 // Used for receiving and dispatching popup created by this Frame. 296 fuchsia::web::PopupFrameCreationListenerPtr popup_listener_; 297 std::list<std::unique_ptr<content::WebContents>> pending_popups_; 298 bool popup_ack_outstanding_ = false; 299 gfx::Size render_size_override_; 300 301 std::unique_ptr<MediaPlayerImpl> media_player_; 302 std::unique_ptr<CastStreamingSessionClient> cast_streaming_session_client_; 303 on_load_script_injector::OnLoadScriptInjectorHost<uint64_t> script_injector_; 304 305 fidl::Binding<fuchsia::web::Frame> binding_; 306 media_control::MediaBlocker media_blocker_; 307 308 ThemeManager theme_manager_; 309 310 // The error page to be displayed when a navigation to an explicit site is 311 // filtered. Explicit sites are filtered if it has a value. If set to the 312 // empty string, the default error page will be displayed. 313 base::Optional<std::string> explicit_sites_filter_error_page_; 314 315 base::WeakPtrFactory<FrameImpl> weak_factory_{this}; 316 }; 317 318 #endif // FUCHSIA_ENGINE_BROWSER_FRAME_IMPL_H_ 319