Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: components/framelet/renderer/framelet_container.cc

Issue 1560553002: Framelet Prototype 2016 Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased + Applied Brett's Windows + Fixed security issue Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 #include "components/framelet/renderer/framelet_container.h"
6
7 #include "cc/blink/web_layer_impl.h"
8 #include "cc/layers/solid_color_layer.h"
9 #include "cc/layers/surface_layer.h"
10 #include "components/framelet/common/framelet_constants.h"
11 #include "components/framelet/common/framelet_messages.h"
12 #include "components/guest_view/common/guest_view_constants.h"
13 #include "components/guest_view/common/guest_view_messages.h"
14 #include "components/guest_view/renderer/guest_view_request.h"
15 #include "content/public/renderer/render_frame.h"
16 #include "content/public/renderer/render_thread.h"
17 #include "content/public/renderer/render_view.h"
18 #include "grit/components_scaled_resources.h"
19 #include "third_party/WebKit/public/web/WebDocument.h"
20 #include "third_party/WebKit/public/web/WebFramelet.h"
21 #include "third_party/WebKit/public/web/WebLocalFrame.h"
22 #include "ui/base/resource/resource_bundle.h"
23
24 namespace framelet {
25
26 namespace {
27
28 class FrameletCreateRequest : public guest_view::GuestViewRequest {
29 public:
30 FrameletCreateRequest(FrameletContainer* framelet_container,
31 ResourceMonitoring resource_monitoring)
32 : guest_view::GuestViewRequest(framelet_container),
33 resource_monitoring_(resource_monitoring) {}
34
35 ~FrameletCreateRequest() override {}
36
37 void PerformRequest() override {
38 DCHECK_NE(container()->element_instance_id(), guest_view::kInstanceIDNone);
39 if (!container() || !container()->render_frame())
40 return;
41
42 // TODO(fsamuel): This is a bit annoying. Maybe container should be a
43 // // template method?
44 FrameletContainer* framelet_container =
45 static_cast<FrameletContainer*>(container());
46 // TODO(fsamuel): We need a mechanism to detach/destroy a guest before
47 // creating a new one.
48 DCHECK(!framelet_container->has_guest());
49
50 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
51 params->SetInteger(guest_view::kElementWidth,
52 framelet_container->element_size().width());
53 params->SetInteger(guest_view::kElementHeight,
54 framelet_container->element_size().height());
55 params->SetString(guest_view::kUrl, framelet_container->url().spec());
56 params->SetBoolean(framelet::kFocused, framelet_container->focused());
57 params->SetBoolean(framelet::kVisible, framelet_container->visible());
58 params->SetBoolean(framelet::kMonitorResources,
59 resource_monitoring_ == ResourceMonitoring::ENABLED);
60
61 container()->render_frame()->Send(new ChromeGuestViewHostMsg_CreateFramelet(
62 container()->render_frame()->GetRoutingID(),
63 container()->element_instance_id(), *params));
64 }
65
66 void HandleResponse(const IPC::Message& message) override {
67 CHECK_EQ(message.type(),
68 static_cast<uint32_t>(ChromeGuestViewMsg_CreateFramelet_ACK::ID));
69 ChromeGuestViewMsg_CreateFramelet_ACK::Param param;
70 if (!ChromeGuestViewMsg_CreateFramelet_ACK::Read(&message, &param))
71 return;
72
73 int guest_instance_id = base::get<1>(param);
74 static_cast<FrameletContainer*>(container())->Attach(guest_instance_id);
75 }
76
77 void HandleDefaultResponse() override {}
78
79 private:
80 ResourceMonitoring resource_monitoring_;
81
82 DISALLOW_COPY_AND_ASSIGN(FrameletCreateRequest);
83 };
84
85 class FrameletAttachRequest : public guest_view::GuestViewRequest {
86 public:
87 explicit FrameletAttachRequest(FrameletContainer* framelet_container)
88 : guest_view::GuestViewRequest(framelet_container) {}
89
90 ~FrameletAttachRequest() override {}
91
92 void PerformRequest() override {
93 if (!container() || !container()->render_frame())
94 return;
95
96 // TODO(fsamuel): This is a bit annoying. Maybe container should be a
97 // // template method?
98 FrameletContainer* framelet_container =
99 static_cast<FrameletContainer*>(container());
100
101 DCHECK(framelet_container->has_guest());
102
103 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue());
104 params->SetInteger(guest_view::kElementWidth,
105 framelet_container->element_size().width());
106 params->SetInteger(guest_view::kElementHeight,
107 framelet_container->element_size().height());
108 params->SetBoolean(framelet::kFocused, framelet_container->focused());
109 params->SetBoolean(framelet::kVisible, framelet_container->visible());
110
111 // Step 1, send the attach params to guest_view/.
112 container()->render_frame()->Send(new GuestViewHostMsg_AttachGuest(
113 container()->element_instance_id(),
114 framelet_container->guest_instance_id(), *params));
115
116 // Step 1, Attach to FrameletGuest.
117 container()->render_frame()->Send(new ChromeGuestViewHostMsg_AttachFramelet(
118 container()->render_frame()->GetRoutingID(),
119 container()->element_instance_id(),
120 framelet_container->guest_instance_id(), *params));
121 }
122
123 void HandleResponse(const IPC::Message& message) override {
124 CHECK_EQ(message.type(),
125 static_cast<uint32_t>(GuestViewMsg_GuestAttached::ID));
126 // TODO(fsamuel): We probably don't care about the ontent window here,
127 // but it would be nice to be able to postMessage.
128 }
129
130 void HandleDefaultResponse() override {}
131
132 private:
133 DISALLOW_COPY_AND_ASSIGN(FrameletAttachRequest);
134 };
135
136 class FrameletDestroyRequest : public guest_view::GuestViewRequest {
137 public:
138 explicit FrameletDestroyRequest(FrameletContainer* framelet_container)
139 : guest_view::GuestViewRequest(framelet_container) {}
140
141 ~FrameletDestroyRequest() override {}
142
143 void PerformRequest() override {
144 if (!container() || !container()->render_frame())
145 return;
146
147 container()->render_frame()->Send(
148 new ChromeGuestViewHostMsg_DestroyFramelet(
149 container()->element_instance_id()));
150
151 static_cast<FrameletContainer*>(container())->Detach();
152 }
153
154 void HandleResponse(const IPC::Message& message) override {
155 CHECK_EQ(message.type(),
156 static_cast<uint32_t>(ChromeGuestViewMsg_DestroyFramelet_ACK::ID));
157 }
158
159 void HandleDefaultResponse() override {}
160
161 private:
162 DISALLOW_COPY_AND_ASSIGN(FrameletDestroyRequest);
163 };
164
165 } // namespace
166
167 FrameletContainer::FrameletContainer(content::RenderFrame* render_frame,
168 const GURL& url,
169 IPC::Sender* thread_safe_sender)
170 : GuestViewContainer(render_frame),
171 guest_instance_id_(guest_view::kInstanceIDNone),
172 focused_(false),
173 visible_(false),
174 killed_(false),
175 url_(url),
176 thread_safe_sender_(thread_safe_sender),
177 framelet_(nullptr),
178 solid_layer_(
179 cc::SolidColorLayer::Create(cc_blink::WebLayerImpl::LayerSettings())),
180 click_to_play_image_(ResourceBundle::GetSharedInstance().GetImageNamed(
181 IDR_FRAMELET_CLICK_TO_PLAY)),
182 click_to_play_layer_(cc::UIResourceLayer::Create(
183 cc_blink::WebLayerImpl::LayerSettings())) {
184 SetElementInstanceID(content::RenderThread::Get()->GenerateRoutingID());
185 }
186
187 FrameletContainer::~FrameletContainer() {}
188
189 void FrameletContainer::Attach(int guest_instance_id) {
190 // Reset the layers.
191 solid_layer_->SetIsDrawable(false);
192 click_to_play_layer_->SetIsDrawable(false);
193 DCHECK(!has_guest());
194 guest_instance_id_ = guest_instance_id;
195 linked_ptr<guest_view::GuestViewRequest> request(
196 new FrameletAttachRequest(this));
197 IssueRequest(request);
198 }
199
200 void FrameletContainer::Detach() {
201 guest_instance_id_ = guest_view::kInstanceIDNone;
202 }
203
204 bool FrameletContainer::OnMessage(const IPC::Message& message) {
205 bool handled = true;
206 IPC_BEGIN_MESSAGE_MAP(FrameletContainer, message)
207 IPC_MESSAGE_HANDLER(ChromeGuestViewMsg_ReportMemoryUsage,
208 OnReportMemoryUsage)
209 IPC_MESSAGE_HANDLER(ChromeGuestViewMsg_SetChildFrameSurface,
210 OnSetChildFrameSurface)
211 IPC_MESSAGE_UNHANDLED(handled = false)
212 IPC_END_MESSAGE_MAP()
213 return handled;
214 }
215
216 void FrameletContainer::didAttach(blink::WebFramelet* framelet) {
217 framelet_ = framelet;
218 // Only create a Framelet if we have a non-zero size.
219 CreateFrameletIfReady(ResourceMonitoring::ENABLED);
220 }
221
222 void FrameletContainer::didDetach() {
223 linked_ptr<guest_view::GuestViewRequest> request(
224 new FrameletDestroyRequest(this));
225 IssueRequest(request);
226 }
227
228 void FrameletContainer::forwardInputEvent(
229 const blink::WebInputEvent* input_event) {
230 if (!has_guest()) {
231 // If this guest has been killed.
232 // TODO(fsamuel): We want a platform-agnostic way to detect click.
233 bool click = input_event->type == blink::WebInputEvent::GestureTap ||
234 ((input_event->type == blink::WebInputEvent::MouseUp) &&
235 (static_cast<const blink::WebMouseEvent*>(input_event)
236 ->clickCount == 1));
237 if (killed_ && click) {
238 CreateFrameletIfReady(ResourceMonitoring::DISABLED);
239 return;
240 }
241 }
242
243 render_frame()->Send(new ChromeGuestViewHostMsg_ForwardInputEvent(
244 element_instance_id(), input_event));
245 }
246
247 void FrameletContainer::frameRectsChanged(const blink::WebRect& frame_rect) {
248 element_size_ = gfx::Size(frame_rect.width, frame_rect.height);
249 UpdateClickToPlayLayerPosition();
250 if (!ready_) {
251 ready_ = true;
252 CreateFrameletIfReady(ResourceMonitoring::ENABLED);
253 return;
254 }
255 if (!has_guest())
256 return;
257 render_frame()->Send(new ChromeGuestViewHostMsg_ResizeFramelet(
258 element_instance_id(), element_size_));
259 }
260
261 void FrameletContainer::updateFocus(bool focused,
262 blink::WebFocusType focus_type) {
263 focused_ = focused;
264 focus_type_ = focus_type;
265 if (!has_guest())
266 return;
267 render_frame()->Send(new ChromeGuestViewHostMsg_SetFocus(
268 element_instance_id(), focused, focus_type));
269 }
270
271 void FrameletContainer::updateVisibility(bool visible) {
272 visible_ = visible;
273 if (!has_guest())
274 return;
275 render_frame()->Send(new ChromeGuestViewHostMsg_SetContainerVisible(
276 element_instance_id(), visible));
277 }
278
279 void FrameletContainer::CreateFrameletIfReady(
280 ResourceMonitoring resource_monitoring) {
281 if (!ready_ || !framelet_)
282 return;
283 killed_ = false;
284 // We might already have a guest at this point that is in the process of being
285 // destroyed. We don't need to worry about that now, we'll find out about it
286 // when this request is handled in queue order.
287 linked_ptr<guest_view::GuestViewRequest> request(
288 new FrameletCreateRequest(this, resource_monitoring));
289 IssueRequest(request);
290 }
291
292 void FrameletContainer::UpdateClickToPlayLayerPosition() {
293 gfx::PointF position(
294 (element_size().width() - click_to_play_image_.Size().width()) / 2.f,
295 (element_size().height() - click_to_play_image_.Size().height()) / 2.f);
296 click_to_play_layer_->SetPosition(position);
297 }
298
299 void FrameletContainer::OnReportMemoryUsage(
300 int element_instance_id,
301 const ResourceUsageLevel& memory_usage) {
302 // TODO(fsamuel): Do something useful with the heap size.
303 switch (memory_usage) {
304 case ResourceUsageLevel::LOW: {
305 solid_layer_->SetIsDrawable(false);
306 click_to_play_layer_->SetIsDrawable(false);
307 return;
308 }
309 case ResourceUsageLevel::MEDIUM: {
310 solid_layer_->SetIsDrawable(true);
311 solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 255, 0));
312 click_to_play_layer_->SetIsDrawable(false);
313 return;
314 }
315 case ResourceUsageLevel::HIGH: {
316 solid_layer_->SetIsDrawable(true);
317 solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 255, 0, 0));
318 click_to_play_layer_->SetIsDrawable(false);
319 return;
320 }
321 case ResourceUsageLevel::CRITICAL: {
322 killed_ = true;
323 solid_layer_->SetIsDrawable(true);
324 solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 0, 0));
325 click_to_play_layer_->SetIsDrawable(true);
326 // Kill the guest.
327 linked_ptr<guest_view::GuestViewRequest> request(
328 new FrameletDestroyRequest(this));
329 IssueRequest(request);
330 return;
331 }
332 default:
333 DCHECK(false);
334 }
335 }
336
337 void FrameletContainer::OnSetChildFrameSurface(
338 int element_instance_id,
339 const cc::SurfaceId& surface_id,
340 const gfx::Size& frame_size,
341 float scale_factor,
342 const cc::SurfaceSequence& sequence) {
343 cc::SurfaceLayer::SatisfyCallback satisfy_callback = base::Bind(
344 &FrameletContainer::SatisfyCallbackOnCompositorThread,
345 thread_safe_sender_, render_frame()->GetRoutingID(), element_instance_id);
346 cc::SurfaceLayer::RequireCallback require_callback = base::Bind(
347 &FrameletContainer::RequireCallbackOnCompositorThread,
348 thread_safe_sender_, render_frame()->GetRoutingID(), element_instance_id);
349 scoped_refptr<cc::SurfaceLayer> surface_layer =
350 cc::SurfaceLayer::Create(cc_blink::WebLayerImpl::LayerSettings(),
351 satisfy_callback, require_callback);
352 surface_layer->SetSurfaceId(surface_id, scale_factor, frame_size);
353 gfx::Size frame_size_in_dip(
354 gfx::ScaleToFlooredSize(frame_size, 1.0f / scale_factor));
355 surface_layer->SetBounds(frame_size_in_dip);
356
357 solid_layer_->SetMasksToBounds(true);
358 solid_layer_->SetBounds(frame_size_in_dip);
359 solid_layer_->SetBackgroundColor(SkColorSetARGBInline(255, 0, 0, 192));
360 solid_layer_->SetIsDrawable(false);
361 solid_layer_->SetOpacity(0.5f);
362 surface_layer->AddChild(solid_layer_);
363
364 SkBitmap* bitmap = const_cast<SkBitmap*>(click_to_play_image_.ToSkBitmap());
365 click_to_play_layer_->SetMasksToBounds(true);
366 click_to_play_layer_->SetBounds(click_to_play_image_.Size());
367 click_to_play_layer_->SetBitmap(*bitmap);
368 click_to_play_layer_->SetOpacity(0.75f);
369 surface_layer->AddChild(click_to_play_layer_);
370
371 blink::WebLayer* layer = new cc_blink::WebLayerImpl(surface_layer);
372 framelet_->setWebLayer(layer);
373 web_layer_.reset(layer);
374 }
375
376 void FrameletContainer::SatisfyCallbackOnCompositorThread(
377 IPC::Sender* sender,
378 int host_routing_id,
379 int element_instance_id,
380 cc::SurfaceSequence sequence) {}
381
382 void FrameletContainer::RequireCallbackOnCompositorThread(
383 IPC::Sender* sender,
384 int host_routing_id,
385 int element_instance_id,
386 cc::SurfaceId id,
387 cc::SurfaceSequence sequence) {}
388
389 } // namespace framelet
OLDNEW
« no previous file with comments | « components/framelet/renderer/framelet_container.h ('k') | components/guest_view/browser/guest_view_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698