From 1a1ef489ee480ab5c9e9fb99b041ef4e842cb32d Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 25 Jun 2015 13:59:22 -0700 Subject: [PATCH] Make it possible to run Sky apps offline This CL makes it possible to run Sky apps offline by introducing new DartLibraryProvider subclasses, specifically one that can load directly from the file system. A future CL will expand this functionality to work with asset bundles as well. Currently, the only platform that uses this functionality is Linux, which can now load a simple Sky app without even loading a network stack. Making this work on other platforms is work for future CLs. TBR=eseidel@chromium.org Review URL: https://codereview.chromium.org/1203143004. --- engine/core/core.gni | 4 +- engine/core/frame/LocalDOMWindow.cpp | 3 +- engine/core/script/dart_controller.cc | 57 +++++------- engine/core/script/dart_controller.h | 12 +-- .../script/dart_library_provider_network.h | 44 ---------- ...rk.cc => dart_library_provider_webview.cc} | 40 +++------ .../script/dart_library_provider_webview.h | 35 ++++++++ engine/core/script/dom_dart_state.cc | 2 +- engine/core/script/dom_dart_state.h | 6 +- engine/public/platform/WebString.h | 14 ++- engine/public/sky/BUILD.gn | 4 +- engine/public/sky/sky_view.cc | 69 +++++++-------- engine/public/sky/sky_view.h | 19 ++-- engine/tonic/dart_library_provider.h | 9 +- services/viewport/viewport_observer.mojom | 5 +- shell/BUILD.gn | 1 + .../sky/shell/PlatformViewAndroid.java | 2 +- shell/dart/BUILD.gn | 24 +++++ shell/dart/dart_library_provider_files.cc | 78 ++++++++++++++++ shell/dart/dart_library_provider_files.h | 36 ++++++++ shell/dart/dart_library_provider_network.cc | 88 +++++++++++++++++++ shell/dart/dart_library_provider_network.h | 41 +++++++++ shell/ios/sky_surface.mm | 2 +- shell/linux/main.cc | 11 ++- shell/ui/engine.cc | 54 +++++++++--- shell/ui/engine.h | 11 ++- viewer/BUILD.gn | 3 + viewer/dart_library_provider_impl.cc | 38 ++++++++ viewer/dart_library_provider_impl.h | 38 ++++++++ viewer/document_view.cc | 20 ++++- viewer/document_view.h | 4 +- 31 files changed, 577 insertions(+), 197 deletions(-) delete mode 100644 engine/core/script/dart_library_provider_network.h rename engine/core/script/{dart_library_provider_network.cc => dart_library_provider_webview.cc} (58%) create mode 100644 engine/core/script/dart_library_provider_webview.h create mode 100644 shell/dart/BUILD.gn create mode 100644 shell/dart/dart_library_provider_files.cc create mode 100644 shell/dart/dart_library_provider_files.h create mode 100644 shell/dart/dart_library_provider_network.cc create mode 100644 shell/dart/dart_library_provider_network.h create mode 100644 viewer/dart_library_provider_impl.cc create mode 100644 viewer/dart_library_provider_impl.h diff --git a/engine/core/core.gni b/engine/core/core.gni index 15141a0f7e2..80f631709d4 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -1052,8 +1052,8 @@ sky_core_files = [ "script/dart_controller.h", "script/dart_debugger.cc", "script/dart_debugger.h", - "script/dart_library_provider_network.cc", - "script/dart_library_provider_network.h", + "script/dart_library_provider_webview.cc", + "script/dart_library_provider_webview.h", "script/dart_service_isolate.cc", "script/dart_service_isolate.h", "script/dom_dart_state.cc", diff --git a/engine/core/frame/LocalDOMWindow.cpp b/engine/core/frame/LocalDOMWindow.cpp index 47c7c6df64c..cb5a02bad5c 100644 --- a/engine/core/frame/LocalDOMWindow.cpp +++ b/engine/core/frame/LocalDOMWindow.cpp @@ -226,7 +226,8 @@ PassRefPtr LocalDOMWindow::installNewDocument(const DocumentInit& init m_document = Document::create(init); m_application = Application::create(m_document.get(), m_document.get(), m_document->url().string()); m_eventQueue = DOMWindowEventQueue::create(m_document.get()); - m_frame->dart().CreateIsolateFor(adoptPtr(new DOMDartState(m_document.get(), m_document->url()))); + m_frame->dart().CreateIsolateFor(adoptPtr( + new DOMDartState(m_document.get(), m_document->url().string()))); { Dart_Isolate isolate = m_frame->dart().dart_state()->isolate(); diff --git a/engine/core/script/dart_controller.cc b/engine/core/script/dart_controller.cc index 1be5dd9f899..f12119736a7 100644 --- a/engine/core/script/dart_controller.cc +++ b/engine/core/script/dart_controller.cc @@ -23,7 +23,7 @@ #include "sky/engine/core/html/imports/HTMLImportChild.h" #include "sky/engine/core/loader/FrameLoaderClient.h" #include "sky/engine/core/script/dart_debugger.h" -#include "sky/engine/core/script/dart_library_provider_network.h" +#include "sky/engine/core/script/dart_library_provider_webview.h" #include "sky/engine/core/script/dart_service_isolate.h" #include "sky/engine/core/script/dom_dart_state.h" #include "sky/engine/public/platform/Platform.h" @@ -50,18 +50,6 @@ void CreateEmptyRootLibraryIfNeeded() { } } -PassOwnPtr -CreatePrefetchedLibraryIfNeeded(const KURL& url, - mojo::URLResponsePtr response) { - OwnPtr prefetched; - if (response && response->status_code == 200) { - prefetched = adoptPtr(new DartLibraryProviderNetwork::PrefetchedLibrary()); - prefetched->name = url.string(); - prefetched->pipe = response->body.Pass(); - } - return prefetched.release(); -} - } // namespace #if ENABLE(DART_STRICT) @@ -133,37 +121,20 @@ Dart_Handle DartController::CreateLibrary(AbstractModule* module, return library; } -void DartController::DidLoadMainLibrary(KURL url) { +void DartController::DidLoadMainLibrary(String name) { DCHECK(Dart_CurrentIsolate() == dart_state()->isolate()); DartApiScope dart_api_scope; if (LogIfError(Dart_FinalizeLoading(true))) return; - Dart_Handle library = Dart_LookupLibrary( - StringToDart(dart_state(), url.string())); + Dart_Handle library = Dart_LookupLibrary(StringToDart(dart_state(), name)); // TODO(eseidel): We need to load a 404 page instead! if (LogIfError(library)) return; DartInvokeAppField(library, ToDart("main"), 0, nullptr); } -void DartController::LoadMainLibrary(const KURL& url, mojo::URLResponsePtr response) { - DartState::Scope scope(dart_state()); - CreateEmptyRootLibraryIfNeeded(); - - library_provider_ = adoptPtr(new DartLibraryProviderNetwork( - CreatePrefetchedLibraryIfNeeded(url, response.Pass()))); - - DartLibraryLoader& loader = dart_state()->library_loader(); - loader.set_library_provider(library_provider_.get()); - - DartDependencyCatcher dependency_catcher(loader); - loader.LoadLibrary(url.string()); - loader.WaitForDependencies(dependency_catcher.dependencies(), - base::Bind(&DartController::DidLoadMainLibrary, weak_factory_.GetWeakPtr(), url)); -} - void DartController::DidLoadSnapshot() { DCHECK(Dart_CurrentIsolate() == nullptr); snapshot_loader_ = nullptr; @@ -185,6 +156,21 @@ void DartController::LoadSnapshot(const KURL& url, mojo::URLResponsePtr response base::Bind(&DartController::DidLoadSnapshot, weak_factory_.GetWeakPtr())); } +void DartController::RunFromLibrary(const String& name, + DartLibraryProvider* library_provider) { + DartState::Scope scope(dart_state()); + CreateEmptyRootLibraryIfNeeded(); + + DartLibraryLoader& loader = dart_state()->library_loader(); + loader.set_library_provider(library_provider); + + DartDependencyCatcher dependency_catcher(loader); + loader.LoadLibrary(name); + loader.WaitForDependencies(dependency_catcher.dependencies(), + base::Bind(&DartController::DidLoadMainLibrary, + weak_factory_.GetWeakPtr(), name)); +} + void DartController::LoadScriptInModule( AbstractModule* module, const String& source, @@ -196,7 +182,7 @@ void DartController::LoadScriptInModule( DartLibraryLoader& loader = dart_state()->library_loader(); if (!library_provider_) { - library_provider_ = adoptPtr(new DartLibraryProviderNetwork(nullptr)); + library_provider_ = adoptPtr(new DartLibraryProviderWebView()); loader.set_library_provider(library_provider_.get()); } @@ -381,9 +367,8 @@ void DartController::CreateIsolateFor(PassOwnPtr state) { char* error = nullptr; dom_dart_state_ = state; Dart_Isolate isolate = Dart_CreateIsolate( - dom_dart_state_->url().string().utf8().data(), "main", - kDartIsolateSnapshotBuffer, nullptr, - static_cast(dom_dart_state_.get()), &error); + dom_dart_state_->url().utf8().data(), "main", kDartIsolateSnapshotBuffer, + nullptr, static_cast(dom_dart_state_.get()), &error); Dart_SetMessageNotifyCallback(MessageNotifyCallback); CHECK(isolate) << error; dom_dart_state_->SetIsolate(isolate); diff --git a/engine/core/script/dart_controller.h b/engine/core/script/dart_controller.h index 7d7347cdc34..bff9f29c7af 100644 --- a/engine/core/script/dart_controller.h +++ b/engine/core/script/dart_controller.h @@ -18,7 +18,8 @@ namespace blink { class AbstractModule; class BuiltinSky; class DOMDartState; -class DartLibraryProviderNetwork; +class DartLibraryProvider; +class DartLibraryProviderWebView; class DartSnapshotLoader; class DartValue; class HTMLScriptElement; @@ -35,10 +36,11 @@ class DartController { typedef base::Callback, RefPtr)> LoadFinishedCallback; - // Can either issue the url load ourselves or take an existing response: - void LoadMainLibrary(const KURL& url, mojo::URLResponsePtr response = nullptr); void LoadSnapshot(const KURL& url, mojo::URLResponsePtr response = nullptr); + void RunFromLibrary(const String& name, + DartLibraryProvider* library_provider); + void LoadScriptInModule(AbstractModule* module, const String& source, const TextPosition& textPosition, @@ -59,12 +61,12 @@ class DartController { const String& source, const TextPosition& position); - void DidLoadMainLibrary(KURL url); + void DidLoadMainLibrary(String url); void DidLoadSnapshot(); OwnPtr dom_dart_state_; OwnPtr builtin_sky_; - OwnPtr library_provider_; + OwnPtr library_provider_; OwnPtr snapshot_loader_; base::WeakPtrFactory weak_factory_; diff --git a/engine/core/script/dart_library_provider_network.h b/engine/core/script/dart_library_provider_network.h deleted file mode 100644 index bc6b7dbad78..00000000000 --- a/engine/core/script/dart_library_provider_network.h +++ /dev/null @@ -1,44 +0,0 @@ -// 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 SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_NETWORK_H_ -#define SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_NETWORK_H_ - -#include "sky/engine/tonic/dart_library_provider.h" -#include "sky/engine/wtf/HashSet.h" -#include "sky/engine/wtf/OwnPtr.h" - -namespace blink { - -class DartLibraryProviderNetwork : public DartLibraryProvider { - public: - struct PrefetchedLibrary { - PrefetchedLibrary(); - ~PrefetchedLibrary(); - - String name; - mojo::ScopedDataPipeConsumerHandle pipe; - }; - - explicit DartLibraryProviderNetwork(PassOwnPtr prefetched); - ~DartLibraryProviderNetwork() override; - - private: - class Job; - - // |DartLibraryProvider| implementation: - void GetLibraryAsStream( - const String& name, - base::Callback callback) - override; - - Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override; - - OwnPtr prefetched_library_; - HashSet> jobs_; -}; - -} // namespace blink - -#endif // SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_NETWORK_H_ diff --git a/engine/core/script/dart_library_provider_network.cc b/engine/core/script/dart_library_provider_webview.cc similarity index 58% rename from engine/core/script/dart_library_provider_network.cc rename to engine/core/script/dart_library_provider_webview.cc index fc8b8e863ce..cea834138ac 100644 --- a/engine/core/script/dart_library_provider_network.cc +++ b/engine/core/script/dart_library_provider_webview.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "sky/engine/core/script/dart_library_provider_network.h" +#include "sky/engine/core/script/dart_library_provider_webview.h" #include "sky/engine/platform/fetcher/MojoFetcher.h" #include "sky/engine/platform/weborigin/KURL.h" @@ -10,14 +10,11 @@ namespace blink { -typedef base::Callback - CompletionCallback; - -class DartLibraryProviderNetwork::Job : public MojoFetcher::Client { +class DartLibraryProviderWebView::Job : public MojoFetcher::Client { public: - Job(DartLibraryProviderNetwork* provider, + Job(DartLibraryProviderWebView* provider, const String& name, - CompletionCallback callback) + DataPipeConsumerCallback callback) : provider_(provider), callback_(callback) { fetcher_ = adoptPtr(new MojoFetcher(this, KURL(ParsedURLString, name))); } @@ -35,39 +32,24 @@ class DartLibraryProviderNetwork::Job : public MojoFetcher::Client { // We're deleted now. } - DartLibraryProviderNetwork* provider_; - CompletionCallback callback_; + DartLibraryProviderWebView* provider_; + DataPipeConsumerCallback callback_; OwnPtr fetcher_; }; -DartLibraryProviderNetwork::PrefetchedLibrary::PrefetchedLibrary() { +DartLibraryProviderWebView::DartLibraryProviderWebView() { } -DartLibraryProviderNetwork::PrefetchedLibrary::~PrefetchedLibrary() { +DartLibraryProviderWebView::~DartLibraryProviderWebView() { } -DartLibraryProviderNetwork::DartLibraryProviderNetwork( - PassOwnPtr prefetched) - : prefetched_library_(prefetched) { -} - -DartLibraryProviderNetwork::~DartLibraryProviderNetwork() { -} - -void DartLibraryProviderNetwork::GetLibraryAsStream( +void DartLibraryProviderWebView::GetLibraryAsStream( const String& name, - CompletionCallback callback) { - if (prefetched_library_ && prefetched_library_->name == name) { - mojo::ScopedDataPipeConsumerHandle pipe = prefetched_library_->pipe.Pass(); - prefetched_library_ = nullptr; - callback.Run(pipe.Pass()); - return; - } - + DataPipeConsumerCallback callback) { jobs_.add(adoptPtr(new Job(this, name, callback))); } -Dart_Handle DartLibraryProviderNetwork::CanonicalizeURL(Dart_Handle library, +Dart_Handle DartLibraryProviderWebView::CanonicalizeURL(Dart_Handle library, Dart_Handle url) { String string = StringFromDart(url); if (string.startsWith("dart:")) diff --git a/engine/core/script/dart_library_provider_webview.h b/engine/core/script/dart_library_provider_webview.h new file mode 100644 index 00000000000..f0973a80c0f --- /dev/null +++ b/engine/core/script/dart_library_provider_webview.h @@ -0,0 +1,35 @@ +// 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 SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_WEBVIEW_H_ +#define SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_WEBVIEW_H_ + +#include "sky/engine/tonic/dart_library_provider.h" +#include "sky/engine/wtf/HashSet.h" +#include "sky/engine/wtf/OwnPtr.h" + +namespace blink { + +class DartLibraryProviderWebView : public DartLibraryProvider { + public: + explicit DartLibraryProviderWebView(); + ~DartLibraryProviderWebView() override; + + private: + class Job; + + // |DartLibraryProvider| implementation: + void GetLibraryAsStream( + const String& name, + DataPipeConsumerCallback callback) + override; + + Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override; + + HashSet> jobs_; +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_WEBVIEW_H_ diff --git a/engine/core/script/dom_dart_state.cc b/engine/core/script/dom_dart_state.cc index cc042b535eb..1784f6b55f6 100644 --- a/engine/core/script/dom_dart_state.cc +++ b/engine/core/script/dom_dart_state.cc @@ -9,7 +9,7 @@ namespace blink { -DOMDartState::DOMDartState(Document* document, const KURL& url) +DOMDartState::DOMDartState(Document* document, const String& url) : document_(document), url_(url) { } diff --git a/engine/core/script/dom_dart_state.h b/engine/core/script/dom_dart_state.h index 17088290a69..ba45f36bafd 100644 --- a/engine/core/script/dom_dart_state.h +++ b/engine/core/script/dom_dart_state.h @@ -16,7 +16,7 @@ class LocalDOMWindow; class DOMDartState : public DartState { public: - explicit DOMDartState(Document* document, const KURL& url); + explicit DOMDartState(Document* document, const String& url); ~DOMDartState() override; virtual void DidSetIsolate(); @@ -27,7 +27,7 @@ class DOMDartState : public DartState { static LocalFrame* CurrentFrame(); static LocalDOMWindow* CurrentWindow(); - const KURL& url() const { return url_; } + const String& url() const { return url_; } Document* document() const { return document_.get(); } @@ -39,7 +39,7 @@ class DOMDartState : public DartState { private: RefPtr document_; - KURL url_; + String url_; DartPersistentValue x_handle_; DartPersistentValue y_handle_; diff --git a/engine/public/platform/WebString.h b/engine/public/platform/WebString.h index a042fcb7f95..2d10b07687a 100644 --- a/engine/public/platform/WebString.h +++ b/engine/public/platform/WebString.h @@ -32,16 +32,13 @@ #define SKY_ENGINE_PUBLIC_PLATFORM_WEBSTRING_H_ #include -#include "sky/engine/public/platform/WebCommon.h" -#include "sky/engine/public/platform/WebPrivatePtr.h" -#if INSIDE_BLINK -#include "sky/engine/wtf/Forward.h" -#else #include "base/strings/latin1_string_conversions.h" #include "base/strings/nullable_string16.h" #include "base/strings/string16.h" -#endif +#include "sky/engine/public/platform/WebCommon.h" +#include "sky/engine/public/platform/WebPrivatePtr.h" +#include "sky/engine/wtf/Forward.h" namespace WTF { class StringImpl; @@ -119,7 +116,7 @@ public: return *this; } -#if INSIDE_BLINK + BLINK_COMMON_EXPORT WebString(const WTF::String&); BLINK_COMMON_EXPORT WebString& operator=(const WTF::String&); BLINK_COMMON_EXPORT operator WTF::String() const; @@ -127,7 +124,7 @@ public: BLINK_COMMON_EXPORT WebString(const WTF::AtomicString&); BLINK_COMMON_EXPORT WebString& operator=(const WTF::AtomicString&); BLINK_COMMON_EXPORT operator WTF::AtomicString() const; -#else + WebString(const base::string16& s) { assign(s.data(), s.length()); @@ -165,7 +162,6 @@ public: { return base::NullableString16(operator base::string16(), m_private.isNull()); } -#endif private: BLINK_COMMON_EXPORT bool is8Bit() const; diff --git a/engine/public/sky/BUILD.gn b/engine/public/sky/BUILD.gn index ae306b2ba2b..19c32b2f253 100644 --- a/engine/public/sky/BUILD.gn +++ b/engine/public/sky/BUILD.gn @@ -5,10 +5,12 @@ source_set("sky") { deps = [ "//base", + "//mojo/public/cpp/system", + "//mojo/services/network/public/interfaces", "//skia", "//sky/engine/core", "//sky/engine/platform", - "//mojo/services/network/public/interfaces", + "//sky/engine/wtf", ] configs += [ diff --git a/engine/public/sky/sky_view.cc b/engine/public/sky/sky_view.cc index 62455d0994f..b18677c65e4 100644 --- a/engine/public/sky/sky_view.cc +++ b/engine/public/sky/sky_view.cc @@ -19,18 +19,12 @@ namespace blink { -class SkyView::Data { - public: - RefPtr view_; -}; - std::unique_ptr SkyView::Create(SkyViewClient* client) { return std::unique_ptr(new SkyView(client)); } SkyView::SkyView(SkyViewClient* client) : client_(client), - data_(new Data), weak_factory_(this) { } @@ -43,39 +37,26 @@ SkyView::~SkyView() { void SkyView::SetDisplayMetrics(const SkyDisplayMetrics& metrics) { display_metrics_ = metrics; - data_->view_->setDisplayMetrics(display_metrics_); + view_->setDisplayMetrics(display_metrics_); } -void SkyView::Load(const WebURL& web_url, mojo::URLResponsePtr response) { - KURL url = web_url; +void SkyView::RunFromLibrary(const WebString& name, + DartLibraryProvider* library_provider) { + CreateView(name); + dart_controller_->RunFromLibrary(name, library_provider); +} - data_->view_ = View::create(base::Bind( - &SkyView::ScheduleFrame, weak_factory_.GetWeakPtr())); - data_->view_->setDisplayMetrics(display_metrics_); - - dart_controller_.reset(new DartController); - dart_controller_->CreateIsolateFor(adoptPtr(new DOMDartState(nullptr, url))); - dart_controller_->InstallView(data_->view_.get()); - - { - Dart_Isolate isolate = dart_controller_->dart_state()->isolate(); - DartIsolateScope scope(isolate); - DartApiScope api_scope; - client_->DidCreateIsolate(isolate); - } - - if (url.path().endsWith(".snapshot")) - dart_controller_->LoadSnapshot(url, response.Pass()); - else - dart_controller_->LoadMainLibrary(url, response.Pass()); +void SkyView::RunFromSnapshot(const WebString& name, + mojo::ScopedDataPipeConsumerHandle snapshot) { + // TODO(abarth): Implement. } void SkyView::BeginFrame(base::TimeTicks frame_time) { - data_->view_->beginFrame(frame_time); + view_->beginFrame(frame_time); } skia::RefPtr SkyView::Paint() { - if (Picture* picture = data_->view_->picture()) + if (Picture* picture = view_->picture()) return skia::SharePtr(picture->toSkia()); return skia::RefPtr(); } @@ -85,22 +66,40 @@ void SkyView::HandleInputEvent(const WebInputEvent& inputEvent) { if (WebInputEvent::isPointerEventType(inputEvent.type)) { const WebPointerEvent& event = static_cast(inputEvent); - data_->view_->handleInputEvent(PointerEvent::create(event)); + view_->handleInputEvent(PointerEvent::create(event)); } else if (WebInputEvent::isGestureEventType(inputEvent.type)) { const WebGestureEvent& event = static_cast(inputEvent); - data_->view_->handleInputEvent(GestureEvent::create(event)); + view_->handleInputEvent(GestureEvent::create(event)); } else if (WebInputEvent::isKeyboardEventType(inputEvent.type)) { const WebKeyboardEvent& event = static_cast(inputEvent); - data_->view_->handleInputEvent(KeyboardEvent::create(event)); + view_->handleInputEvent(KeyboardEvent::create(event)); } else if (WebInputEvent::isWheelEventType(inputEvent.type)) { const WebWheelEvent& event = static_cast(inputEvent); - data_->view_->handleInputEvent(WheelEvent::create(event)); + view_->handleInputEvent(WheelEvent::create(event)); } else if (inputEvent.type == WebInputEvent::Back) { - data_->view_->handleInputEvent(Event::create("back")); + view_->handleInputEvent(Event::create("back")); } } +void SkyView::CreateView(const String& name) { + DCHECK(!view_); + DCHECK(!dart_controller_); + + view_ = View::create( + base::Bind(&SkyView::ScheduleFrame, weak_factory_.GetWeakPtr())); + view_->setDisplayMetrics(display_metrics_); + + dart_controller_ = adoptPtr(new DartController); + dart_controller_->CreateIsolateFor(adoptPtr(new DOMDartState(nullptr, name))); + dart_controller_->InstallView(view_.get()); + + Dart_Isolate isolate = dart_controller_->dart_state()->isolate(); + DartIsolateScope scope(isolate); + DartApiScope api_scope; + client_->DidCreateIsolate(isolate); +} + void SkyView::ScheduleFrame() { client_->ScheduleFrame(); } diff --git a/engine/public/sky/sky_view.h b/engine/public/sky/sky_view.h index abf64fad9c8..08adc3b09d9 100644 --- a/engine/public/sky/sky_view.h +++ b/engine/public/sky/sky_view.h @@ -9,16 +9,22 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "mojo/services/network/public/interfaces/url_loader.mojom.h" #include "skia/ext/refptr.h" #include "sky/engine/public/platform/WebCommon.h" #include "sky/engine/public/platform/WebURL.h" #include "sky/engine/public/platform/sky_display_metrics.h" +#include "sky/engine/wtf/OwnPtr.h" +#include "sky/engine/wtf/RefPtr.h" +#include "sky/engine/wtf/text/WTFString.h" #include "third_party/skia/include/core/SkPicture.h" namespace blink { class DartController; +class DartLibraryProvider; class SkyViewClient; +class View; class WebInputEvent; class SkyView { @@ -30,8 +36,10 @@ class SkyView { void SetDisplayMetrics(const SkyDisplayMetrics& metrics); void BeginFrame(base::TimeTicks frame_time); - // Sky can either issue the load itself or use an existing response pipe. - void Load(const WebURL& url, mojo::URLResponsePtr response = nullptr); + void RunFromLibrary(const WebString& name, + DartLibraryProvider* library_provider); + void RunFromSnapshot(const WebString& name, + mojo::ScopedDataPipeConsumerHandle snapshot); skia::RefPtr Paint(); void HandleInputEvent(const WebInputEvent& event); @@ -39,14 +47,13 @@ class SkyView { private: explicit SkyView(SkyViewClient* client); + void CreateView(const String& name); void ScheduleFrame(); - class Data; - SkyViewClient* client_; SkyDisplayMetrics display_metrics_; - std::unique_ptr dart_controller_; - std::unique_ptr data_; + RefPtr view_; + OwnPtr dart_controller_; base::WeakPtrFactory weak_factory_; diff --git a/engine/tonic/dart_library_provider.h b/engine/tonic/dart_library_provider.h index 737e673771c..e849fdc0473 100644 --- a/engine/tonic/dart_library_provider.h +++ b/engine/tonic/dart_library_provider.h @@ -12,15 +12,16 @@ namespace blink { +typedef base::Callback + DataPipeConsumerCallback; + class DartLibraryProvider { public: - virtual void GetLibraryAsStream( - const String& name, - base::Callback callback) = 0; + virtual void GetLibraryAsStream(const String& name, + DataPipeConsumerCallback callback) = 0; virtual Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) = 0; - protected: virtual ~DartLibraryProvider(); }; diff --git a/services/viewport/viewport_observer.mojom b/services/viewport/viewport_observer.mojom index 6271729b711..ce86699be25 100644 --- a/services/viewport/viewport_observer.mojom +++ b/services/viewport/viewport_observer.mojom @@ -10,5 +10,8 @@ import "sky/services/viewport/input_event.mojom"; interface ViewportObserver { OnViewportMetricsChanged(int32 width, int32 height, float device_pixel_ratio); OnInputEvent(InputEvent event); - LoadURL(string url); + + RunFromNetwork(string url); + RunFromFile(string main, string package_root); + RunFromSnapshot(handle snapshot); }; diff --git a/shell/BUILD.gn b/shell/BUILD.gn index b28c8f8bdfe..a71ad12c133 100644 --- a/shell/BUILD.gn +++ b/shell/BUILD.gn @@ -21,6 +21,7 @@ common_deps = [ "//sky/engine/wtf", "//sky/services/platform", "//sky/services/viewport", + "//sky/shell/dart", "//ui/gfx/geometry", "//ui/gl", ] diff --git a/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java b/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java index 1a036fb6be8..685e9bd80d9 100644 --- a/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java +++ b/shell/android/org/domokit/sky/shell/PlatformViewAndroid.java @@ -183,7 +183,7 @@ public class PlatformViewAndroid extends SurfaceView } public void loadUrl(String url) { - mViewportObserver.loadUrl(url); + mViewportObserver.runFromNetwork(url); } private void attach() { diff --git a/shell/dart/BUILD.gn b/shell/dart/BUILD.gn new file mode 100644 index 00000000000..b4a1cf528a0 --- /dev/null +++ b/shell/dart/BUILD.gn @@ -0,0 +1,24 @@ +# 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. + +source_set("dart") { + sources = [ + "dart_library_provider_files.cc", + "dart_library_provider_files.h", + "dart_library_provider_network.cc", + "dart_library_provider_network.h", + ] + + deps = [ + "//base", + "//build/config/sanitizers:deps", + "//dart/runtime:libdart", + "//mojo/common", + "//mojo/public/cpp/application", + "//mojo/services/network/public/interfaces", + "//sky/engine/tonic", + "//sky/engine/wtf", + "//url", + ] +} diff --git a/shell/dart/dart_library_provider_files.cc b/shell/dart/dart_library_provider_files.cc new file mode 100644 index 00000000000..04a6284f175 --- /dev/null +++ b/shell/dart/dart_library_provider_files.cc @@ -0,0 +1,78 @@ +// 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/dart/dart_library_provider_files.h" + +#include "base/bind.h" +#include "base/strings/string_util.h" +#include "base/threading/worker_pool.h" +#include "mojo/common/data_pipe_utils.h" +#include "sky/engine/tonic/dart_converter.h" + +namespace sky { +namespace shell { +namespace { + +void Ignored(bool) { +} + +base::FilePath SimplifyPath(const base::FilePath& path) { + std::vector components; + path.GetComponents(&components); + base::FilePath result; + for (const auto& component : components) { + if (component == base::FilePath::kCurrentDirectory) + continue; + if (component == base::FilePath::kParentDirectory) + result = result.DirName(); + else + result = result.Append(component); + } + return result; +} + +} // namespace + +DartLibraryProviderFiles::DartLibraryProviderFiles( + const base::FilePath& package_root) + : package_root_(package_root) { +} + +DartLibraryProviderFiles::~DartLibraryProviderFiles() { +} + +void DartLibraryProviderFiles::GetLibraryAsStream( + const String& name, + blink::DataPipeConsumerCallback callback) { + mojo::DataPipe pipe; + callback.Run(pipe.consumer_handle.Pass()); + + base::FilePath source(name.toUTF8()); + scoped_refptr runner = + base::WorkerPool::GetTaskRunner(true); + mojo::common::CopyFromFile(source, pipe.producer_handle.Pass(), 0, + runner.get(), base::Bind(&Ignored)); +} + +std::string DartLibraryProviderFiles::CanonicalizePackageURL(std::string url) { + DCHECK(StartsWithASCII(url, "package:", true)); + ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); + return package_root_.Append(url).AsUTF8Unsafe(); +} + +Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library, + Dart_Handle url) { + std::string string = blink::StdStringFromDart(url); + if (StartsWithASCII(string, "dart:", true)) + return url; + if (StartsWithASCII(string, "package:", true)) + return blink::StdStringToDart(CanonicalizePackageURL(string)); + base::FilePath base_path(blink::StdStringFromDart(Dart_LibraryUrl(library))); + base::FilePath resolved_path = base_path.DirName().Append(string); + base::FilePath normalized_path = SimplifyPath(resolved_path); + return blink::StdStringToDart(normalized_path.AsUTF8Unsafe()); +} + +} // namespace shell +} // namespace sky diff --git a/shell/dart/dart_library_provider_files.h b/shell/dart/dart_library_provider_files.h new file mode 100644 index 00000000000..6a3c46cc510 --- /dev/null +++ b/shell/dart/dart_library_provider_files.h @@ -0,0 +1,36 @@ +// 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 SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ +#define SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ + +#include "base/files/file_path.h" +#include "sky/engine/tonic/dart_library_provider.h" + +namespace sky { +namespace shell { + +class DartLibraryProviderFiles : public blink::DartLibraryProvider { + public: + explicit DartLibraryProviderFiles(const base::FilePath& package_root); + ~DartLibraryProviderFiles() override; + + protected: + // |DartLibraryProvider| implementation: + void GetLibraryAsStream(const String& name, + blink::DataPipeConsumerCallback callback) override; + Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override; + + private: + std::string CanonicalizePackageURL(std::string url); + + base::FilePath package_root_; + + DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderFiles); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ diff --git a/shell/dart/dart_library_provider_network.cc b/shell/dart/dart_library_provider_network.cc new file mode 100644 index 00000000000..8138e049e43 --- /dev/null +++ b/shell/dart/dart_library_provider_network.cc @@ -0,0 +1,88 @@ +// 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/dart/dart_library_provider_network.h" + +#include "base/bind.h" +#include "base/strings/string_util.h" +#include "sky/engine/tonic/dart_converter.h" +#include "url/gurl.h" + +namespace sky { +namespace shell { +namespace { + +mojo::URLLoaderPtr Fetch(mojo::NetworkService* network_service, + const String& url, + base::Callback callback) { + mojo::URLLoaderPtr loader; + network_service->CreateURLLoader(GetProxy(&loader)); + + mojo::URLRequestPtr request = mojo::URLRequest::New(); + request->url = url.toUTF8(); + request->auto_follow_redirects = true; + loader->Start(request.Pass(), callback); + + return loader.Pass(); +} + +} // namespace + +class DartLibraryProviderNetwork::Job { + public: + Job(DartLibraryProviderNetwork* provider, + const String& name, + blink::DataPipeConsumerCallback callback) + : provider_(provider), callback_(callback), weak_factory_(this) { + url_loader_ = + Fetch(provider_->network_service(), name, + base::Bind(&Job::OnReceivedResponse, weak_factory_.GetWeakPtr())); + } + + private: + void OnReceivedResponse(mojo::URLResponsePtr response) { + mojo::ScopedDataPipeConsumerHandle data; + if (response->status_code == 200) + data = response->body.Pass(); + callback_.Run(data.Pass()); + provider_->jobs_.remove(this); + // We're deleted now. + } + + DartLibraryProviderNetwork* provider_; + blink::DataPipeConsumerCallback callback_; + mojo::URLLoaderPtr url_loader_; + + base::WeakPtrFactory weak_factory_; +}; + +DartLibraryProviderNetwork::DartLibraryProviderNetwork( + mojo::NetworkService* network_service) + : network_service_(network_service) { +} + +DartLibraryProviderNetwork::~DartLibraryProviderNetwork() { +} + +void DartLibraryProviderNetwork::GetLibraryAsStream( + const String& name, + blink::DataPipeConsumerCallback callback) { + jobs_.add(adoptPtr(new Job(this, name, callback))); +} + +Dart_Handle DartLibraryProviderNetwork::CanonicalizeURL(Dart_Handle library, + Dart_Handle url) { + std::string string = blink::StdStringFromDart(url); + if (StartsWithASCII(string, "dart:", true)) + return url; + // TODO(abarth): The package root should be configurable. + if (StartsWithASCII(string, "package:", true)) + ReplaceFirstSubstringAfterOffset(&string, 0, "package:", "/packages/"); + GURL library_url(blink::StdStringFromDart(Dart_LibraryUrl(library))); + GURL resolved_url = library_url.Resolve(string); + return blink::StdStringToDart(resolved_url.spec()); +} + +} // namespace shell +} // namespace sky diff --git a/shell/dart/dart_library_provider_network.h b/shell/dart/dart_library_provider_network.h new file mode 100644 index 00000000000..b1f0add5859 --- /dev/null +++ b/shell/dart/dart_library_provider_network.h @@ -0,0 +1,41 @@ +// 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 SKY_SHELL_DART_DART_LIBRARY_PROVIDER_NETWORK_H_ +#define SKY_SHELL_DART_DART_LIBRARY_PROVIDER_NETWORK_H_ + +#include "mojo/services/network/public/interfaces/network_service.mojom.h" +#include "sky/engine/tonic/dart_library_provider.h" +#include "sky/engine/wtf/HashSet.h" +#include "sky/engine/wtf/OwnPtr.h" + +namespace sky { +namespace shell { + +class DartLibraryProviderNetwork : public blink::DartLibraryProvider { + public: + explicit DartLibraryProviderNetwork(mojo::NetworkService* network_service); + ~DartLibraryProviderNetwork() override; + + mojo::NetworkService* network_service() const { return network_service_; } + + protected: + // |DartLibraryProvider| implementation: + void GetLibraryAsStream(const String& name, + blink::DataPipeConsumerCallback callback) override; + Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override; + + private: + class Job; + + mojo::NetworkService* network_service_; + HashSet> jobs_; + + DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderNetwork); +}; + +} // namespace shell +} // namespace sky + +#endif // SKY_SHELL_DART_DART_LIBRARY_PROVIDER_NETWORK_H_ diff --git a/shell/ios/sky_surface.mm b/shell/ios/sky_surface.mm index d676ebdae7f..a99cadd3dde 100644 --- a/shell/ios/sky_surface.mm +++ b/shell/ios/sky_surface.mm @@ -131,7 +131,7 @@ static sky::InputEventPtr BasicInputEventFromRecognizer( self.platformView->ConnectToViewportObserver(interface_request.Pass()); mojo::String string(self.skyInitialLoadURL.UTF8String); - _viewport_observer->LoadURL(string); + _viewport_observer->RunFromNetwork(string); } - (void)notifySurfaceDestruction { diff --git a/shell/linux/main.cc b/shell/linux/main.cc index a6b021bd7b1..56fd84f5ae3 100644 --- a/shell/linux/main.cc +++ b/shell/linux/main.cc @@ -17,6 +17,9 @@ namespace sky { namespace shell { +const char kMain[] = "main"; +const char kPackageRoot[] = "package-root"; + void Init() { Shell::Init(make_scoped_ptr(new ServiceProviderContext( base::MessageLoop::current()->task_runner()))); @@ -27,8 +30,12 @@ void Init() { ViewportObserverPtr viewport_observer; shell_view->view()->ConnectToViewportObserver(GetProxy(&viewport_observer)); - // TODO(abarth): At this point we should load some content into the view. - // viewport_observer->LoadURL("https://domokit.github.io/home.dart"); + base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); + + std::string main = command_line.GetSwitchValueASCII(kMain); + std::string package_root = command_line.GetSwitchValueASCII(kPackageRoot); + + viewport_observer->RunFromFile(main, package_root); } } // namespace shell diff --git a/shell/ui/engine.cc b/shell/ui/engine.cc index 726f1d3c6ef..6e35f098aae 100644 --- a/shell/ui/engine.cc +++ b/shell/ui/engine.cc @@ -15,6 +15,8 @@ #include "sky/engine/public/web/WebSettings.h" #include "sky/engine/public/web/WebView.h" #include "sky/services/platform/platform_impl.h" +#include "sky/shell/dart/dart_library_provider_files.h" +#include "sky/shell/dart/dart_library_provider_network.h" #include "sky/shell/service_provider.h" #include "sky/shell/ui/animator.h" #include "sky/shell/ui/input_event_converter.h" @@ -184,18 +186,45 @@ void Engine::OnInputEvent(InputEventPtr event) { web_view_->handleInputEvent(*web_event); } -void Engine::LoadURL(const mojo::String& mojo_url) { - GURL url(mojo_url); - if (!blink::WebView::shouldUseWebView(url)) { - if (web_view_) { - web_view_->close(); - web_view_ = nullptr; - } - sky_view_ = blink::SkyView::Create(this); - sky_view_->Load(url); - UpdateSkyViewSize(); +void Engine::CloseWebViewIfNeeded() { + if (web_view_) { + web_view_->close(); + web_view_ = nullptr; + } +} + +void Engine::RunFromLibrary(const mojo::String& name) { + CloseWebViewIfNeeded(); + sky_view_ = blink::SkyView::Create(this); + sky_view_->RunFromLibrary(blink::WebString::fromUTF8(name), + dart_library_provider_.get()); + UpdateSkyViewSize(); +} + +void Engine::RunFromNetwork(const mojo::String& url) { + if (blink::WebView::shouldUseWebView(GURL(url))) { + LoadUsingWebView(url); return; } + dart_library_provider_.reset( + new DartLibraryProviderNetwork(g_platform_impl->networkService())); + RunFromLibrary(url); +} + +void Engine::RunFromFile(const mojo::String& main, + const mojo::String& package_root) { + dart_library_provider_.reset( + new DartLibraryProviderFiles(base::FilePath(package_root))); + RunFromLibrary(main); +} + +void Engine::RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot) { + // TODO(abarth): Implement. +} + +void Engine::LoadUsingWebView(const mojo::String& mojo_url) { + GURL url(mojo_url); + DCHECK(blink::WebView::shouldUseWebView(url)); if (sky_view_) sky_view_ = nullptr; @@ -250,8 +279,9 @@ mojo::NavigatorHost* Engine::NavigatorHost() { 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)); + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&Engine::RunFromNetwork, GetWeakPtr(), request->url)); } void Engine::DidNavigateLocally(const mojo::String& url) { diff --git a/shell/ui/engine.h b/shell/ui/engine.h index f11960590ed..cfaf073695f 100644 --- a/shell/ui/engine.h +++ b/shell/ui/engine.h @@ -69,7 +69,11 @@ class Engine : public UIDelegate, void OnViewportMetricsChanged(int width, int height, float device_pixel_ratio) override; void OnInputEvent(InputEventPtr event) override; - void LoadURL(const mojo::String& url) override; + + void RunFromNetwork(const mojo::String& url) override; + void RunFromFile(const mojo::String& main, + const mojo::String& package_root) override; + void RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot) override; // WebViewClient methods: void frameDetached(blink::WebFrame*) override; @@ -95,12 +99,17 @@ class Engine : public UIDelegate, void DidNavigateLocally(const mojo::String& url) override; void RequestNavigateHistory(int32_t delta) override; + void RunFromLibrary(const mojo::String& name); + void CloseWebViewIfNeeded(); + void LoadUsingWebView(const mojo::String& mojo_url); + void UpdateSkyViewSize(); void UpdateWebViewSize(); Config config_; scoped_ptr animator_; + scoped_ptr dart_library_provider_; std::unique_ptr sky_view_; blink::WebView* web_view_; diff --git a/viewer/BUILD.gn b/viewer/BUILD.gn index 20505a9f756..5db00001443 100644 --- a/viewer/BUILD.gn +++ b/viewer/BUILD.gn @@ -15,6 +15,8 @@ mojo_native_application("viewer") { "converters/basic_types.h", "converters/input_event_types.cc", "converters/input_event_types.h", + "dart_library_provider_impl.cc", + "dart_library_provider_impl.h", "document_view.cc", "document_view.h", "internals.cc", @@ -53,6 +55,7 @@ mojo_native_application("viewer") { "//sky/engine/tonic", "//sky/services/platform", "//sky/services/testing:bindings", + "//sky/shell/dart", "//third_party/icu", "//ui/events", "//url", diff --git a/viewer/dart_library_provider_impl.cc b/viewer/dart_library_provider_impl.cc new file mode 100644 index 00000000000..a0d2bee895f --- /dev/null +++ b/viewer/dart_library_provider_impl.cc @@ -0,0 +1,38 @@ +// 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/viewer/dart_library_provider_impl.h" + +namespace sky { + +DartLibraryProviderImpl::PrefetchedLibrary::PrefetchedLibrary() { +} + +DartLibraryProviderImpl::PrefetchedLibrary::~PrefetchedLibrary() { +} + +DartLibraryProviderImpl::DartLibraryProviderImpl( + mojo::NetworkService* network_service, + scoped_ptr prefetched) + : shell::DartLibraryProviderNetwork(network_service), + prefetched_library_(prefetched.Pass()) { +} + +DartLibraryProviderImpl::~DartLibraryProviderImpl() { +} + +void DartLibraryProviderImpl::GetLibraryAsStream( + const String& name, + blink::DataPipeConsumerCallback callback) { + if (prefetched_library_ && prefetched_library_->name == name) { + mojo::ScopedDataPipeConsumerHandle pipe = prefetched_library_->pipe.Pass(); + prefetched_library_ = nullptr; + callback.Run(pipe.Pass()); + return; + } + + shell::DartLibraryProviderNetwork::GetLibraryAsStream(name, callback); +} + +} // namespace sky diff --git a/viewer/dart_library_provider_impl.h b/viewer/dart_library_provider_impl.h new file mode 100644 index 00000000000..705975ec766 --- /dev/null +++ b/viewer/dart_library_provider_impl.h @@ -0,0 +1,38 @@ +// 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 SKY_VIEWER_DART_LIBRARY_PROVIDER_IMPL_H_ +#define SKY_VIEWER_DART_LIBRARY_PROVIDER_IMPL_H_ + +#include "base/memory/scoped_ptr.h" +#include "sky/shell/dart/dart_library_provider_network.h" + +namespace sky { + +class DartLibraryProviderImpl : public shell::DartLibraryProviderNetwork { + public: + struct PrefetchedLibrary { + PrefetchedLibrary(); + ~PrefetchedLibrary(); + + String name; + mojo::ScopedDataPipeConsumerHandle pipe; + }; + + explicit DartLibraryProviderImpl(mojo::NetworkService* network_service, + scoped_ptr prefetched); + ~DartLibraryProviderImpl() override; + + private: + void GetLibraryAsStream(const String& name, + blink::DataPipeConsumerCallback callback) override; + + scoped_ptr prefetched_library_; + + DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderImpl); +}; + +} // namespace sky + +#endif // SKY_VIEWER_DART_LIBRARY_PROVIDER_IMPL_H_ diff --git a/viewer/document_view.cc b/viewer/document_view.cc index 1e0bb78e79b..9e22009d38b 100644 --- a/viewer/document_view.cc +++ b/viewer/document_view.cc @@ -36,13 +36,13 @@ #include "sky/engine/public/web/WebView.h" #include "sky/services/platform/url_request_types.h" #include "sky/viewer/converters/input_event_types.h" +#include "sky/viewer/dart_library_provider_impl.h" #include "sky/viewer/internals.h" #include "sky/viewer/runtime_flags.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkDevice.h" #include "ui/events/gestures/gesture_recognizer.h" -#include "v8/include/v8.h" namespace sky { namespace { @@ -94,6 +94,18 @@ scoped_ptr ConvertToUITouchEvent( base::TimeDelta::FromMillisecondsD(pointer_event.timeStampMS))); } +scoped_ptr +CreatePrefetchedLibraryIfNeeded(const String& name, + mojo::URLResponsePtr response) { + scoped_ptr prefetched; + if (response->status_code == 200) { + prefetched.reset(new DartLibraryProviderImpl::PrefetchedLibrary()); + prefetched->name = name; + prefetched->pipe = response->body.Pass(); + } + return prefetched.Pass(); +} + } // namespace DocumentView::DocumentView( @@ -161,9 +173,13 @@ void DocumentView::Load(mojo::URLResponsePtr response) { GURL responseURL(response->url); if (!blink::WebView::shouldUseWebView(responseURL)) { + String name = String::fromUTF8(responseURL.spec()); + library_provider_.reset(new DartLibraryProviderImpl( + blink::Platform::current()->networkService(), + CreatePrefetchedLibraryIfNeeded(name, response.Pass()))); sky_view_ = blink::SkyView::Create(this); initializeLayerTreeView(); - sky_view_->Load(responseURL, response.Pass()); + sky_view_->RunFromLibrary(name, library_provider_.get()); return; } diff --git a/viewer/document_view.h b/viewer/document_view.h index 76b8cbe8dfb..6b6c798e04e 100644 --- a/viewer/document_view.h +++ b/viewer/document_view.h @@ -29,7 +29,6 @@ #include "sky/services/testing/test_harness.mojom.h" #include "ui/events/gestures/gesture_types.h" - namespace mojo { class ViewManager; class View; @@ -40,6 +39,7 @@ class Rasterizer; class RasterizerBitmap; class Layer; class LayerHost; +class DartLibraryProviderImpl; class DocumentView : public blink::ServiceProvider, public blink::WebFrameClient, @@ -149,12 +149,14 @@ class DocumentView : public blink::ServiceProvider, blink::WebView* web_view_; mojo::View* root_; mojo::ViewManagerClientFactory view_manager_client_factory_; + scoped_ptr library_provider_; scoped_ptr layer_host_; scoped_refptr root_layer_; RasterizerBitmap* bitmap_rasterizer_; // Used for pixel tests. mojo::ServiceRegistryPtr service_registry_; scoped_ptr> service_registry_service_provider_binding_; + base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(DocumentView);