blob: 1439c6a23136e6e7353209c5c91a750174f131c1 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_HTML_VIEWER_HTML_FRAME_H_
#define COMPONENTS_HTML_VIEWER_HTML_FRAME_H_
#include <vector>
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "cc/layers/surface_layer.h"
#include "components/html_viewer/html_frame_tree_manager.h"
#include "components/html_viewer/replicated_frame_state.h"
#include "components/mus/public/cpp/input_event_handler.h"
#include "components/mus/public/cpp/window_observer.h"
#include "components/web_view/public/interfaces/frame.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/services/tracing/public/interfaces/tracing.mojom.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebFrameClient.h"
#include "third_party/WebKit/public/web/WebRemoteFrameClient.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "third_party/WebKit/public/web/WebTextInputInfo.h"
namespace cc_blink {
class WebLayerImpl;
}
namespace blink {
class WebFrame;
class WebWidget;
}
namespace mojo {
class ApplicationImpl;
class Rect;
}
namespace mus {
class ScopedWindowPtr;
class Window;
}
namespace html_viewer {
class DevToolsAgentImpl;
class GeolocationClientImpl;
class HTMLFrameDelegate;
class HTMLFrameTreeManager;
class HTMLWidget;
class TouchHandler;
class WebLayerTreeViewImpl;
// Frame is used to represent a single frame in the frame tree of a page. The
// frame is either local or remote. Each Frame is associated with a single
// HTMLFrameTreeManager and can not be moved to another HTMLFrameTreeManager.
// Local frames have a mus::Window, remote frames do not.
//
// HTMLFrame serves as the FrameClient. It implements it by forwarding the
// calls to HTMLFrameTreeManager so that HTMLFrameTreeManager can update the
// frame tree as appropriate.
//
// Local frames may share the connection (and client implementation) with an
// ancestor. This happens when a child frame is created. Once a navigate
// happens the frame is swapped to a remote frame.
//
// Remote frames may become local again if the embed happens in the same
// process. See HTMLFrameTreeManager for details.
class HTMLFrame : public blink::WebFrameClient,
public blink::WebRemoteFrameClient,
public web_view::mojom::FrameClient,
public mus::WindowObserver,
public mus::InputEventHandler {
public:
struct CreateParams {
CreateParams(
HTMLFrameTreeManager* manager,
HTMLFrame* parent,
uint32_t id,
mus::Window* window,
const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties,
HTMLFrameDelegate* delegate)
: manager(manager),
parent(parent),
id(id),
window(window),
properties(properties),
delegate(delegate),
is_local_create_child(false) {}
~CreateParams() {}
HTMLFrameTreeManager* manager;
HTMLFrame* parent;
uint32_t id;
mus::Window* window;
const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties;
HTMLFrameDelegate* delegate;
private:
friend class HTMLFrame;
// True if the creation is the result of createChildFrame(). That is, a
// local parent is creating a new child frame.
bool is_local_create_child;
};
explicit HTMLFrame(CreateParams* params);
// Closes and deletes this Frame.
void Close();
uint32_t id() const { return id_; }
// Returns the Frame whose id is |id|.
HTMLFrame* FindFrame(uint32_t id) {
return const_cast<HTMLFrame*>(
const_cast<const HTMLFrame*>(this)->FindFrame(id));
}
const HTMLFrame* FindFrame(uint32_t id) const;
HTMLFrame* parent() { return parent_; }
const std::vector<HTMLFrame*>& children() { return children_; }
// Returns the WebFrame for this Frame. This is either a WebLocalFrame or
// WebRemoteFrame.
blink::WebFrame* web_frame() { return web_frame_; }
// Returns the WebView for this frame, or null if there isn't one. The root
// has a WebView, the children WebFrameWidgets.
blink::WebView* web_view();
blink::WebWidget* GetWebWidget();
// The mus::Window this frame renders to. This is non-null for the local frame
// the frame tree was created with as well as non-null for any frames created
// locally.
mus::Window* window() { return window_; }
HTMLFrameTreeManager* frame_tree_manager() { return frame_tree_manager_; }
// Returns null if the browser side didn't request to setup an agent in this
// frame.
DevToolsAgentImpl* devtools_agent() { return devtools_agent_.get(); }
// Returns true if the Frame is local, false if remote.
bool IsLocal() const;
// Returns true if this or one of the frames descendants is local.
bool HasLocalDescendant() const;
void LoadRequest(const blink::WebURLRequest& request,
base::TimeTicks navigation_start_time);
protected:
~HTMLFrame() override;
// WebFrameClient methods:
blink::WebMediaPlayer* createMediaPlayer(
blink::WebLocalFrame* frame,
const blink::WebURL& url,
blink::WebMediaPlayerClient* client,
blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
blink::WebContentDecryptionModule* initial_cdm,
const blink::WebString& sink_id) override;
blink::WebFrame* createChildFrame(
blink::WebLocalFrame* parent,
blink::WebTreeScopeType scope,
const blink::WebString& frame_ame,
blink::WebSandboxFlags sandbox_flags,
const blink::WebFrameOwnerProperties& frame_owner_properties) override;
void frameDetached(blink::WebFrame* frame,
blink::WebFrameClient::DetachType type) override;
blink::WebCookieJar* cookieJar(blink::WebLocalFrame* frame) override;
blink::WebNavigationPolicy decidePolicyForNavigation(
const NavigationPolicyInfo& info) override;
bool hasPendingNavigation(blink::WebLocalFrame* frame) override;
void didHandleOnloadEvents(blink::WebLocalFrame* frame) override;
void didAddMessageToConsole(const blink::WebConsoleMessage& message,
const blink::WebString& source_name,
unsigned source_line,
const blink::WebString& stack_trace) override;
void didFinishLoad(blink::WebLocalFrame* frame) override;
void didNavigateWithinPage(blink::WebLocalFrame* frame,
const blink::WebHistoryItem& history_item,
blink::WebHistoryCommitType commit_type) override;
blink::WebGeolocationClient* geolocationClient() override;
blink::WebEncryptedMediaClient* encryptedMediaClient() override;
void didStartLoading(bool to_different_document) override;
void didStopLoading() override;
void didChangeLoadProgress(double load_progress) override;
void dispatchLoad() override;
void didChangeName(blink::WebLocalFrame* frame,
const blink::WebString& name) override;
void didCommitProvisionalLoad(
blink::WebLocalFrame* frame,
const blink::WebHistoryItem& item,
blink::WebHistoryCommitType commit_type) override;
void didReceiveTitle(blink::WebLocalFrame* frame,
const blink::WebString& title,
blink::WebTextDirection direction) override;
void reportFindInFrameMatchCount(int identifier,
int count,
bool finalUpdate) override;
void reportFindInPageSelection(int identifier,
int activeMatchOrdinal,
const blink::WebRect& selection) override;
bool shouldSearchSingleFrame() override;
private:
friend class HTMLFrameTreeManager;
// Binds this frame to the specified server. |this| serves as the
// FrameClient for the server.
void Bind(web_view::mojom::FramePtr frame,
mojo::InterfaceRequest<web_view::mojom::FrameClient>
frame_client_request);
// Sets the appropriate value from the client property. |name| identifies
// the property and |new_data| the new value.
void SetValueFromClientProperty(const std::string& name,
mojo::Array<uint8_t> new_data);
// The local root is the first ancestor (starting at this) that has its own
// delegate.
HTMLFrame* GetFirstAncestorWithDelegate();
// Returns the ApplicationImpl from the first ancestor with a delegate.
mojo::ApplicationImpl* GetApp();
// Gets the server Frame to use for this frame.
web_view::mojom::Frame* GetServerFrame();
void SetWindow(mus::Window* window);
// Creates the appropriate WebWidget implementation for the Frame.
void CreateRootWebWidget();
void CreateLocalRootWebWidget(blink::WebLocalFrame* local_frame);
void UpdateFocus();
// Swaps this frame from a local frame to remote frame. |request| is the url
// to load in the frame.
void SwapToRemote();
// Swaps this frame from a remote frame to a local frame.
void SwapToLocal(
HTMLFrameDelegate* delegate,
mus::Window* window,
const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties);
// Invoked when changing the delegate. This informs the new delegate to take
// over. This is used when a different connection is going to take over
// responsibility for the frame.
void SwapDelegate(HTMLFrameDelegate* delegate);
GlobalState* global_state() { return frame_tree_manager_->global_state(); }
// Returns the focused element if the focused element is in this
// frame. Returns an empty one otherwise.
blink::WebElement GetFocusedElement();
// Returns the Frame associated with the specified WebFrame.
HTMLFrame* FindFrameWithWebFrame(blink::WebFrame* web_frame);
// The various frameDetached() implementations call into this.
void FrameDetachedImpl(blink::WebFrame* web_frame);
// mus::WindowObserver methods:
void OnWindowBoundsChanged(mus::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) override;
void OnWindowDestroyed(mus::Window* window) override;
void OnWindowFocusChanged(mus::Window* gained_focus,
mus::Window* lost_focus) override;
// mus::InputEventHandler:
void OnWindowInputEvent(mus::Window* window,
mus::mojom::EventPtr event,
scoped_ptr<base::Closure>* ack_callback) override;
// web_view::mojom::FrameClient:
void OnConnect(web_view::mojom::FramePtr server,
uint32_t change_id,
uint32_t window_id,
web_view::mojom::WindowConnectType window_connect_type,
mojo::Array<web_view::mojom::FrameDataPtr> frame_data,
int64_t navigation_start_time_ticks,
const OnConnectCallback& callback) override;
void OnFrameAdded(uint32_t change_id,
web_view::mojom::FrameDataPtr frame_data) override;
void OnFrameRemoved(uint32_t change_id, uint32_t frame_id) override;
void OnFrameClientPropertyChanged(uint32_t frame_id,
const mojo::String& name,
mojo::Array<uint8_t> new_value) override;
void OnPostMessageEvent(
uint32_t source_frame_id,
uint32_t target_frame_id,
web_view::mojom::HTMLMessageEventPtr serialized_event) override;
void OnWillNavigate(const mojo::String& origin,
const OnWillNavigateCallback& callback) override;
void OnFrameLoadingStateChanged(uint32_t frame_id, bool loading) override;
void OnDispatchFrameLoadEvent(uint32_t frame_id) override;
void Find(int32 request_id,
const mojo::String& search_text,
web_view::mojom::FindOptionsPtr options,
bool wrap_within_frame,
const FindCallback& callback) override;
void StopFinding(bool clear_selection) override;
void HighlightFindResults(int32_t request_id,
const mojo::String& search_test,
web_view::mojom::FindOptionsPtr options,
bool reset) override;
void StopHighlightingFindResults() override;
// blink::WebRemoteFrameClient:
void frameDetached(blink::WebRemoteFrameClient::DetachType type) override;
void postMessageEvent(blink::WebLocalFrame* source_web_frame,
blink::WebRemoteFrame* target_web_frame,
blink::WebSecurityOrigin target_origin,
blink::WebDOMMessageEvent event) override;
void initializeChildFrame(const blink::WebRect& frame_rect,
float scale_factor) override;
void navigate(const blink::WebURLRequest& request,
bool should_replace_current_entry) override;
void reload(bool ignore_cache, bool is_client_redirect) override;
void frameRectsChanged(const blink::WebRect& frame_rect) override;
HTMLFrameTreeManager* frame_tree_manager_;
HTMLFrame* parent_;
// |window_| is non-null for local frames or remote frames that were once
// local.
mus::Window* window_;
// The id for this frame. If there is a window, this is the same id as the
// window has.
const uint32_t id_;
std::vector<HTMLFrame*> children_;
blink::WebFrame* web_frame_;
scoped_ptr<HTMLWidget> html_widget_;
scoped_ptr<GeolocationClientImpl> geolocation_client_impl_;
scoped_ptr<TouchHandler> touch_handler_;
scoped_ptr<cc_blink::WebLayerImpl> web_layer_;
scoped_refptr<cc::SurfaceLayer> surface_layer_;
HTMLFrameDelegate* delegate_;
scoped_ptr<mojo::Binding<web_view::mojom::FrameClient>> frame_client_binding_;
web_view::mojom::FramePtr server_;
ReplicatedFrameState state_;
// If this frame is the result of creating a local frame
// (createChildFrame()), then |owned_window_| is the Window initially created
// for the frame. While the frame is local |owned_window_| is the same as
// |window_|. If this frame becomes remote |window_| is set to null and
// |owned_window_| remains as the Window initially created for the frame.
//
// This is done to ensure the Window isn't prematurely deleted (it must exist
// as long as the frame is valid). If the Window was deleted as soon as the
// frame was swapped to remote then the process rendering to the window would
// be severed.
scoped_ptr<mus::ScopedWindowPtr> owned_window_;
// This object is only valid in the context of performance tests.
tracing::StartupPerformanceDataCollectorPtr
startup_performance_data_collector_;
scoped_ptr<DevToolsAgentImpl> devtools_agent_;
// A navigation request has been sent to the frame server side, and we haven't
// received response to it.
bool pending_navigation_;
base::TimeTicks navigation_start_time_;
base::WeakPtrFactory<HTMLFrame> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(HTMLFrame);
};
} // namespace html_viewer
#endif // COMPONENTS_HTML_VIEWER_HTML_FRAME_H_