提交 1a1ef489 编写于 作者: A Adam Barth

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.
上级 6c205c6a
......@@ -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",
......
......@@ -226,7 +226,8 @@ PassRefPtr<Document> 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();
......
......@@ -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<DartLibraryProviderNetwork::PrefetchedLibrary>
CreatePrefetchedLibraryIfNeeded(const KURL& url,
mojo::URLResponsePtr response) {
OwnPtr<DartLibraryProviderNetwork::PrefetchedLibrary> 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<DOMDartState> 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<DartState*>(dom_dart_state_.get()), &error);
dom_dart_state_->url().utf8().data(), "main", kDartIsolateSnapshotBuffer,
nullptr, static_cast<DartState*>(dom_dart_state_.get()), &error);
Dart_SetMessageNotifyCallback(MessageNotifyCallback);
CHECK(isolate) << error;
dom_dart_state_->SetIsolate(isolate);
......
......@@ -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<void(RefPtr<AbstractModule>, RefPtr<DartValue>)>
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<DOMDartState> dom_dart_state_;
OwnPtr<BuiltinSky> builtin_sky_;
OwnPtr<DartLibraryProviderNetwork> library_provider_;
OwnPtr<DartLibraryProviderWebView> library_provider_;
OwnPtr<DartSnapshotLoader> snapshot_loader_;
base::WeakPtrFactory<DartController> weak_factory_;
......
......@@ -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<void(mojo::ScopedDataPipeConsumerHandle)>
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<MojoFetcher> fetcher_;
};
DartLibraryProviderNetwork::PrefetchedLibrary::PrefetchedLibrary() {
}
DartLibraryProviderNetwork::PrefetchedLibrary::~PrefetchedLibrary() {
DartLibraryProviderWebView::DartLibraryProviderWebView() {
}
DartLibraryProviderNetwork::DartLibraryProviderNetwork(
PassOwnPtr<PrefetchedLibrary> prefetched)
: prefetched_library_(prefetched) {
DartLibraryProviderWebView::~DartLibraryProviderWebView() {
}
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:"))
......
......@@ -2,8 +2,8 @@
// 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_
#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"
......@@ -11,18 +11,10 @@
namespace blink {
class DartLibraryProviderNetwork : public DartLibraryProvider {
class DartLibraryProviderWebView : public DartLibraryProvider {
public:
struct PrefetchedLibrary {
PrefetchedLibrary();
~PrefetchedLibrary();
String name;
mojo::ScopedDataPipeConsumerHandle pipe;
};
explicit DartLibraryProviderNetwork(PassOwnPtr<PrefetchedLibrary> prefetched);
~DartLibraryProviderNetwork() override;
explicit DartLibraryProviderWebView();
~DartLibraryProviderWebView() override;
private:
class Job;
......@@ -30,15 +22,14 @@ class DartLibraryProviderNetwork : public DartLibraryProvider {
// |DartLibraryProvider| implementation:
void GetLibraryAsStream(
const String& name,
base::Callback<void(mojo::ScopedDataPipeConsumerHandle)> callback)
DataPipeConsumerCallback callback)
override;
Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override;
OwnPtr<PrefetchedLibrary> prefetched_library_;
HashSet<OwnPtr<Job>> jobs_;
};
} // namespace blink
#endif // SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_NETWORK_H_
#endif // SKY_ENGINE_CORE_SCRIPT_DART_LIBRARY_PROVIDER_WEBVIEW_H_
......@@ -9,7 +9,7 @@
namespace blink {
DOMDartState::DOMDartState(Document* document, const KURL& url)
DOMDartState::DOMDartState(Document* document, const String& url)
: document_(document), url_(url) {
}
......
......@@ -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> document_;
KURL url_;
String url_;
DartPersistentValue x_handle_;
DartPersistentValue y_handle_;
......
......@@ -32,16 +32,13 @@
#define SKY_ENGINE_PUBLIC_PLATFORM_WEBSTRING_H_
#include <string>
#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;
......
......@@ -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 += [
......
......@@ -19,18 +19,12 @@
namespace blink {
class SkyView::Data {
public:
RefPtr<View> view_;
};
std::unique_ptr<SkyView> SkyView::Create(SkyViewClient* client) {
return std::unique_ptr<SkyView>(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;
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);
}
void SkyView::RunFromLibrary(const WebString& name,
DartLibraryProvider* library_provider) {
CreateView(name);
dart_controller_->RunFromLibrary(name, library_provider);
}
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<SkPicture> SkyView::Paint() {
if (Picture* picture = data_->view_->picture())
if (Picture* picture = view_->picture())
return skia::SharePtr(picture->toSkia());
return skia::RefPtr<SkPicture>();
}
......@@ -85,22 +66,40 @@ void SkyView::HandleInputEvent(const WebInputEvent& inputEvent) {
if (WebInputEvent::isPointerEventType(inputEvent.type)) {
const WebPointerEvent& event = static_cast<const WebPointerEvent&>(inputEvent);
data_->view_->handleInputEvent(PointerEvent::create(event));
view_->handleInputEvent(PointerEvent::create(event));
} else if (WebInputEvent::isGestureEventType(inputEvent.type)) {
const WebGestureEvent& event = static_cast<const WebGestureEvent&>(inputEvent);
data_->view_->handleInputEvent(GestureEvent::create(event));
view_->handleInputEvent(GestureEvent::create(event));
} else if (WebInputEvent::isKeyboardEventType(inputEvent.type)) {
const WebKeyboardEvent& event = static_cast<const WebKeyboardEvent&>(inputEvent);
data_->view_->handleInputEvent(KeyboardEvent::create(event));
view_->handleInputEvent(KeyboardEvent::create(event));
} else if (WebInputEvent::isWheelEventType(inputEvent.type)) {
const WebWheelEvent& event = static_cast<const WebWheelEvent&>(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();
}
......
......@@ -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<SkPicture> 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<DartController> dart_controller_;
std::unique_ptr<Data> data_;
RefPtr<View> view_;
OwnPtr<DartController> dart_controller_;
base::WeakPtrFactory<SkyView> weak_factory_;
......
......@@ -12,15 +12,16 @@
namespace blink {
typedef base::Callback<void(mojo::ScopedDataPipeConsumerHandle)>
DataPipeConsumerCallback;
class DartLibraryProvider {
public:
virtual void GetLibraryAsStream(
const String& name,
base::Callback<void(mojo::ScopedDataPipeConsumerHandle)> 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();
};
......
......@@ -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<data_pipe_consumer> snapshot);
};
......@@ -21,6 +21,7 @@ common_deps = [
"//sky/engine/wtf",
"//sky/services/platform",
"//sky/services/viewport",
"//sky/shell/dart",
"//ui/gfx/geometry",
"//ui/gl",
]
......
......@@ -183,7 +183,7 @@ public class PlatformViewAndroid extends SurfaceView
}
public void loadUrl(String url) {
mViewportObserver.loadUrl(url);
mViewportObserver.runFromNetwork(url);
}
private void attach() {
......
# 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",
]
}
// 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<base::FilePath::StringType> 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<base::TaskRunner> 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
// 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_
// 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<void(mojo::URLResponsePtr)> 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<Job> 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
// 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<OwnPtr<Job>> jobs_;
DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderNetwork);
};
} // namespace shell
} // namespace sky
#endif // SKY_SHELL_DART_DART_LIBRARY_PROVIDER_NETWORK_H_
......@@ -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 {
......
......@@ -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
......
......@@ -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) {
......
......@@ -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> animator_;
scoped_ptr<blink::DartLibraryProvider> dart_library_provider_;
std::unique_ptr<blink::SkyView> sky_view_;
blink::WebView* web_view_;
......
......@@ -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",
......
// 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<PrefetchedLibrary> 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
// 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<PrefetchedLibrary> prefetched);
~DartLibraryProviderImpl() override;
private:
void GetLibraryAsStream(const String& name,
blink::DataPipeConsumerCallback callback) override;
scoped_ptr<PrefetchedLibrary> prefetched_library_;
DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderImpl);
};
} // namespace sky
#endif // SKY_VIEWER_DART_LIBRARY_PROVIDER_IMPL_H_
......@@ -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<ui::TouchEvent> ConvertToUITouchEvent(
base::TimeDelta::FromMillisecondsD(pointer_event.timeStampMS)));
}
scoped_ptr<DartLibraryProviderImpl::PrefetchedLibrary>
CreatePrefetchedLibraryIfNeeded(const String& name,
mojo::URLResponsePtr response) {
scoped_ptr<DartLibraryProviderImpl::PrefetchedLibrary> 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;
}
......
......@@ -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<DartLibraryProviderImpl> library_provider_;
scoped_ptr<LayerHost> layer_host_;
scoped_refptr<Layer> root_layer_;
RasterizerBitmap* bitmap_rasterizer_; // Used for pixel tests.
mojo::ServiceRegistryPtr service_registry_;
scoped_ptr<mojo::StrongBinding<mojo::ServiceProvider>>
service_registry_service_provider_binding_;
base::WeakPtrFactory<DocumentView> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DocumentView);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册