summaryrefslogtreecommitdiffstats
path: root/components/html_viewer/html_frame.h
blob: a293ba31d74d31382fcb526efa77123bbf5f1bce (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
// 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 "components/html_viewer/html_frame_tree_manager.h"
#include "components/html_viewer/replicated_frame_state.h"
#include "components/view_manager/public/cpp/view_observer.h"
#include "mandoline/tab/public/interfaces/frame_tree.mojom.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"
#include "third_party/WebKit/public/web/WebViewClient.h"

namespace blink {
class WebFrame;
}

namespace mojo {
class ApplicationImpl;
class Rect;
class ScopedViewPtr;
class View;
}

namespace html_viewer {

class GeolocationClientImpl;
class HTMLFrameDelegate;
class HTMLFrameTreeManager;
class TouchHandler;
class WebLayerImpl;
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 mojo::View, remote frames do not.
//
// HTMLFrame serves as the FrameTreeClient. 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::WebViewClient,
                  public blink::WebRemoteFrameClient,
                  public mandoline::FrameTreeClient,
                  public mojo::ViewObserver {
 public:
  struct CreateParams {
    CreateParams(
        HTMLFrameTreeManager* manager,
        HTMLFrame* parent,
        uint32_t id,
        mojo::View* view,
        const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties,
        HTMLFrameDelegate* delegate)
        : manager(manager),
          parent(parent),
          id(id),
          view(view),
          properties(properties),
          delegate(delegate),
          allow_local_shared_frame(false) {}
    ~CreateParams() {}

    HTMLFrameTreeManager* manager;
    HTMLFrame* parent;
    uint32_t id;
    mojo::View* view;
    const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties;
    HTMLFrameDelegate* delegate;

   private:
    friend class HTMLFrame;

    // TODO(sky): nuke.
    bool allow_local_shared_frame;
  };

  explicit HTMLFrame(CreateParams* params);

  // Called when another app is embedded in the View this Frame is associated
  // with.
  void OnViewUnembed();

  // 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();

  // The mojo::View 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.
  mojo::View* view() { return view_; }

  HTMLFrameTreeManager* frame_tree_manager() { return frame_tree_manager_; }

  // Returns true if this or one of the frames descendants is local.
  bool HasLocalDescendant() const;

 protected:
  virtual ~HTMLFrame();

  // TODO(sky): move implementations to match new position.

  // WebViewClient methods:
  virtual blink::WebStorageNamespace* createSessionStorageNamespace();
  virtual void didCancelCompositionOnSelectionChange();
  virtual void didChangeContents();

  // WebWidgetClient methods:
  virtual void initializeLayerTreeView();
  virtual blink::WebLayerTreeView* layerTreeView();
  virtual void resetInputMethod();
  virtual void didHandleGestureEvent(const blink::WebGestureEvent& event,
                                     bool eventCancelled);
  virtual void didUpdateTextOfFocusedElementByNonUserInput();
  virtual void showImeIfNeeded();

  // WebFrameClient methods:
  virtual blink::WebMediaPlayer* createMediaPlayer(
      blink::WebLocalFrame* frame,
      const blink::WebURL& url,
      blink::WebMediaPlayerClient* client,
      blink::WebMediaPlayerEncryptedMediaClient* encrypted_client,
      blink::WebContentDecryptionModule* initial_cdm);
  virtual blink::WebFrame* createChildFrame(
      blink::WebLocalFrame* parent,
      blink::WebTreeScopeType scope,
      const blink::WebString& frame_ame,
      blink::WebSandboxFlags sandbox_flags);
  virtual void frameDetached(blink::WebFrame* frame,
                             blink::WebFrameClient::DetachType type);
  virtual blink::WebCookieJar* cookieJar(blink::WebLocalFrame* frame);
  virtual blink::WebNavigationPolicy decidePolicyForNavigation(
      const NavigationPolicyInfo& info);
  virtual void didHandleOnloadEvents(blink::WebLocalFrame* frame);
  virtual void didAddMessageToConsole(const blink::WebConsoleMessage& message,
                                      const blink::WebString& source_name,
                                      unsigned source_line,
                                      const blink::WebString& stack_trace);
  virtual void didFinishLoad(blink::WebLocalFrame* frame);
  virtual void didNavigateWithinPage(blink::WebLocalFrame* frame,
                                     const blink::WebHistoryItem& history_item,
                                     blink::WebHistoryCommitType commit_type);
  virtual void didFirstVisuallyNonEmptyLayout(blink::WebLocalFrame* frame);
  virtual blink::WebGeolocationClient* geolocationClient();
  virtual blink::WebEncryptedMediaClient* encryptedMediaClient();
  virtual void didStartLoading(bool to_different_document);
  virtual void didStopLoading();
  virtual void didChangeLoadProgress(double load_progress);
  virtual void didChangeName(blink::WebLocalFrame* frame,
                             const blink::WebString& name);
  virtual void didCommitProvisionalLoad(
      blink::WebLocalFrame* frame,
      const blink::WebHistoryItem& item,
      blink::WebHistoryCommitType commit_type);

 private:
  friend class HTMLFrameTreeManager;

  // Binds this frame to the specified server. |this| serves as the
  // FrameTreeClient for the server.
  void Bind(mandoline::FrameTreeServerPtr frame_tree_server,
            mojo::InterfaceRequest<mandoline::FrameTreeClient>
                frame_tree_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);

  // Returns true if the Frame is local, false if remote.
  bool IsLocal() const;

  // The local root is the first ancestor (starting at this) that has its own
  // connection.
  HTMLFrame* GetLocalRoot();

  // Gets the FrameTreeServer to use for this frame.
  mandoline::FrameTreeServer* GetFrameTreeServer();

  // Returns the ApplicationImpl from the local root's delegate.
  mojo::ApplicationImpl* GetLocalRootApp();

  void SetView(mojo::View* view);

  // Creates the appropriate WebWidget implementation for the Frame.
  void CreateRootWebWidget();
  void CreateLocalRootWebWidget(blink::WebLocalFrame* local_frame);

  void InitializeWebWidget();

  void UpdateFocus();

  // Updates the size and scale factor of the webview and related classes from
  // |root_|.
  void UpdateWebViewSizeFromViewSize();

  // 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,
      mojo::View* view,
      const mojo::Map<mojo::String, mojo::Array<uint8_t>>& properties);

  GlobalState* global_state() { return frame_tree_manager_->global_state(); }

  // 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);

  // Update text input state from WebView to mojo::View. If the focused element
  // is editable and |show_ime| is True, the software keyboard will be shown.
  void UpdateTextInputState(bool show_ime);

  // mojo::ViewObserver methods:
  void OnViewBoundsChanged(mojo::View* view,
                           const mojo::Rect& old_bounds,
                           const mojo::Rect& new_bounds) override;
  void OnViewDestroyed(mojo::View* view) override;
  void OnViewInputEvent(mojo::View* view, const mojo::EventPtr& event) override;
  void OnViewFocusChanged(mojo::View* gained_focus,
                          mojo::View* lost_focus) override;

  // mandoline::FrameTreeClient:
  void OnConnect(mandoline::FrameTreeServerPtr server,
                 uint32_t change_id,
                 mojo::Array<mandoline::FrameDataPtr> frame_data) override;
  void OnFrameAdded(uint32_t change_id,
                    mandoline::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,
      mandoline::HTMLMessageEventPtr serialized_event) override;

  // blink::WebRemoteFrameClient:
  virtual void frameDetached(blink::WebRemoteFrameClient::DetachType type);
  virtual void postMessageEvent(blink::WebLocalFrame* source_web_frame,
                                blink::WebRemoteFrame* target_web_frame,
                                blink::WebSecurityOrigin target_origin,
                                blink::WebDOMMessageEvent event);
  virtual void initializeChildFrame(const blink::WebRect& frame_rect,
                                    float scale_factor);
  virtual void navigate(const blink::WebURLRequest& request,
                        bool should_replace_current_entry);
  virtual void reload(bool ignore_cache, bool is_client_redirect);
  virtual void forwardInputEvent(const blink::WebInputEvent* event);

  HTMLFrameTreeManager* frame_tree_manager_;
  HTMLFrame* parent_;
  // |view_| is non-null for local frames or remote frames that were once
  // local.
  mojo::View* view_;
  // The id for this frame. If there is a view, this is the same id as the
  // view has.
  const uint32_t id_;
  std::vector<HTMLFrame*> children_;
  blink::WebFrame* web_frame_;
  blink::WebWidget* web_widget_;
  scoped_ptr<GeolocationClientImpl> geolocation_client_impl_;
  scoped_ptr<WebLayerTreeViewImpl> web_layer_tree_view_impl_;
  scoped_ptr<TouchHandler> touch_handler_;

  scoped_ptr<WebLayerImpl> web_layer_;

  HTMLFrameDelegate* delegate_;
  scoped_ptr<mojo::Binding<mandoline::FrameTreeClient>>
      frame_tree_client_binding_;
  mandoline::FrameTreeServerPtr server_;

  ReplicatedFrameState state_;

  // If this frame is the result of creating a local frame
  // (createChildFrame()), then |owned_view_| is the View initially created
  // for the frame. While the frame is local |owned_view_| is the same as
  // |view_|. If this frame becomes remote |view_| is set to null and
  // |owned_view_| remains as the View initially created for the frame.
  //
  // This is done to ensure the View isn't prematurely deleted (it must exist
  // as long as the frame is valid). If the View was deleted as soon as the
  // frame was swapped to remote then the process rendering to the view would
  // be severed.
  scoped_ptr<mojo::ScopedViewPtr> owned_view_;

  blink::WebTextInputInfo text_input_info_;

  // This object is only valid in the context of performance tests.
  tracing::StartupPerformanceDataCollectorPtr
      startup_performance_data_collector_;

  base::WeakPtrFactory<HTMLFrame> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(HTMLFrame);
};

}  // namespace html_viewer

#endif  // COMPONENTS_HTML_VIEWER_HTML_FRAME_H_