From b23f07e5c7146b213a9a45d2e23bb1f9373cefcf Mon Sep 17 00:00:00 2001 From: John McCutchan Date: Mon, 1 Aug 2016 12:30:44 -0700 Subject: [PATCH] Initial modified libraries support (#2845) --- DEPS | 2 +- flutter/tonic/dart_isolate_reloader.cc | 19 +++++++++--- flutter/tonic/dart_library_loader.cc | 15 ++++++++-- flutter/tonic/dart_library_loader.h | 2 +- flutter/tonic/dart_library_provider.h | 3 +- sky/engine/core/script/dart_init.cc | 25 ++++++++++++++++ .../core/script/dart_service_isolate.cc | 6 ++-- sky/shell/dart/dart_library_provider_files.cc | 3 +- sky/shell/diagnostic/diagnostic_server.cc | 1 + sky/tools/sky_snapshot/loader.cc | 30 ++++++++++++++----- 10 files changed, 85 insertions(+), 21 deletions(-) diff --git a/DEPS b/DEPS index 7a1f1baf82469..fbd93d2ce7e83 100644 --- a/DEPS +++ b/DEPS @@ -25,7 +25,7 @@ vars = { # Note: When updating the Dart revision, ensure that all entries that are # dependencies of dart are also updated - 'dart_revision': 'd37ea681f5d80a3ab150b709baaeb1fef7a12cae', + 'dart_revision': '59e67cc36d0877949719160de8959a11db4a8027', 'dart_boringssl_revision': 'daeafc22c66ad48f6b32fc8d3362eb9ba31b774e', 'dart_observatory_packages_revision': 'e5e1e543bea10d4bed95b22ad3e7aa2b20a23584', 'dart_root_certificates_revision': 'aed07942ce98507d2be28cbd29e879525410c7fc', diff --git a/flutter/tonic/dart_isolate_reloader.cc b/flutter/tonic/dart_isolate_reloader.cc index e31a4d38f2c7b..17fdf3dad5c66 100644 --- a/flutter/tonic/dart_isolate_reloader.cc +++ b/flutter/tonic/dart_isolate_reloader.cc @@ -30,11 +30,13 @@ class DartIsolateReloader::LoadResult { LoadResult(intptr_t tag, const std::string& url, const std::string& library_url, + const std::string& resolved_url, std::vector payload) : success_(true), tag_(tag), url_(url), library_url_(library_url), + resolved_url_(resolved_url), payload_(std::move(payload)) { DCHECK(success()); } @@ -58,6 +60,10 @@ class DartIsolateReloader::LoadResult { return StdStringToDart(error_); } Dart_Handle uri = StdStringToDart(url_); + Dart_Handle resolved_uri = Dart_Null(); + if (!resolved_url_.empty()) { + resolved_uri = StdStringToDart(resolved_url_); + } Dart_Handle library = Dart_Null(); if (!library_url_.empty()) { library = Dart_LookupLibrary(StdStringToDart(library_url_)); @@ -67,13 +73,13 @@ class DartIsolateReloader::LoadResult { Dart_Handle result = Dart_Null(); switch (tag_) { case Dart_kImportTag: - result = Dart_LoadLibrary(uri, source, 0, 0); + result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0); break; case Dart_kSourceTag: - result = Dart_LoadSource(library, uri, source, 0, 0); + result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0); break; case Dart_kScriptTag: - result = Dart_LoadScript(uri, source, 0, 0); + result = Dart_LoadScript(uri, resolved_uri, source, 0, 0); break; } @@ -88,6 +94,7 @@ class DartIsolateReloader::LoadResult { intptr_t tag_; std::string url_; std::string library_url_; + std::string resolved_url_; std::string error_; std::vector payload_; }; @@ -153,7 +160,8 @@ class DartIsolateReloader::LoadRequest : public DataPipeDrainer::Client { } protected: - void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle pipe) { + void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle pipe, + const std::string& resolved_url) { if (!pipe.is_valid()) { std::unique_ptr result( new DartIsolateReloader::LoadResult( @@ -167,6 +175,7 @@ class DartIsolateReloader::LoadRequest : public DataPipeDrainer::Client { delete this; return; } + resolved_url_ = resolved_url; drainer_.reset(new DataPipeDrainer(this, pipe.Pass())); } @@ -182,6 +191,7 @@ class DartIsolateReloader::LoadRequest : public DataPipeDrainer::Client { new DartIsolateReloader::LoadResult(tag_, url_, library_url_, + resolved_url_, std::move(buffer_))); isolate_reloader_->PostResult(std::move(result)); // We are finished with this request. @@ -193,6 +203,7 @@ class DartIsolateReloader::LoadRequest : public DataPipeDrainer::Client { intptr_t tag_; std::string url_; std::string library_url_; + std::string resolved_url_; std::vector buffer_; std::unique_ptr drainer_; diff --git a/flutter/tonic/dart_library_loader.cc b/flutter/tonic/dart_library_loader.cc index eb4ced1da7e8f..fce46b5d82a81 100644 --- a/flutter/tonic/dart_library_loader.cc +++ b/flutter/tonic/dart_library_loader.cc @@ -5,6 +5,8 @@ #include "flutter/tonic/dart_library_loader.h" #include "base/callback.h" +#include "base/strings/string_util.h" +#include "base/files/file_util.h" #include "base/trace_event/trace_event.h" #include "flutter/tonic/dart_api_scope.h" #include "flutter/tonic/dart_converter.h" @@ -46,18 +48,23 @@ class DartLibraryLoader::Job : public DartDependency, const std::string& name() const { return name_; } + const std::string& resolved_url() const { return resolved_url_; } + protected: DartLibraryLoader* loader_; // TODO(abarth): Should we be using SharedBuffer to buffer the data? std::vector buffer_; private: - void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle pipe) { + void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle pipe, + const std::string& resolved_url) { if (!pipe.is_valid()) { loader_->DidFailJob(this); return; } - drainer_ = std::unique_ptr(new DataPipeDrainer(this, pipe.Pass())); + resolved_url_ = resolved_url; + drainer_ = std::unique_ptr( + new DataPipeDrainer(this, pipe.Pass())); } // DataPipeDrainer::Client @@ -68,6 +75,7 @@ class DartLibraryLoader::Job : public DartDependency, // Subclasses must implement OnDataComplete. std::string name_; + std::string resolved_url_; std::unique_ptr drainer_; base::WeakPtrFactory weak_factory_; @@ -291,11 +299,13 @@ void DartLibraryLoader::DidCompleteImportJob( if (job->should_load_as_script()) { result = Dart_LoadScript( StdStringToDart(job->name()), + StdStringToDart(job->resolved_url()), Dart_NewStringFromUTF8(buffer.data(), buffer.size()), 0, 0); } else { result = Dart_LoadLibrary( StdStringToDart(job->name()), + StdStringToDart(job->resolved_url()), Dart_NewStringFromUTF8(buffer.data(), buffer.size()), 0, 0); } @@ -319,6 +329,7 @@ void DartLibraryLoader::DidCompleteSourceJob( Dart_Handle result = Dart_LoadSource( Dart_HandleFromPersistent(job->library()), StdStringToDart(job->name()), + StdStringToDart(job->resolved_url()), Dart_NewStringFromUTF8(buffer.data(), buffer.size()), 0, 0); if (Dart_IsError(result)) { diff --git a/flutter/tonic/dart_library_loader.h b/flutter/tonic/dart_library_loader.h index 8177aed9d247a..236d60b0ea3c8 100644 --- a/flutter/tonic/dart_library_loader.h +++ b/flutter/tonic/dart_library_loader.h @@ -31,7 +31,7 @@ class DartLibraryLoader { ~DartLibraryLoader(); // TODO(dart): This can be called both on the main thread from application - // solates or from the handle watcher isolate thread. + // isolates or from the handle watcher isolate thread. static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url); diff --git a/flutter/tonic/dart_library_provider.h b/flutter/tonic/dart_library_provider.h index 774368fe21ed7..340bf6d634e06 100644 --- a/flutter/tonic/dart_library_provider.h +++ b/flutter/tonic/dart_library_provider.h @@ -13,7 +13,8 @@ namespace blink { -typedef base::Callback +typedef base::Callback DataPipeConsumerCallback; class DartLibraryProvider { diff --git a/sky/engine/core/script/dart_init.cc b/sky/engine/core/script/dart_init.cc index 2aea22777dd60..c7d6008b73c00 100644 --- a/sky/engine/core/script/dart_init.cc +++ b/sky/engine/core/script/dart_init.cc @@ -130,6 +130,29 @@ void IsolateShutdownCallback(void* callback_data) { delete dart_state; } +bool DartFileModifiedCallback(const char* source_url, + int64_t since_ms) { + std::string url(source_url); + if (!base::StartsWithASCII(url, "file:", true)) { + // Assume modified. + return true; + } + base::ReplaceFirstSubstringAfterOffset(&url, 0, "file:", ""); + base::FilePath path(url); + base::File::Info file_info; + if (!base::GetFileInfo(path, &file_info)) { + // Assume modified. + return true; + } + int64_t since_seconds = since_ms / base::Time::kMillisecondsPerSecond; + int64_t since_milliseconds = + since_ms - (since_seconds * base::Time::kMillisecondsPerSecond); + base::Time since_time = base::Time::FromTimeT(since_seconds) + + base::TimeDelta::FromMilliseconds(since_milliseconds); + // TODO(johnmccutchan): Remove 'true ||' after Todd's fix has landed. + return true || file_info.last_modified > since_time; +} + void ThreadExitCallback() { #ifdef OS_ANDROID DartJni::OnThreadExit(); @@ -564,6 +587,8 @@ void InitDartVM() { Dart_SetEmbedderTimelineCallbacks(&EmbedderTimelineStartRecording, &EmbedderTimelineStopRecording); + Dart_SetFileModifiedCallback(&DartFileModifiedCallback); + { TRACE_EVENT0("flutter", "Dart_Initialize"); char* init_error = Dart_Initialize( diff --git a/sky/engine/core/script/dart_service_isolate.cc b/sky/engine/core/script/dart_service_isolate.cc index fabe92ca1a22c..6ebd685f3e55a 100644 --- a/sky/engine/core/script/dart_service_isolate.cc +++ b/sky/engine/core/script/dart_service_isolate.cc @@ -188,13 +188,13 @@ Dart_Handle DartServiceIsolate::GetSource(const char* name) { Dart_Handle DartServiceIsolate::LoadScript(const char* name) { Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_sky"); Dart_Handle source = GetSource(name); - return Dart_LoadScript(url, source, 0, 0); + return Dart_LoadScript(url, Dart_Null(), source, 0, 0); } Dart_Handle DartServiceIsolate::LoadSource(Dart_Handle library, const char* name) { Dart_Handle url = Dart_NewStringFromCString(name); Dart_Handle source = GetSource(name); - return Dart_LoadSource(library, url, source, 0, 0); + return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0); } Dart_Handle DartServiceIsolate::LoadResource(Dart_Handle library, @@ -282,7 +282,7 @@ Dart_Handle DartServiceIsolate::LibraryTagHandler(Dart_LibraryTag tag, if (Dart_IsError(source)) { return source; } - return Dart_LoadSource(library, url, source, 0, 0); + return Dart_LoadSource(library, url, Dart_Null(), source, 0, 0); } diff --git a/sky/shell/dart/dart_library_provider_files.cc b/sky/shell/dart/dart_library_provider_files.cc index 8c4f989b51015..fcb5210331612 100644 --- a/sky/shell/dart/dart_library_provider_files.cc +++ b/sky/shell/dart/dart_library_provider_files.cc @@ -88,9 +88,10 @@ void DartLibraryProviderFiles::GetLibraryAsStream( const std::string& name, blink::DataPipeConsumerCallback callback) { mojo::DataPipe pipe; - callback.Run(pipe.consumer_handle.Pass()); base::FilePath path = GetFilePathForURL(name); base::FilePath source = base::MakeAbsoluteFilePath(path); + std::string source_url = "file://" + source.value(); + callback.Run(pipe.consumer_handle.Pass(), source_url); scoped_refptr runner = base::WorkerPool::GetTaskRunner(true); mojo::common::CopyFromFile(source, pipe.producer_handle.Pass(), 0, diff --git a/sky/shell/diagnostic/diagnostic_server.cc b/sky/shell/diagnostic/diagnostic_server.cc index 214b9f1db9126..ad14a17e5981f 100644 --- a/sky/shell/diagnostic/diagnostic_server.cc +++ b/sky/shell/diagnostic/diagnostic_server.cc @@ -80,6 +80,7 @@ void DiagnosticServer::Start() { Dart_Handle diagnostic_library = Dart_LoadLibrary( Dart_NewStringFromCString("dart:diagnostic_server"), + Dart_Null(), Dart_NewStringFromUTF8(reinterpret_cast(source), source_length), 0, 0); diff --git a/sky/tools/sky_snapshot/loader.cc b/sky/tools/sky_snapshot/loader.cc index cd020a3f4947e..61697fff15b07 100644 --- a/sky/tools/sky_snapshot/loader.cc +++ b/sky/tools/sky_snapshot/loader.cc @@ -67,7 +67,7 @@ class Loader { base::FilePath GetFilePathForURL(std::string url); base::FilePath GetFilePathForPackageURL(std::string url); base::FilePath GetFilePathForFileURL(std::string url); - std::string Fetch(const std::string& url); + std::string Fetch(const std::string& url, std::string* resolved_url); Dart_Handle Import(Dart_Handle url); Dart_Handle Source(Dart_Handle library, Dart_Handle url); @@ -159,10 +159,13 @@ base::FilePath Loader::GetFilePathForFileURL(std::string url) { return base::FilePath(url); } -std::string Loader::Fetch(const std::string& url) { +std::string Loader::Fetch(const std::string& url, + std::string* resolved_url) { base::FilePath path = GetFilePathForURL(url); + base::FilePath absolute_path = base::MakeAbsoluteFilePath(path); + *resolved_url = "file://" + absolute_path.value(); std::string source; - if (!base::ReadFileToString(base::MakeAbsoluteFilePath(path), &source)) { + if (!base::ReadFileToString(absolute_path, &source)) { fprintf(stderr, "error: Unable to find Dart library '%s'.\n", url.c_str()); exit(1); } @@ -171,15 +174,22 @@ std::string Loader::Fetch(const std::string& url) { } Dart_Handle Loader::Import(Dart_Handle url) { - Dart_Handle source = StringToDart(Fetch(StringFromDart(url))); - Dart_Handle result = Dart_LoadLibrary(url, source, 0, 0); + std::string resolved_url; + Dart_Handle source = StringToDart(Fetch(StringFromDart(url), &resolved_url)); + Dart_Handle result = Dart_LoadLibrary(url, + StringToDart(resolved_url), + source, 0, 0); LogIfError(result); return result; } Dart_Handle Loader::Source(Dart_Handle library, Dart_Handle url) { - Dart_Handle source = StringToDart(Fetch(StringFromDart(url))); - Dart_Handle result = Dart_LoadSource(library, url, source, 0, 0); + std::string resolved_url; + Dart_Handle source = StringToDart(Fetch(StringFromDart(url), &resolved_url)); + Dart_Handle result = Dart_LoadSource(library, + url, + StringToDart(resolved_url), + source, 0, 0); LogIfError(result); return result; } @@ -226,8 +236,12 @@ Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, } void LoadScript(const std::string& url) { + std::string resolved_url; + Dart_Handle source = StringToDart(GetLoader().Fetch(url, &resolved_url)); LogIfError( - Dart_LoadScript(StringToDart(url), StringToDart(GetLoader().Fetch(url)), + Dart_LoadScript(StringToDart(url), + StringToDart(resolved_url), + source, 0, 0)); }