diff options
author | bbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-26 23:32:12 +0000 |
---|---|---|
committer | bbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-26 23:32:12 +0000 |
commit | d8e942a682fccb8f96300efa6120f25abc55a52e (patch) | |
tree | aee3bfa74edb97d7b91822405e4c9cd9ed85345b /ppapi | |
parent | 37017fd26a7527fd048405360fa6888bae856a0b (diff) | |
download | chromium_src-d8e942a682fccb8f96300efa6120f25abc55a52e.zip chromium_src-d8e942a682fccb8f96300efa6120f25abc55a52e.tar.gz chromium_src-d8e942a682fccb8f96300efa6120f25abc55a52e.tar.bz2 |
Add progress events for DSO downloads required on startup. Modify the NaCl
plugin to generate progress events for DSOs as well as the .nexe.
BUG=100535
TEST=none
Review URL: http://codereview.chromium.org/8341035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107466 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
4 files changed, 110 insertions, 60 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.h b/ppapi/native_client/src/trusted/plugin/file_downloader.h index 1e9066f..0cbdf2a 100644 --- a/ppapi/native_client/src/trusted/plugin/file_downloader.h +++ b/ppapi/native_client/src/trusted/plugin/file_downloader.h @@ -79,6 +79,9 @@ class FileDownloader { // Returns the url passed to Open(). const nacl::string& url_to_open() const { return url_to_open_; } + // Returns the PP_Resource of the active URL loader, or kInvalidResource. + PP_Resource url_loader() const { return url_loader_.pp_resource(); } + // Returns the buffer used for DOWNLOAD_TO_BUFFER mode. const std::deque<char>& buffer() const { return buffer_; } diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index 9eec3dc..24a0157 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -810,17 +810,31 @@ MethodInfo* Plugin::GetMethodInfo(uintptr_t method_id, CallType call_type) { return method_info; } +// Suggested names for progress event types, per +// http://www.w3.org/TR/progress-events/ +const char* const Plugin::kProgressEventLoadStart = "loadstart"; +const char* const Plugin::kProgressEventProgress = "progress"; +const char* const Plugin::kProgressEventError = "error"; +const char* const Plugin::kProgressEventAbort = "abort"; +const char* const Plugin::kProgressEventLoad = "load"; +const char* const Plugin::kProgressEventLoadEnd = "loadend"; +// Define a NaCl specific event type for .nexe crashes. +const char* const Plugin::kProgressEventCrash = "crash"; + class ProgressEvent { public: ProgressEvent(const char* event_type, + const nacl::string& url, Plugin::LengthComputable length_computable, uint64_t loaded_bytes, uint64_t total_bytes) : event_type_(event_type), + url_(url), length_computable_(length_computable), loaded_bytes_(loaded_bytes), total_bytes_(total_bytes) { } const char* event_type() const { return event_type_; } + const char* url() const { return url_.c_str(); } Plugin::LengthComputable length_computable() const { return length_computable_; } @@ -832,6 +846,7 @@ class ProgressEvent { // not taken. Hence it does not need to be deleted when ProgressEvent is // destroyed. const char* event_type_; + nacl::string url_; Plugin::LengthComputable length_computable_; uint64_t loaded_bytes_; uint64_t total_bytes_; @@ -1193,7 +1208,8 @@ void Plugin::NexeFileDidOpen(int32_t pp_error) { static_cast<float>(nexe_downloader_.TimeSinceOpenMilliseconds())); // Inform JavaScript that we successfully downloaded the nacl module. - EnqueueProgressEvent("progress", + EnqueueProgressEvent(kProgressEventProgress, + nexe_downloader_.url_to_open(), LENGTH_IS_COMPUTABLE, nexe_bytes_read, nexe_bytes_read); @@ -1276,10 +1292,7 @@ void Plugin::BitcodeDidTranslate(int32_t pp_error) { return; } // Inform JavaScript that we successfully translated the bitcode to a nexe. - EnqueueProgressEvent("progress", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventProgress); nacl::scoped_ptr<nacl::DescWrapper> wrapper(pnacl_.ReleaseTranslatedFD()); ErrorInfo error_info; @@ -1422,10 +1435,7 @@ void Plugin::ReportDeadNexe() { set_last_error_string(message); browser_interface()->AddToConsole(this, message); - EnqueueProgressEvent("crash", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventCrash); set_nexe_error_reported(true); CHECK(ppapi_proxy_ == NULL || !ppapi_proxy_->is_valid()); ShutdownProxy(); @@ -1595,10 +1605,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { if (SelectProgramURLFromManifest(&program_url, &error_info, &is_portable)) { set_nacl_ready_state(LOADING); // Inform JavaScript that we found a nexe URL to load. - EnqueueProgressEvent("progress", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventProgress); if (is_portable) { // TODO(jvoung): Do we want to check an ENV var if pnacl is enabled first? nacl::string llc_url; @@ -1622,7 +1629,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { nexe_downloader_.Open(program_url, DOWNLOAD_TO_FILE, open_callback, - &UpdateNexeDownloadProgress)); + &UpdateDownloadProgress)); return; } } @@ -1653,10 +1660,7 @@ void Plugin::RequestNaClManifest(const nacl::string& url) { set_manifest_url(url); // Inform JavaScript that a load is starting. set_nacl_ready_state(OPENED); - EnqueueProgressEvent("loadstart", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventLoadStart); bool is_data_uri = GetUrlScheme(nmf_resolved_url.AsString()) == SCHEME_DATA; HistogramEnumerateManifestIsDataURI(static_cast<int>(is_data_uri)); if (is_data_uri) { @@ -1775,7 +1779,10 @@ bool Plugin::StreamAsFile(const nacl::string& url, return false; } // If true, will always call the callback on success or failure. - return downloader->Open(url, DOWNLOAD_TO_FILE, open_callback, NULL); + return downloader->Open(url, + DOWNLOAD_TO_FILE, + open_callback, + &UpdateDownloadProgress); } #ifndef HACK_FOR_MACOS_HANG_REMOVED @@ -1804,8 +1811,11 @@ void Plugin::ReportLoadSuccess(LengthComputable length_computable, // Set the readyState attribute to indicate loaded. set_nacl_ready_state(DONE); // Inform JavaScript that loading was successful and is complete. - EnqueueProgressEvent("load", length_computable, loaded_bytes, total_bytes); - EnqueueProgressEvent("loadend", length_computable, loaded_bytes, total_bytes); + const nacl::string& url = nexe_downloader_.url_to_open(); + EnqueueProgressEvent( + kProgressEventLoad, url, length_computable, loaded_bytes, total_bytes); + EnqueueProgressEvent( + kProgressEventLoadEnd, url, length_computable, loaded_bytes, total_bytes); // UMA HistogramEnumerateLoadStatus(ERROR_LOAD_SUCCESS); @@ -1826,14 +1836,8 @@ void Plugin::ReportLoadError(const ErrorInfo& error_info) { browser_interface()->AddToConsole(this, message); ShutdownProxy(); // Inform JavaScript that loading encountered an error and is complete. - EnqueueProgressEvent("error", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); - EnqueueProgressEvent("loadend", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventError); + EnqueueProgressEvent(kProgressEventLoadEnd); // UMA HistogramEnumerateLoadStatus(error_info.error_code()); @@ -1851,22 +1855,16 @@ void Plugin::ReportLoadAbort() { browser_interface()->AddToConsole(this, error_string); ShutdownProxy(); // Inform JavaScript that loading was aborted and is complete. - EnqueueProgressEvent("abort", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); - EnqueueProgressEvent("loadend", - LENGTH_IS_NOT_COMPUTABLE, - kUnknownBytes, - kUnknownBytes); + EnqueueProgressEvent(kProgressEventAbort); + EnqueueProgressEvent(kProgressEventLoadEnd); // UMA HistogramEnumerateLoadStatus(ERROR_LOAD_ABORTED); } -void Plugin::UpdateNexeDownloadProgress( +void Plugin::UpdateDownloadProgress( PP_Instance pp_instance, - PP_Resource /*pp_resource*/, + PP_Resource pp_resource, int64_t /*bytes_sent*/, int64_t /*total_bytes_to_be_sent*/, int64_t bytes_received, @@ -1879,7 +1877,14 @@ void Plugin::UpdateNexeDownloadProgress( if (progress > kProgressThreshold) { LengthComputable length_computable = (total_bytes_to_be_received >= 0) ? LENGTH_IS_COMPUTABLE : LENGTH_IS_NOT_COMPUTABLE; - plugin->EnqueueProgressEvent("progress", + // Get the URL for the URL loader that sent this notification. + const FileDownloader* file_downloader = + plugin->FindFileDownloader(pp_resource); + nacl::string url = (file_downloader != NULL) ? + file_downloader->url_to_open() : NACL_NO_URL; + + plugin->EnqueueProgressEvent(kProgressEventProgress, + url, length_computable, bytes_received, total_bytes_to_be_received); @@ -1888,19 +1893,48 @@ void Plugin::UpdateNexeDownloadProgress( } } +const FileDownloader* Plugin::FindFileDownloader( + PP_Resource url_loader) const { + const FileDownloader* file_downloader = NULL; + if (url_loader == nexe_downloader_.url_loader()) { + file_downloader = &nexe_downloader_; + } else { + std::set<FileDownloader*>::const_iterator it = url_downloaders_.begin(); + while (it != url_downloaders_.end()) { + if (url_loader == (*it)->url_loader()) { + file_downloader = (*it); + break; + } + ++it; + } + } + return file_downloader; +} + +void Plugin::EnqueueProgressEvent(const char* event_type) { + EnqueueProgressEvent(event_type, + NACL_NO_URL, + Plugin::LENGTH_IS_NOT_COMPUTABLE, + Plugin::kUnknownBytes, + Plugin::kUnknownBytes); +} + void Plugin::EnqueueProgressEvent(const char* event_type, + const nacl::string& url, LengthComputable length_computable, uint64_t loaded_bytes, uint64_t total_bytes) { PLUGIN_PRINTF(("Plugin::EnqueueProgressEvent (" - "event_type='%s', length_computable=%d, " + "event_type='%s', url='%s', length_computable=%d, " "loaded=%"NACL_PRIu64", total=%"NACL_PRIu64")\n", event_type, + url.c_str(), static_cast<int>(length_computable), loaded_bytes, total_bytes)); progress_events_.push(new ProgressEvent(event_type, + url, length_computable, loaded_bytes, total_bytes)); @@ -1930,20 +1964,23 @@ void Plugin::DispatchProgressEvent(int32_t result) { nacl::scoped_ptr<ProgressEvent> event(progress_events_.front()); progress_events_.pop(); PLUGIN_PRINTF(("Plugin::DispatchProgressEvent (" - "event_type='%s', length_computable=%d, " + "event_type='%s', url='%s', length_computable=%d, " "loaded=%"NACL_PRIu64", total=%"NACL_PRIu64")\n", event->event_type(), + event->url(), static_cast<int>(event->length_computable()), event->loaded_bytes(), event->total_bytes())); static const char* kEventClosureJS = - "(function(target, type, lengthComputable, loadedBytes, totalBytes) {" + "(function(target, type, url," + " lengthComputable, loadedBytes, totalBytes) {" " var progress_event = document.createEvent('ProgressEvent');" " progress_event.initProgressEvent(type, false, true," " lengthComputable," " loadedBytes," " totalBytes);" + " progress_event.url = url;" " target.dispatchEvent(progress_event);" "})"; @@ -1966,13 +2003,14 @@ void Plugin::DispatchProgressEvent(int32_t result) { return; } - pp::Var argv[5]; + pp::Var argv[6]; static const uint32_t argc = NACL_ARRAY_SIZE(argv); argv[0] = owner_element_object; argv[1] = pp::Var(event->event_type()); - argv[2] = pp::Var(event->length_computable() == LENGTH_IS_COMPUTABLE); - argv[3] = pp::Var(static_cast<double>(event->loaded_bytes())); - argv[4] = pp::Var(static_cast<double>(event->total_bytes())); + argv[2] = pp::Var(event->url()); + argv[3] = pp::Var(event->length_computable() == LENGTH_IS_COMPUTABLE); + argv[4] = pp::Var(static_cast<double>(event->loaded_bytes())); + argv[5] = pp::Var(static_cast<double>(event->total_bytes())); // Dispatch the event. const pp::Var default_method; diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index cfac990..cc804b7 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -168,16 +168,28 @@ class Plugin : public pp::InstancePrivate { void ReportLoadError(const ErrorInfo& error_info); // Report loading a module was aborted, typically due to user action. void ReportLoadAbort(); + // Dispatch a JavaScript event to indicate a key step in loading. // |event_type| is a character string indicating which type of progress // event (loadstart, progress, error, abort, load, loadend). Events are // enqueued on the JavaScript event loop, which then calls back through // DispatchProgressEvent. + void EnqueueProgressEvent(const char* event_type); void EnqueueProgressEvent(const char* event_type, + const nacl::string& url, LengthComputable length_computable, uint64_t loaded_bytes, uint64_t total_bytes); + // Progress event types. + static const char* const kProgressEventLoadStart; + static const char* const kProgressEventProgress; + static const char* const kProgressEventError; + static const char* const kProgressEventAbort; + static const char* const kProgressEventLoad; + static const char* const kProgressEventLoadEnd; + static const char* const kProgressEventCrash; + // Report the error code that sel_ldr produces when starting a nexe. void ReportSelLdrLoadStatus(int status); @@ -542,7 +554,8 @@ class Plugin : public pp::InstancePrivate { int64_t ready_time_; size_t nexe_size_; - static void UpdateNexeDownloadProgress( + // Callback to receive .nexe and .dso download progress notifications. + static void UpdateDownloadProgress( PP_Instance pp_instance, PP_Resource pp_resource, int64_t bytes_sent, @@ -550,6 +563,11 @@ class Plugin : public pp::InstancePrivate { int64_t bytes_received, int64_t total_bytes_to_be_received); + // Finds the file downloader which owns the given URL loader. This is used + // in UpdateDownloadProgress to map a url loader back to the URL being + // downloaded. + const FileDownloader* FindFileDownloader(PP_Resource url_loader) const; + int64_t last_event_bytes_received_; }; diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index 1fd57ae..7e35399 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -144,10 +144,7 @@ int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error, NaClSubprocessId PnaclCoordinator::HelperNexeDidLoad(int32_t fd, ErrorInfo* error_info) { // Inform JavaScript that we successfully loaded a helper nexe. - instance_->EnqueueProgressEvent("progress", - Plugin::LENGTH_IS_NOT_COMPUTABLE, - Plugin::kUnknownBytes, - Plugin::kUnknownBytes); + instance_->EnqueueProgressEvent(Plugin::kProgressEventProgress); nacl::scoped_ptr<nacl::DescWrapper> wrapper(instance_->wrapper_factory()->MakeFileDesc(fd, O_RDONLY)); @@ -360,10 +357,7 @@ PnaclCoordinator::RunTranslateDidFinish(int32_t pp_error, return; } SetObjectFile(translate_args_->obj_fd, translate_args_->obj_len); - instance_->EnqueueProgressEvent("progress", - Plugin::LENGTH_IS_NOT_COMPUTABLE, - Plugin::kUnknownBytes, - Plugin::kUnknownBytes); + instance_->EnqueueProgressEvent(Plugin::kProgressEventProgress); delayed_callback->RunIfTime(); } @@ -577,10 +571,7 @@ void PnaclCoordinator::RunLinkDidFinish(int32_t pp_error) { return; } SetTranslatedFile(link_args_->nexe_fd); - instance_->EnqueueProgressEvent("progress", - Plugin::LENGTH_IS_NOT_COMPUTABLE, - Plugin::kUnknownBytes, - Plugin::kUnknownBytes); + instance_->EnqueueProgressEvent(Plugin::kProgressEventProgress); PnaclDidFinish(PP_OK); } |