| // 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. |
| |
| #include "sky/shell/ui/engine.h" |
| |
| #include "base/bind.h" |
| #include "mojo/public/cpp/application/connect.h" |
| #include "sky/engine/public/platform/WebInputEvent.h" |
| #include "sky/engine/public/web/Sky.h" |
| #include "sky/engine/public/web/WebLocalFrame.h" |
| #include "sky/engine/public/web/WebSettings.h" |
| #include "sky/engine/public/web/WebView.h" |
| #include "sky/services/platform/platform_impl.h" |
| #include "sky/shell/java_service_provider.h" |
| #include "sky/shell/ui/animator.h" |
| #include "sky/shell/ui/input_event_converter.h" |
| #include "sky/shell/ui/internals.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| #include "third_party/skia/include/core/SkPictureRecorder.h" |
| |
| namespace sky { |
| namespace shell { |
| |
| namespace { |
| |
| void ConfigureSettings(blink::WebSettings* settings) { |
| settings->setDefaultFixedFontSize(13); |
| settings->setDefaultFontSize(16); |
| settings->setLoadsImagesAutomatically(true); |
| } |
| |
| } |
| |
| Engine::Engine(const Config& config) |
| : config_(config), |
| animator_(new Animator(config, this)), |
| web_view_(nullptr), |
| device_pixel_ratio_(1.0f), |
| viewport_observer_binding_(this), |
| weak_factory_(this) { |
| } |
| |
| Engine::~Engine() { |
| if (web_view_) |
| web_view_->close(); |
| } |
| |
| base::WeakPtr<Engine> Engine::GetWeakPtr() { |
| return weak_factory_.GetWeakPtr(); |
| } |
| |
| mojo::ServiceProviderPtr Engine::CreateServiceProvider() { |
| mojo::MessagePipe pipe; |
| config_.java_task_runner->PostTask( |
| FROM_HERE, |
| base::Bind(CreateJavaServiceProvider, |
| base::Passed(mojo::MakeRequest<mojo::ServiceProvider>( |
| pipe.handle1.Pass())))); |
| return mojo::MakeProxy<mojo::ServiceProvider>(pipe.handle0.Pass()); |
| } |
| |
| void Engine::Init() { |
| service_provider_ = CreateServiceProvider(); |
| mojo::NetworkServicePtr network_service; |
| mojo::ConnectToService(service_provider_.get(), &network_service); |
| platform_impl_.reset(new PlatformImpl(network_service.Pass())); |
| |
| blink::initialize(platform_impl_.get()); |
| } |
| |
| void Engine::BeginFrame(base::TimeTicks frame_time) { |
| double frame_time_sec = (frame_time - base::TimeTicks()).InSecondsF(); |
| double deadline_sec = frame_time_sec; |
| double interval_sec = 1.0 / 60; |
| blink::WebBeginFrameArgs args(frame_time_sec, deadline_sec, interval_sec); |
| |
| web_view_->beginFrame(args); |
| web_view_->layout(); |
| } |
| |
| skia::RefPtr<SkPicture> Engine::Paint() { |
| SkRTreeFactory factory; |
| SkPictureRecorder recorder; |
| auto canvas = skia::SharePtr(recorder.beginRecording( |
| physical_size_.width(), physical_size_.height(), &factory, |
| SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); |
| |
| web_view_->paint(canvas.get(), blink::WebRect(gfx::Rect(physical_size_))); |
| return skia::AdoptRef(recorder.endRecordingAsPicture()); |
| } |
| |
| void Engine::ConnectToViewportObserver( |
| mojo::InterfaceRequest<ViewportObserver> request) { |
| viewport_observer_binding_.Bind(request.Pass()); |
| } |
| |
| void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { |
| config_.gpu_task_runner->PostTask( |
| FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable, |
| config_.gpu_delegate, widget)); |
| if (web_view_) |
| scheduleVisualUpdate(); |
| } |
| |
| void Engine::OnOutputSurfaceDestroyed() { |
| config_.gpu_task_runner->PostTask( |
| FROM_HERE, |
| base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate)); |
| } |
| |
| void Engine::OnViewportMetricsChanged(int width, int height, |
| float device_pixel_ratio) { |
| physical_size_.SetSize(width, height); |
| device_pixel_ratio_ = device_pixel_ratio; |
| if (web_view_) |
| UpdateWebViewSize(); |
| } |
| |
| void Engine::UpdateWebViewSize() |
| { |
| CHECK(web_view_); |
| web_view_->setDeviceScaleFactor(device_pixel_ratio_); |
| gfx::SizeF size = gfx::ScaleSize(physical_size_, 1 / device_pixel_ratio_); |
| // FIXME: We should be able to set the size of the WebView in floating point |
| // because its in logical pixels. |
| web_view_->resize(blink::WebSize(size.width(), size.height())); |
| } |
| |
| // TODO(eseidel): This is likely not needed anymore. |
| blink::WebScreenInfo Engine::screenInfo() { |
| blink::WebScreenInfo screen; |
| screen.rect = blink::WebRect(gfx::Rect(physical_size_)); |
| screen.availableRect = screen.rect; |
| screen.deviceScaleFactor = device_pixel_ratio_; |
| return screen; |
| } |
| |
| void Engine::OnInputEvent(InputEventPtr event) { |
| scoped_ptr<blink::WebInputEvent> web_event = |
| ConvertEvent(event, device_pixel_ratio_); |
| if (!web_event) |
| return; |
| web_view_->handleInputEvent(*web_event); |
| } |
| |
| void Engine::LoadURL(const mojo::String& url) { |
| // Something bad happens if you try to call WebView::close and replace |
| // the webview. So for now we just load into the existing one. :/ |
| if (!web_view_) |
| web_view_ = blink::WebView::create(this); |
| ConfigureSettings(web_view_->settings()); |
| web_view_->setMainFrame(blink::WebLocalFrame::create(this)); |
| UpdateWebViewSize(); |
| web_view_->mainFrame()->load(GURL(url)); |
| } |
| |
| void Engine::frameDetached(blink::WebFrame* frame) { |
| // |frame| is invalid after here. |
| frame->close(); |
| } |
| |
| void Engine::initializeLayerTreeView() { |
| } |
| |
| void Engine::scheduleVisualUpdate() { |
| animator_->RequestFrame(); |
| } |
| |
| void Engine::didCreateIsolate(blink::WebLocalFrame* frame, |
| Dart_Isolate isolate) { |
| Internals::Create(isolate, CreateServiceProvider()); |
| } |
| |
| blink::ServiceProvider* Engine::services() { |
| return this; |
| } |
| |
| mojo::NavigatorHost* Engine::NavigatorHost() { |
| return this; |
| } |
| |
| void Engine::RequestNavigate(mojo::Target target, |
| mojo::URLRequestPtr request) { |
| // Ignoring target for now. |
| base::MessageLoop::current()->PostTask(FROM_HERE, |
| base::Bind(&Engine::LoadURL, GetWeakPtr(), request->url)); |
| } |
| |
| void Engine::DidNavigateLocally(const mojo::String& url) { |
| } |
| |
| void Engine::RequestNavigateHistory(int32_t delta) { |
| NOTIMPLEMENTED(); |
| } |
| |
| } // namespace shell |
| } // namespace sky |