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