summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 23:32:12 +0000
committerbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 23:32:12 +0000
commitd8e942a682fccb8f96300efa6120f25abc55a52e (patch)
treeaee3bfa74edb97d7b91822405e4c9cd9ed85345b /ppapi
parent37017fd26a7527fd048405360fa6888bae856a0b (diff)
downloadchromium_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')
-rw-r--r--ppapi/native_client/src/trusted/plugin/file_downloader.h3
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc132
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.h20
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc15
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);
}