diff options
author | mtomasz <mtomasz@chromium.org> | 2014-09-01 00:56:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-01 07:58:26 +0000 |
commit | 47501847827d29b4ba148a161a521eb3cd5b0730 (patch) | |
tree | a8cf902ba1474430f4bff20df37934fe6ce22cc2 /chrome/renderer | |
parent | e0ce97e9f1afa1f28c1c1261e5372d03b2af1cdb (diff) | |
download | chromium_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.js | 60 |
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); |