summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authormtomasz <mtomasz@chromium.org>2014-09-01 00:56:20 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-01 07:58:26 +0000
commit47501847827d29b4ba148a161a521eb3cd5b0730 (patch)
treea8cf902ba1474430f4bff20df37934fe6ce22cc2 /chrome/renderer
parente0ce97e9f1afa1f28c1c1261e5372d03b2af1cdb (diff)
downloadchromium_src-47501847827d29b4ba148a161a521eb3cd5b0730.zip
chromium_src-47501847827d29b4ba148a161a521eb3cd5b0730.tar.gz
chromium_src-47501847827d29b4ba148a161a521eb3cd5b0730.tar.bz2
[fsp] Add support for providing thumbnails.
Previously, thumbnails were generated from full size images, which in case of cloud providers would invoke downloading the entire file. This CL adds an ability to provide a thumbnail as a data URI, so: (1) We can have thumbnails for other file types than images. (2) Thumbnails are shown fast. (3) Resource consumption is significantly reduced. Note, that the thumbnails are not wired to Files app yet. That will be done in a separate patch. TEST=unit_tests: *FileSystemProvider*GetMetadata* BUG=407954 Review URL: https://codereview.chromium.org/513683002 Cr-Commit-Position: refs/heads/master@{#292840}
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js60
1 files changed, 60 insertions, 0 deletions
diff --git a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
index 020c772..86a07b6 100644
--- a/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_system_provider_custom_bindings.js
@@ -12,6 +12,22 @@ var fileSystemNatives = requireNative('file_system_natives');
var GetDOMError = fileSystemNatives.GetDOMError;
/**
+ * Maximum size of the thumbnail in bytes.
+ * @type {number}
+ * @const
+ */
+var METADATA_THUMBNAIL_SIZE_LIMIT = 32 * 1024 * 1024;
+
+/**
+ * Regular expression to validate if the thumbnail URI is a valid data URI,
+ * taking into account allowed formats.
+ * @type {RegExp}
+ * @const
+ */
+var METADATA_THUMBNAIL_FORMAT = new RegExp(
+ '^data:image/(png|jpeg|webp);', 'i');
+
+/**
* Annotates a date with its serialized value.
* @param {Date} date Input date.
* @return {Date} Date with an extra <code>value</code> attribute.
@@ -24,6 +40,19 @@ function annotateDate(date) {
}
/**
+ * Verifies if the passed image URI is valid.
+ * @param {*} uri Image URI.
+ * @return {boolean} True if valid, valse otherwise.
+ */
+function verifyImageURI(uri) {
+ // The URI is specified by a user, so the type may be incorrect.
+ if (typeof uri != 'string' && !(uri instanceof String))
+ return false;
+
+ return METADATA_THUMBNAIL_FORMAT.test(uri);
+}
+
+/**
* Annotates an entry metadata by serializing its modifiedTime value.
* @param {EntryMetadata} metadata Input metadata.
* @return {EntryMetadata} metadata Annotated metadata, which can be passed
@@ -38,6 +67,8 @@ function annotateMetadata(metadata) {
};
if ('mimeType' in metadata)
result.mimeType = metadata.mimeType;
+ if ('thumbnail' in metadata)
+ result.thumbnail = metadata.thumbnail;
return result;
}
@@ -141,6 +172,25 @@ eventBindings.registerArgumentMassager(
var executionStart = Date.now();
var options = args[0];
var onSuccessCallback = function(metadata) {
+ // It is invalid to return a thumbnail when it's not requested. The
+ // restriction is added in order to avoid fetching the thumbnail while
+ // it's not needed.
+ if (!options.thumbnail && metadata.thumbnail) {
+ fileSystemProviderInternal.operationRequestedError(
+ options.fileSystemId, options.requestId, 'FAILED',
+ Date.now() - executionStart);
+ throw new Error('Thumbnail data provided, but not requested.');
+ }
+
+ // Check the format and size. Note, that in the C++ layer, there is
+ // another sanity check to avoid passing any evil URL.
+ if ('thumbnail' in metadata && !verifyImageURI(metadata.thumbnail))
+ throw new Error('Thumbnail format invalid.');
+ if ('thumbnail' in metadata &&
+ metadata.thumbnail.length > METADATA_THUMBNAIL_SIZE_LIMIT) {
+ throw new Error('Thumbnail data too large.');
+ }
+
fileSystemProviderInternal.getMetadataRequestedSuccess(
options.fileSystemId,
options.requestId,
@@ -162,6 +212,16 @@ eventBindings.registerArgumentMassager(
var options = args[0];
var onSuccessCallback = function(entries, hasNext) {
var annotatedEntries = entries.map(annotateMetadata);
+ // It is invalid to return a thumbnail when it's not requested.
+ annotatedEntries.forEach(function(metadata) {
+ if (metadata.thumbnail) {
+ fileSystemProviderInternal.operationRequestedError(
+ options.fileSystemId, options.requestId, 'FAILED',
+ Date.now() - executionStart);
+ throw new Error(
+ 'Thumbnails must not be provided when reading a directory.');
+ }
+ });
fileSystemProviderInternal.readDirectoryRequestedSuccess(
options.fileSystemId, options.requestId, annotatedEntries, hasNext,
Date.now() - executionStart);