OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 'use strict'; | 5 'use strict'; |
6 | 6 |
7 /** | 7 /** |
8 * MetadataCache is a map from Entry to an object containing properties. | 8 * MetadataCache is a map from Entry to an object containing properties. |
9 * Properties are divided by types, and all properties of one type are accessed | 9 * Properties are divided by types, and all properties of one type are accessed |
10 * at once. | 10 * at once. |
11 * Some of the properties: | 11 * Some of the properties: |
12 * { | 12 * { |
13 * filesystem: size, modificationTime | 13 * filesystem: size, modificationTime |
14 * internal: presence | 14 * internal: presence |
15 * drive: pinned, present, hosted, availableOffline | 15 * external: pinned, present, hosted, availableOffline |
16 * | 16 * |
17 * Following are not fetched for non-present drive files. | 17 * Following are not fetched for non-present external files. |
18 * media: artist, album, title, width, height, imageTransform, etc. | 18 * media: artist, album, title, width, height, imageTransform, etc. |
19 * thumbnail: url, transform | 19 * thumbnail: url, transform |
20 * | 20 * |
21 * Following are always fetched from content, and so force the downloading | 21 * Following are always fetched from content, and so force the downloading |
22 * of remote drive files. One should use this for required content metadata, | 22 * of external files. One should use this for required content metadata, |
23 * i.e. image orientation. | 23 * i.e. image orientation. |
24 * fetchedMedia: width, height, etc. | 24 * fetchedMedia: width, height, etc. |
25 * } | 25 * } |
26 * | 26 * |
27 * Typical usages: | 27 * Typical usages: |
28 * { | 28 * { |
29 * cache.get([entry1, entry2], 'drive|filesystem', function(metadata) { | 29 * cache.get([entry1, entry2], 'external|filesystem', function(metadata) { |
30 * if (metadata[0].drive.pinned && metadata[1].filesystem.size === 0) | 30 * if (metadata[0].external.pinned && metadata[1].filesystem.size === 0) |
31 * alert("Pinned and empty!"); | 31 * alert("Pinned and empty!"); |
32 * }); | 32 * }); |
33 * | 33 * |
34 * cache.set(entry, 'internal', {presence: 'deleted'}); | 34 * cache.set(entry, 'internal', {presence: 'deleted'}); |
35 * | 35 * |
36 * cache.clear([fileEntry1, fileEntry2], 'filesystem'); | 36 * cache.clear([fileEntry1, fileEntry2], 'filesystem'); |
37 * | 37 * |
38 * // Getting fresh value. | 38 * // Getting fresh value. |
39 * cache.clear(entry, 'thumbnail'); | 39 * cache.clear(entry, 'thumbnail'); |
40 * cache.getOne(entry, 'thumbnail', function(thumbnail) { | 40 * cache.getOne(entry, 'thumbnail', function(thumbnail) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 /** | 111 /** |
112 * Margin of the cache size. This amount of caches may be kept in addition. | 112 * Margin of the cache size. This amount of caches may be kept in addition. |
113 */ | 113 */ |
114 MetadataCache.EVICTION_THRESHOLD_MARGIN = 500; | 114 MetadataCache.EVICTION_THRESHOLD_MARGIN = 500; |
115 | 115 |
116 /** | 116 /** |
117 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. | 117 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. |
118 * @return {MetadataCache!} The cache with all providers. | 118 * @return {MetadataCache!} The cache with all providers. |
119 */ | 119 */ |
120 MetadataCache.createFull = function(volumeManager) { | 120 MetadataCache.createFull = function(volumeManager) { |
121 // DriveProvider should be prior to FileSystemProvider, because it covers | 121 // ExternalProvider should be prior to FileSystemProvider, because it covers |
122 // FileSystemProvider for files in Drive. | 122 // FileSystemProvider for files on the external backend, eg. Drive. |
123 return new MetadataCache([ | 123 return new MetadataCache([ |
124 new DriveProvider(volumeManager), | 124 new ExternalProvider(volumeManager), |
125 new FilesystemProvider(), | 125 new FilesystemProvider(), |
126 new ContentProvider() | 126 new ContentProvider() |
127 ]); | 127 ]); |
128 }; | 128 }; |
129 | 129 |
130 /** | 130 /** |
131 * Clones metadata entry. Metadata entries may contain scalars, arrays, | 131 * Clones metadata entry. Metadata entries may contain scalars, arrays, |
132 * hash arrays and Date object. Other objects are not supported. | 132 * hash arrays and Date object. Other objects are not supported. |
133 * @param {Object} metadata Metadata object. | 133 * @param {Object} metadata Metadata object. |
134 * @return {Object} Cloned entry. | 134 * @return {Object} Cloned entry. |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 size: (entry.isFile ? (metadata.size || 0) : -1), | 751 size: (entry.isFile ? (metadata.size || 0) : -1), |
752 modificationTime: metadata.modificationTime | 752 modificationTime: metadata.modificationTime |
753 } | 753 } |
754 }); | 754 }); |
755 } | 755 } |
756 | 756 |
757 entry.getMetadata(onMetadata.bind(null, entry), onError); | 757 entry.getMetadata(onMetadata.bind(null, entry), onError); |
758 }; | 758 }; |
759 | 759 |
760 /** | 760 /** |
761 * Provider of drive metadata. | 761 * Provider of metadata for entries on the external file system backend. |
762 * This provider returns the following objects: | 762 * This provider returns the following objects: |
763 * drive: { pinned, hosted, present, customIconUrl, etc. } | 763 * external: { pinned, hosted, present, customIconUrl, etc. } |
764 * thumbnail: { url, transform } | 764 * thumbnail: { url, transform } |
765 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. | 765 * @param {VolumeManagerWrapper} volumeManager Volume manager instance. |
766 * @constructor | 766 * @constructor |
767 */ | 767 */ |
768 function DriveProvider(volumeManager) { | 768 function ExternalProvider(volumeManager) { |
769 MetadataProvider.call(this); | 769 MetadataProvider.call(this); |
770 | 770 |
771 /** | 771 /** |
772 * @type {VolumeManagerWrapper} | 772 * @type {VolumeManagerWrapper} |
773 * @private | 773 * @private |
774 */ | 774 */ |
775 this.volumeManager_ = volumeManager; | 775 this.volumeManager_ = volumeManager; |
776 | 776 |
777 // We batch metadata fetches into single API call. | 777 // We batch metadata fetches into single API call. |
778 this.entries_ = []; | 778 this.entries_ = []; |
779 this.callbacks_ = []; | 779 this.callbacks_ = []; |
780 this.scheduled_ = false; | 780 this.scheduled_ = false; |
781 | 781 |
782 this.callApiBound_ = this.callApi_.bind(this); | 782 this.callApiBound_ = this.callApi_.bind(this); |
783 } | 783 } |
784 | 784 |
785 DriveProvider.prototype = { | 785 ExternalProvider.prototype = { |
786 __proto__: MetadataProvider.prototype | 786 __proto__: MetadataProvider.prototype |
787 }; | 787 }; |
788 | 788 |
789 /** | 789 /** |
790 * @param {Entry} entry The entry. | 790 * @param {Entry} entry The entry. |
791 * @return {boolean} Whether this provider supports the entry. | 791 * @return {boolean} Whether this provider supports the entry. |
792 */ | 792 */ |
793 DriveProvider.prototype.supportsEntry = function(entry) { | 793 ExternalProvider.prototype.supportsEntry = function(entry) { |
794 var locationInfo = this.volumeManager_.getLocationInfo(entry); | 794 var locationInfo = this.volumeManager_.getLocationInfo(entry); |
| 795 // TODO(mtomasz): Add support for provided file systems. |
795 return locationInfo && locationInfo.isDriveBased; | 796 return locationInfo && locationInfo.isDriveBased; |
796 }; | 797 }; |
797 | 798 |
798 /** | 799 /** |
799 * @param {string} type The metadata type. | 800 * @param {string} type The metadata type. |
800 * @return {boolean} Whether this provider provides this metadata. | 801 * @return {boolean} Whether this provider provides this metadata. |
801 */ | 802 */ |
802 DriveProvider.prototype.providesType = function(type) { | 803 ExternalProvider.prototype.providesType = function(type) { |
803 return type === 'drive' || type === 'thumbnail' || | 804 return type === 'external' || type === 'thumbnail' || |
804 type === 'media' || type === 'filesystem'; | 805 type === 'media' || type === 'filesystem'; |
805 }; | 806 }; |
806 | 807 |
807 /** | 808 /** |
808 * @return {string} Unique provider id. | 809 * @return {string} Unique provider id. |
809 */ | 810 */ |
810 DriveProvider.prototype.getId = function() { return 'drive'; }; | 811 ExternalProvider.prototype.getId = function() { return 'external'; }; |
811 | 812 |
812 /** | 813 /** |
813 * Fetches the metadata. | 814 * Fetches the metadata. |
814 * @param {Entry} entry File entry. | 815 * @param {Entry} entry File entry. |
815 * @param {string} type Requested metadata type. | 816 * @param {string} type Requested metadata type. |
816 * @param {function(Object)} callback Callback expects a map from metadata type | 817 * @param {function(Object)} callback Callback expects a map from metadata type |
817 * to metadata value. This callback is called asynchronously. | 818 * to metadata value. This callback is called asynchronously. |
818 */ | 819 */ |
819 DriveProvider.prototype.fetch = function(entry, type, callback) { | 820 ExternalProvider.prototype.fetch = function(entry, type, callback) { |
820 this.entries_.push(entry); | 821 this.entries_.push(entry); |
821 this.callbacks_.push(callback); | 822 this.callbacks_.push(callback); |
822 if (!this.scheduled_) { | 823 if (!this.scheduled_) { |
823 this.scheduled_ = true; | 824 this.scheduled_ = true; |
824 setTimeout(this.callApiBound_, 0); | 825 setTimeout(this.callApiBound_, 0); |
825 } | 826 } |
826 }; | 827 }; |
827 | 828 |
828 /** | 829 /** |
829 * Schedules the API call. | 830 * Schedules the API call. |
830 * @private | 831 * @private |
831 */ | 832 */ |
832 DriveProvider.prototype.callApi_ = function() { | 833 ExternalProvider.prototype.callApi_ = function() { |
833 this.scheduled_ = false; | 834 this.scheduled_ = false; |
834 | 835 |
835 var entries = this.entries_; | 836 var entries = this.entries_; |
836 var callbacks = this.callbacks_; | 837 var callbacks = this.callbacks_; |
837 this.entries_ = []; | 838 this.entries_ = []; |
838 this.callbacks_ = []; | 839 this.callbacks_ = []; |
839 var self = this; | 840 var self = this; |
840 | 841 |
841 // TODO(mtomasz): Make getEntryProperties accept Entry instead of URL. | 842 // TODO(mtomasz): Make getEntryProperties accept Entry instead of URL. |
842 var entryURLs = util.entriesToURLs(entries); | 843 var entryURLs = util.entriesToURLs(entries); |
843 chrome.fileBrowserPrivate.getEntryProperties( | 844 chrome.fileBrowserPrivate.getEntryProperties( |
844 entryURLs, | 845 entryURLs, |
845 function(propertiesList) { | 846 function(propertiesList) { |
846 console.assert(propertiesList.length === callbacks.length); | 847 console.assert(propertiesList.length === callbacks.length); |
847 for (var i = 0; i < callbacks.length; i++) { | 848 for (var i = 0; i < callbacks.length; i++) { |
848 callbacks[i](self.convert_(propertiesList[i], entries[i])); | 849 callbacks[i](self.convert_(propertiesList[i], entries[i])); |
849 } | 850 } |
850 }); | 851 }); |
851 }; | 852 }; |
852 | 853 |
853 /** | 854 /** |
854 * Converts API metadata to internal format. | 855 * Converts API metadata to internal format. |
855 * @param {Object} data Metadata from API call. | 856 * @param {Object} data Metadata from API call. |
856 * @param {Entry} entry File entry. | 857 * @param {Entry} entry File entry. |
857 * @return {Object} Metadata in internal format. | 858 * @return {Object} Metadata in internal format. |
858 * @private | 859 * @private |
859 */ | 860 */ |
860 DriveProvider.prototype.convert_ = function(data, entry) { | 861 ExternalProvider.prototype.convert_ = function(data, entry) { |
861 var result = {}; | 862 var result = {}; |
862 result.drive = { | 863 result.external = { |
863 present: data.isPresent, | 864 present: data.isPresent, |
864 pinned: data.isPinned, | 865 pinned: data.isPinned, |
865 hosted: data.isHosted, | 866 hosted: data.isHosted, |
866 imageWidth: data.imageWidth, | 867 imageWidth: data.imageWidth, |
867 imageHeight: data.imageHeight, | 868 imageHeight: data.imageHeight, |
868 imageRotation: data.imageRotation, | 869 imageRotation: data.imageRotation, |
869 availableOffline: data.isAvailableOffline, | 870 availableOffline: data.isAvailableOffline, |
870 availableWhenMetered: data.isAvailableWhenMetered, | 871 availableWhenMetered: data.isAvailableWhenMetered, |
871 customIconUrl: data.customIconUrl || '', | 872 customIconUrl: data.customIconUrl || '', |
872 contentMimeType: data.contentMimeType || '', | 873 contentMimeType: data.contentMimeType || '', |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 | 1085 |
1085 /** | 1086 /** |
1086 * Handles the 'log' message from the worker. | 1087 * Handles the 'log' message from the worker. |
1087 * @param {Array.<*>} arglist Log arguments. | 1088 * @param {Array.<*>} arglist Log arguments. |
1088 * @private | 1089 * @private |
1089 */ | 1090 */ |
1090 ContentProvider.prototype.onLog_ = function(arglist) { | 1091 ContentProvider.prototype.onLog_ = function(arglist) { |
1091 if (MetadataCache.log) // Avoid log spam by default. | 1092 if (MetadataCache.log) // Avoid log spam by default. |
1092 console.log.apply(console, ['metadata:'].concat(arglist)); | 1093 console.log.apply(console, ['metadata:'].concat(arglist)); |
1093 }; | 1094 }; |
OLD | NEW |