summaryrefslogtreecommitdiffstats
path: root/components/html_viewer/html_frame.h
blob: 9f108ac3d8071f51794d0f8a9d31cfdd3f562702 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
// 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/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:
  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 OnWindowInputEvent(mus::Window* window,
                          const mus::mojom::EventPtr& event) override;
  void OnWindowFocusChanged(mus::Window* gained_focus,
                            mus::Window* lost_focus) 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_