提交 470118b0 编写于 作者: J Jason Simmons

Support spawning new Dart isolates from within a Flutter app

上级 52c516bd
......@@ -21,25 +21,18 @@ void Ignored(bool) {
} // namespace
unzFile ScopedUnzFileTraits::InvalidValue() {
void* ScopedUnzFileTraits::InvalidValue() {
return nullptr;
}
void ScopedUnzFileTraits::Free(unzFile file) {
void ScopedUnzFileTraits::Free(void* file) {
unzClose(file);
}
scoped_refptr<ZipAssetBundle> ZipAssetService::Create(
void ZipAssetService::Create(
InterfaceRequest<AssetBundle> request,
const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner) {
scoped_refptr<ZipAssetBundle> zip_asset_bundle(
new ZipAssetBundle(zip_path, worker_runner.Pass()));
// Register as a Mojo service.
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle) {
new ZipAssetService(request.Pass(), zip_asset_bundle);
return zip_asset_bundle;
}
ZipAssetService::ZipAssetService(
......
......@@ -13,7 +13,6 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/environment/async_waiter.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace mojo {
namespace asset_bundle {
......@@ -24,6 +23,9 @@ class ZipAssetBundle : public base::RefCountedThreadSafe<ZipAssetBundle> {
friend class ZipAssetService;
public:
ZipAssetBundle(const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner);
// AssetBundle implementation
void GetAsStream(
const String& asset_name,
......@@ -40,10 +42,6 @@ class ZipAssetBundle : public base::RefCountedThreadSafe<ZipAssetBundle> {
friend class base::RefCountedThreadSafe<ZipAssetBundle>;
virtual ~ZipAssetBundle();
private:
ZipAssetBundle(const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner);
const base::FilePath zip_path_;
scoped_refptr<base::TaskRunner> worker_runner_;
std::map<String, base::FilePath> overlay_files_;
......@@ -54,11 +52,9 @@ class ZipAssetBundle : public base::RefCountedThreadSafe<ZipAssetBundle> {
// Wrapper that exposes the ZipAssetBundle as a Mojo service.
class ZipAssetService : public AssetBundle {
public:
// Construct a ZipAssetBundle and register it as a Mojo service.
static scoped_refptr<ZipAssetBundle> Create(
static void Create(
InterfaceRequest<AssetBundle> request,
const base::FilePath& zip_path,
scoped_refptr<base::TaskRunner> worker_runner);
const scoped_refptr<ZipAssetBundle>& zip_asset_bundle);
public:
void GetAsStream(
......@@ -76,11 +72,11 @@ class ZipAssetService : public AssetBundle {
};
struct ScopedUnzFileTraits {
static unzFile InvalidValue();
static void Free(unzFile file);
static void* InvalidValue();
static void Free(void* unz_file);
};
typedef base::ScopedGeneric<unzFile, ScopedUnzFileTraits> ScopedUnzFile;
typedef base::ScopedGeneric<void*, ScopedUnzFileTraits> ScopedUnzFile;
// Reads an asset from a ZIP archive and writes it to a Mojo pipe.
class ZipAssetHandler {
......
......@@ -123,12 +123,25 @@ static void InitDartAsync(Dart_Handle builtin_library,
&schedule_microtask));
}
void DartRuntimeHooks::Install(IsolateType isolate_type) {
static void InitDartIo(const std::string& script_uri) {
if (!script_uri.empty()) {
Dart_Handle io_lib = Dart_LookupLibrary(ToDart("dart:io"));
DART_CHECK_VALID(io_lib);
Dart_Handle platform_type = Dart_GetType(io_lib, ToDart("_Platform"),
0, nullptr);
DART_CHECK_VALID(platform_type);
DART_CHECK_VALID(Dart_SetField(
platform_type, ToDart("_nativeScript"), ToDart(script_uri)));
}
}
void DartRuntimeHooks::Install(IsolateType isolate_type, const std::string& script_uri) {
Dart_Handle builtin = Dart_LookupLibrary(ToDart("dart:ui"));
DART_CHECK_VALID(builtin);
InitDartInternal(builtin, isolate_type);
InitDartCore(builtin);
InitDartAsync(builtin, isolate_type);
InitDartIo(script_uri);
}
// Implementation of native functions which are used for some
......
......@@ -18,7 +18,7 @@ class DartRuntimeHooks {
DartIOIsolate,
};
static void Install(IsolateType isolate_type);
static void Install(IsolateType isolate_type, const std::string& script_uri);
static void RegisterNatives(DartLibraryNatives* natives);
private:
......
dart:io,::,_setupHooks
dart:io,_Platform,set:_nativeScript
dart:isolate,::,_startMainIsolate
dart:mojo.internal,MojoHandleWatcher,mojoControlHandle
dart:ui,::,_beginFrame
......
......@@ -66,6 +66,7 @@ static_library("core") {
":generate_sky_embedder_service_isolate_resources_cc",
":libraries",
":prerequisites",
"//services/asset_bundle:lib",
"//sky/engine/platform",
"//sky/engine/bindings",
"//sky/services/engine:interfaces",
......
......@@ -193,7 +193,8 @@ void DartController::CreateIsolateFor(std::unique_ptr<DOMDartState> state) {
DartIO::InitForIsolate();
DartUI::InitForIsolate();
DartMojoInternal::InitForIsolate();
DartRuntimeHooks::Install(DartRuntimeHooks::MainIsolate);
DartRuntimeHooks::Install(DartRuntimeHooks::MainIsolate,
dom_dart_state_->url().c_str());
dart_state()->class_library().add_provider(
"ui",
......
......@@ -13,6 +13,7 @@
#include "dart/runtime/bin/embedded_dart_io.h"
#include "dart/runtime/include/dart_mirrors_api.h"
#include "mojo/public/platform/dart/dart_handle_watcher.h"
#include "services/asset_bundle/zip_asset_bundle.h"
#include "sky/engine/bindings/dart_mojo_internal.h"
#include "sky/engine/bindings/dart_runtime_hooks.h"
#include "sky/engine/bindings/dart_ui.h"
......@@ -51,6 +52,10 @@ extern const uint8_t* observatory_assets_archive;
namespace blink {
using mojo::asset_bundle::ZipAssetBundle;
const char kSnapshotAssetKey[] = "snapshot_blob.bin";
Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
......@@ -59,13 +64,6 @@ Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag,
namespace {
void CreateEmptyRootLibraryIfNeeded() {
if (Dart_IsNull(Dart_RootLibrary())) {
Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), Dart_EmptyString(),
0, 0);
}
}
static const char* kDartArgs[] = {
"--enable_mirrors=false",
// Dart assumes ARM devices are insufficiently powerful and sets the
......@@ -100,6 +98,8 @@ static const char* kDartStartPausedArgs[]{
"--pause_isolates_on_start",
};
const char kFileUriPrefix[] = "file://";
void IsolateShutdownCallback(void* callback_data) {
// TODO(dart)
}
......@@ -138,7 +138,7 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
#ifdef OS_ANDROID
DartJni::InitForIsolate();
#endif
DartRuntimeHooks::Install(DartRuntimeHooks::DartIOIsolate);
DartRuntimeHooks::Install(DartRuntimeHooks::DartIOIsolate, "");
const SkySettings& settings = SkySettings::Get();
if (settings.enable_observatory) {
std::string ip = "127.0.0.1";
......@@ -152,11 +152,19 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
return isolate;
}
// Create & start the handle watcher isolate
// TODO(abarth): Who deletes this DartState instance?
std::vector<uint8_t> snapshot_data;
if (!IsRunningPrecompiledCode()) {
CHECK(base::StartsWith(script_uri, kFileUriPrefix,
base::CompareCase::SENSITIVE));
base::FilePath flx_path(script_uri + strlen(kFileUriPrefix));
scoped_refptr<ZipAssetBundle> zip_asset_bundle(
new ZipAssetBundle(flx_path, nullptr));
CHECK(zip_asset_bundle->GetAsBuffer(kSnapshotAssetKey, &snapshot_data));
}
DartState* dart_state = new DartState();
Dart_Isolate isolate = Dart_CreateIsolate(
"sky:handle_watcher", "",
script_uri, main,
reinterpret_cast<uint8_t*>(DART_SYMBOL(kDartIsolateSnapshotBuffer)),
nullptr, dart_state, error);
CHECK(isolate) << error;
......@@ -172,9 +180,12 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
#ifdef OS_ANDROID
DartJni::InitForIsolate();
#endif
DartRuntimeHooks::Install(DartRuntimeHooks::MainIsolate, script_uri);
if (!script_uri)
CreateEmptyRootLibraryIfNeeded();
if (!snapshot_data.empty()) {
CHECK(!LogIfError(Dart_LoadScriptFromSnapshot(
snapshot_data.data(), snapshot_data.size())));
}
}
Dart_ExitIsolate();
......
......@@ -33,6 +33,9 @@ extern void* kDartIsolateSnapshotBuffer;
#endif // DART_ALLOW_DYNAMIC_RESOLUTION
// Name of the snapshot blob asset within the FLX bundle.
extern const char kSnapshotAssetKey[];
bool IsRunningPrecompiledCode();
void InitDartVM();
......
......@@ -51,12 +51,12 @@ void SkyView::PopRoute() {
GetWindow()->PopRoute();
}
void SkyView::CreateView(const std::string& name) {
void SkyView::CreateView(const std::string& script_uri) {
DCHECK(!dart_controller_);
dart_controller_ = WTF::MakeUnique<DartController>();
dart_controller_->CreateIsolateFor(WTF::MakeUnique<DOMDartState>(
WTF::MakeUnique<Window>(this), name));
WTF::MakeUnique<Window>(this), script_uri));
DOMDartState* dart_state = dart_controller_->dart_state();
DartState::Scope scope(dart_state);
......@@ -76,8 +76,7 @@ void SkyView::RunFromPrecompiledSnapshot() {
dart_controller_->RunFromPrecompiledSnapshot();
}
void SkyView::RunFromSnapshot(const std::string& name,
mojo::ScopedDataPipeConsumerHandle snapshot) {
void SkyView::RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot) {
dart_controller_->RunFromSnapshot(snapshot.Pass());
}
......
......@@ -47,13 +47,12 @@ class SkyView : public WindowClient {
std::unique_ptr<flow::LayerTree> BeginFrame(
base::TimeTicks frame_time);
void CreateView(const std::string& name);
void CreateView(const std::string& script_uri);
void RunFromLibrary(const std::string& name,
DartLibraryProvider* library_provider);
void RunFromPrecompiledSnapshot();
void RunFromSnapshot(const std::string& name,
mojo::ScopedDataPipeConsumerHandle snapshot);
void RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot);
void HandlePointerPacket(const pointer::PointerPacketPtr& packet);
......
......@@ -13,6 +13,8 @@
#include "mojo/public/cpp/application/connect.h"
#include "services/asset_bundle/zip_asset_bundle.h"
#include "sky/engine/bindings/mojo_services.h"
#include "sky/engine/core/script/dart_init.h"
#include "sky/engine/core/script/dom_dart_state.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
#include "sky/engine/public/platform/WebInputEvent.h"
#include "sky/engine/public/web/Sky.h"
......@@ -28,8 +30,6 @@ namespace sky {
namespace shell {
namespace {
const char kSnapshotKey[] = "snapshot_blob.bin";
PlatformImpl* g_platform_impl = nullptr;
} // namespace
......@@ -172,12 +172,13 @@ void Engine::RunFromLibrary(const std::string& name) {
}
void Engine::RunFromSnapshotStream(
const std::string& name,
const std::string& bundle_path,
mojo::ScopedDataPipeConsumerHandle snapshot) {
TRACE_EVENT0("flutter", "Engine::RunFromSnapshotStream");
std::string script_uri = std::string("file://") + bundle_path;
sky_view_ = blink::SkyView::Create(this);
sky_view_->CreateView(name);
sky_view_->RunFromSnapshot(name, snapshot.Pass());
sky_view_->CreateView(script_uri);
sky_view_->RunFromSnapshot(snapshot.Pass());
sky_view_->SetDisplayMetrics(display_metrics_);
sky_view_->SetLocale(language_code_, country_code_);
if (!initial_route_.empty())
......@@ -188,10 +189,9 @@ void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) {
TRACE_EVENT0("flutter", "Engine::RunFromPrecompiledSnapshot");
std::string path_str = bundle_path;
zip_asset_bundle_ = ZipAssetService::Create(
mojo::GetProxy(&root_bundle_),
base::FilePath(path_str),
base::WorkerPool::GetTaskRunner(true));
zip_asset_bundle_ = new ZipAssetBundle(
base::FilePath(path_str), base::WorkerPool::GetTaskRunner(true));
ZipAssetService::Create(mojo::GetProxy(&root_bundle_), zip_asset_bundle_);
sky_view_ = blink::SkyView::Create(this);
sky_view_->CreateView("http://localhost");
......@@ -214,12 +214,11 @@ void Engine::RunFromFile(const mojo::String& main,
void Engine::RunFromBundle(const mojo::String& path) {
TRACE_EVENT0("flutter", "Engine::RunFromBundle");
std::string path_str = path;
zip_asset_bundle_ = ZipAssetService::Create(
mojo::GetProxy(&root_bundle_),
base::FilePath(path_str),
base::WorkerPool::GetTaskRunner(true));
zip_asset_bundle_ = new ZipAssetBundle(
base::FilePath(path_str), base::WorkerPool::GetTaskRunner(true));
ZipAssetService::Create(mojo::GetProxy(&root_bundle_), zip_asset_bundle_);
root_bundle_->GetAsStream(kSnapshotKey,
root_bundle_->GetAsStream(blink::kSnapshotAssetKey,
base::Bind(&Engine::RunFromSnapshotStream,
weak_factory_.GetWeakPtr(), path_str));
}
......@@ -228,16 +227,15 @@ void Engine::RunFromBundleAndSnapshot(const mojo::String& bundle_path,
const mojo::String& snapshot_path) {
TRACE_EVENT0("flutter", "Engine::RunFromBundleAndSnapshot");
std::string bundle_path_str = bundle_path;
zip_asset_bundle_ = ZipAssetService::Create(
mojo::GetProxy(&root_bundle_),
base::FilePath(bundle_path_str),
base::WorkerPool::GetTaskRunner(true));
zip_asset_bundle_ = new ZipAssetBundle(
base::FilePath(bundle_path_str), base::WorkerPool::GetTaskRunner(true));
ZipAssetService::Create(mojo::GetProxy(&root_bundle_), zip_asset_bundle_);
std::string snapshot_path_str = snapshot_path;
zip_asset_bundle_->AddOverlayFile(kSnapshotKey,
zip_asset_bundle_->AddOverlayFile(blink::kSnapshotAssetKey,
base::FilePath(snapshot_path_str));
root_bundle_->GetAsStream(kSnapshotKey,
root_bundle_->GetAsStream(blink::kSnapshotAssetKey,
base::Bind(&Engine::RunFromSnapshotStream,
weak_factory_.GetWeakPtr(),
bundle_path_str));
......@@ -275,8 +273,9 @@ void Engine::OnAppLifecycleStateChanged(sky::AppLifecycleState state) {
void Engine::DidCreateIsolate(Dart_Isolate isolate) {
blink::MojoServices::Create(isolate, services_.Pass(), root_bundle_.Pass());
if (zip_asset_bundle_)
if (zip_asset_bundle_) {
FlutterFontSelector::install(zip_asset_bundle_);
}
}
void Engine::StopAnimator() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册