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 // If directory files changes too often, don't rescan directory more than once | 5 // If directory files changes too often, don't rescan directory more than once |
6 // per specified interval | 6 // per specified interval |
7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; | 7 var SIMULTANEOUS_RESCAN_INTERVAL = 1000; |
8 // Used for operations that require almost instant rescan. | 8 // Used for operations that require almost instant rescan. |
9 var SHORT_RESCAN_INTERVAL = 100; | 9 var SHORT_RESCAN_INTERVAL = 100; |
10 | 10 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
46 * A map root.fullPath -> currentDirectory.fullPath. | 46 * A map root.fullPath -> currentDirectory.fullPath. |
47 * @private | 47 * @private |
48 * @type {Object.<string, string>} | 48 * @type {Object.<string, string>} |
49 */ | 49 */ |
50 this.currentDirByRoot_ = {}; | 50 this.currentDirByRoot_ = {}; |
51 | 51 |
52 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. | 52 // The map 'name' -> callback. Callbacks are function(entry) -> boolean. |
53 this.filters_ = {}; | 53 this.filters_ = {}; |
54 this.setFilterHidden(true); | 54 this.setFilterHidden(true); |
55 | 55 |
56 // Readonly status. | 56 /** @type {Hash.<srting, boolead>} */ |
Vladislav Kaznacheev
2012/04/25 08:43:11
2 typos
SeRya
2012/04/25 10:15:16
Done.
| |
57 this.readonly_ = false; | 57 this.volumeReadOnlyStatus_ = {}; |
58 this.currentVolumeMetadata_ = {rootPath: '/'}; | |
59 this.offline_ = false; | 58 this.offline_ = false; |
60 } | 59 } |
61 | 60 |
62 /** | 61 /** |
63 * The name of the directory containing externally | 62 * The name of the directory containing externally |
64 * mounted removable storage volumes. | 63 * mounted removable storage volumes. |
65 */ | 64 */ |
66 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; | 65 DirectoryModel.REMOVABLE_DIRECTORY = 'removable'; |
67 | 66 |
68 /** | 67 /** |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 * @return {string} Root name. | 131 * @return {string} Root name. |
133 */ | 132 */ |
134 DirectoryModel.prototype.getRootName = function() { | 133 DirectoryModel.prototype.getRootName = function() { |
135 return DirectoryModel.getRootName(this.currentDirEntry_.fullPath); | 134 return DirectoryModel.getRootName(this.currentDirEntry_.fullPath); |
136 }; | 135 }; |
137 | 136 |
138 /** | 137 /** |
139 * @return {boolean} True if current directory is read only. | 138 * @return {boolean} True if current directory is read only. |
140 */ | 139 */ |
141 DirectoryModel.prototype.isReadOnly = function() { | 140 DirectoryModel.prototype.isReadOnly = function() { |
142 return this.readonly_; | 141 return this.isPathReadOnly(this.getCurrentRootPath()); |
143 }; | 142 }; |
144 | 143 |
145 /** | 144 /** |
145 * @param {strin} path Path to check. | |
146 * @return {boolean} True if the |path| is read only. | |
147 */ | |
148 DirectoryModel.prototype.isPathReadOnly = function(path) { | |
149 switch (DirectoryModel.getRootType(path)) { | |
150 case DirectoryModel.RootType.REMOVABLE: | |
151 return !!this.volumeReadOnlyStatus_[DirectoryModel.getRootPath(path)]; | |
152 case DirectoryModel.RootType.ARCHIVE: | |
153 return true; | |
154 case DirectoryModel.RootType.DOWNLOADS: | |
155 return false; | |
156 case DirectoryModel.RootType.GDATA: | |
157 return this.offline_; | |
Vladislav Kaznacheev
2012/04/25 08:43:11
Lets use !navigator.onLine directly and remove the
SeRya
2012/04/25 10:15:16
Done.
| |
158 default: | |
159 return true; | |
160 } | |
161 }; | |
162 | |
163 /** | |
146 * @return {boolean} If offline. | 164 * @return {boolean} If offline. |
147 */ | 165 */ |
148 DirectoryModel.prototype.isOffline = function() { | 166 DirectoryModel.prototype.isOffline = function() { |
149 return this.offline_; | 167 return this.offline_; |
150 }; | 168 }; |
151 | 169 |
152 /** | 170 /** |
153 * @param {boolean} value New online status. | 171 * @param {boolean} value New online status. |
154 */ | 172 */ |
155 DirectoryModel.prototype.setOffline = function(value) { | 173 DirectoryModel.prototype.setOffline = function(value) { |
156 if (this.offline_ != value) { | 174 if (this.offline_ != value) { |
157 this.offline_ = !!value; | 175 this.offline_ = !!value; |
158 this.updateReadonlyStatus_(); | |
159 } | 176 } |
160 }; | 177 }; |
161 | 178 |
162 /** | 179 /** |
163 * @return {boolean} If current directory is system. | 180 * @return {boolean} If current directory is system. |
164 */ | 181 */ |
165 DirectoryModel.prototype.isSystemDirectory = function() { | 182 DirectoryModel.prototype.isSystemDirectory = function() { |
166 var path = this.currentDirEntry_.fullPath; | 183 var path = this.currentDirEntry_.fullPath; |
167 return path == '/' || | 184 return path == '/' || |
168 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || | 185 path == '/' + DirectoryModel.REMOVABLE_DIRECTORY || |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
701 DirectoryModel.prototype.changeDirectoryEntry_ = function(dirEntry, action, | 718 DirectoryModel.prototype.changeDirectoryEntry_ = function(dirEntry, action, |
702 initial) { | 719 initial) { |
703 var previous = this.currentDirEntry_; | 720 var previous = this.currentDirEntry_; |
704 this.currentDirEntry_ = dirEntry; | 721 this.currentDirEntry_ = dirEntry; |
705 function onRescanComplete() { | 722 function onRescanComplete() { |
706 action(); | 723 action(); |
707 // For tests that open the dialog to empty directories, everything | 724 // For tests that open the dialog to empty directories, everything |
708 // is loaded at this point. | 725 // is loaded at this point. |
709 chrome.test.sendMessage('directory-change-complete'); | 726 chrome.test.sendMessage('directory-change-complete'); |
710 } | 727 } |
711 this.updateReadonlyStatus_(); | |
712 this.updateVolumeMetadata_(); | |
713 this.updateRootsListSelection_(); | 728 this.updateRootsListSelection_(); |
714 this.scan_(onRescanComplete); | 729 this.scan_(onRescanComplete); |
715 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath; | 730 this.currentDirByRoot_[this.getCurrentRootPath()] = dirEntry.fullPath; |
716 | 731 |
717 var e = new cr.Event('directory-changed'); | 732 var e = new cr.Event('directory-changed'); |
718 e.previousDirEntry = previous; | 733 e.previousDirEntry = previous; |
719 e.newDirEntry = dirEntry; | 734 e.newDirEntry = dirEntry; |
720 e.initial = initial; | 735 e.initial = initial; |
721 this.dispatchEvent(e); | 736 this.dispatchEvent(e); |
722 }; | 737 }; |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
908 * @param {function(Array.<Entry>)} callback Called when roots are resolved. | 923 * @param {function(Array.<Entry>)} callback Called when roots are resolved. |
909 * @param {boolean} resolveGData See comment for updateRoots. | 924 * @param {boolean} resolveGData See comment for updateRoots. |
910 */ | 925 */ |
911 DirectoryModel.prototype.resolveRoots_ = function(callback, resolveGData) { | 926 DirectoryModel.prototype.resolveRoots_ = function(callback, resolveGData) { |
912 var groups = { | 927 var groups = { |
913 downloads: null, | 928 downloads: null, |
914 archives: null, | 929 archives: null, |
915 removables: null, | 930 removables: null, |
916 gdata: null | 931 gdata: null |
917 }; | 932 }; |
933 var self = this; | |
918 | 934 |
919 metrics.startInterval('Load.Roots'); | 935 metrics.startInterval('Load.Roots'); |
920 function done() { | 936 function done() { |
921 for (var i in groups) | 937 for (var i in groups) |
922 if (!groups[i]) | 938 if (!groups[i]) |
923 return; | 939 return; |
924 | 940 |
941 self.updateVolumeReadOnlyStatus_(groups.removables); | |
925 callback(groups.downloads. | 942 callback(groups.downloads. |
926 concat(groups.gdata). | 943 concat(groups.gdata). |
927 concat(groups.archives). | 944 concat(groups.archives). |
928 concat(groups.removables)); | 945 concat(groups.removables)); |
929 metrics.recordInterval('Load.Roots'); | 946 metrics.recordInterval('Load.Roots'); |
930 } | 947 } |
931 | 948 |
932 function append(index, values, opt_error) { | 949 function append(index, values, opt_error) { |
933 groups[index] = values; | 950 groups[index] = values; |
934 done(); | 951 done(); |
935 } | 952 } |
936 | 953 |
937 function onDownloads(entry) { | 954 function onDownloads(entry) { |
938 groups.downloads = [entry]; | 955 groups.downloads = [entry]; |
939 done(); | 956 done(); |
940 } | 957 } |
941 | 958 |
942 function onDownloadsError(error) { | 959 function onDownloadsError(error) { |
943 groups.downloads = []; | 960 groups.downloads = []; |
944 done(); | 961 done(); |
945 } | 962 } |
946 | 963 |
947 var self = this; | |
948 | |
949 function onGData(entry) { | 964 function onGData(entry) { |
950 console.log('GData found:', entry); | 965 console.log('GData found:', entry); |
951 self.unmountedGDataEntry_ = null; | 966 self.unmountedGDataEntry_ = null; |
952 groups.gdata = [entry]; | 967 groups.gdata = [entry]; |
953 done(); | 968 done(); |
954 } | 969 } |
955 | 970 |
956 function onGDataError(error) { | 971 function onGDataError(error) { |
957 console.log('GData error: ', error); | 972 console.log('GData error: ', error); |
958 self.unmountedGDataEntry_ = { | 973 self.unmountedGDataEntry_ = { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1037 | 1052 |
1038 /** | 1053 /** |
1039 * @private | 1054 * @private |
1040 */ | 1055 */ |
1041 DirectoryModel.prototype.updateRootsListSelection_ = function() { | 1056 DirectoryModel.prototype.updateRootsListSelection_ = function() { |
1042 var rootPath = DirectoryModel.getRootPath(this.currentDirEntry_.fullPath); | 1057 var rootPath = DirectoryModel.getRootPath(this.currentDirEntry_.fullPath); |
1043 this.rootsListSelection_.selectedIndex = this.findRootsListItem_(rootPath); | 1058 this.rootsListSelection_.selectedIndex = this.findRootsListItem_(rootPath); |
1044 }; | 1059 }; |
1045 | 1060 |
1046 /** | 1061 /** |
1062 * @param {Array.<DirectoryEntry>} roots Removable volumes entries. | |
1047 * @private | 1063 * @private |
1048 */ | 1064 */ |
1049 DirectoryModel.prototype.updateReadonlyStatus_ = function() { | 1065 DirectoryModel.prototype.updateVolumeReadOnlyStatus_ = function(roots) { |
1050 switch (this.getRootType()) { | 1066 var status = this.volumeReadOnlyStatus_ = {}; |
1051 case DirectoryModel.RootType.REMOVABLE: | 1067 for (var i = 0; i < roots.length; i++) { |
1052 this.readonly_ = !!this.currentVolumeMetadata_.isReadOnly; | 1068 status[roots[i].fullPath] = false; |
1053 break; | 1069 chrome.fileBrowserPrivate.getVolumeMetadata(roots[i].toURL(), |
Vladislav Kaznacheev
2012/04/25 08:43:11
It looks like you are making this call for all roo
SeRya
2012/04/25 10:15:16
No, it's for removable only (I mentioned in JsDoc)
| |
1054 case DirectoryModel.RootType.ARCHIVE: | 1070 function(systemMetadata, path) { |
1055 this.readonly_ = true; | 1071 status[path] = !!(systemMetadata && systemMetadata.isReadOnly); |
1056 break; | 1072 }.bind(null, roots[i].fullPath)); |
1057 case DirectoryModel.RootType.DOWNLOADS: | |
1058 this.readonly_ = false; | |
1059 break; | |
1060 case DirectoryModel.RootType.GDATA: | |
1061 this.readonly_ = this.offline_; | |
1062 break; | |
1063 default: | |
1064 this.readonly_ = true; | |
1065 break; | |
1066 } | 1073 } |
1067 }; | 1074 }; |
1068 | 1075 |
1069 /** | |
1070 * @private | |
1071 */ | |
1072 DirectoryModel.prototype.updateVolumeMetadata_ = function() { | |
1073 var rootPath = this.getCurrentRootPath(); | |
1074 if (this.currentVolumeMetadata_.rootPath != rootPath) { | |
1075 var metadata = this.currentVolumeMetadata_ = {rootPath: rootPath}; | |
1076 if (DirectoryModel.getRootType(rootPath) == | |
1077 DirectoryModel.RootType.REMOVABLE) { | |
1078 var self = this; | |
1079 this.root_.getDirectory(rootPath, {}, function(entry) { | |
1080 chrome.fileBrowserPrivate.getVolumeMetadata(entry.toURL(), | |
1081 function(systemMetadata) { | |
1082 if (systemMetadata) { | |
1083 metadata.isReadOnly = systemMetadata.isReadOnly; | |
1084 self.updateReadonlyStatus_(); | |
1085 } | |
1086 }); | |
1087 }); | |
1088 } | |
1089 } | |
1090 }; | |
1091 | |
1092 /** | 1076 /** |
1093 * Prepare the root for the unmount. | 1077 * Prepare the root for the unmount. |
1094 * | 1078 * |
1095 * @param {string} rootPath The path to the root. | 1079 * @param {string} rootPath The path to the root. |
1096 */ | 1080 */ |
1097 DirectoryModel.prototype.prepareUnmount = function(rootPath) { | 1081 DirectoryModel.prototype.prepareUnmount = function(rootPath) { |
1098 var index = this.findRootsListItem_(rootPath); | 1082 var index = this.findRootsListItem_(rootPath); |
1099 if (index == -1) { | 1083 if (index == -1) { |
1100 console.error('Unknown root entry', rootPath); | 1084 console.error('Unknown root entry', rootPath); |
1101 return; | 1085 return; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1270 /** | 1254 /** |
1271 * @private | 1255 * @private |
1272 */ | 1256 */ |
1273 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { | 1257 DirectoryModel.Scanner.prototype.recordMetrics_ = function() { |
1274 metrics.recordInterval('DirectoryScan'); | 1258 metrics.recordInterval('DirectoryScan'); |
1275 if (this.dir_.fullPath == | 1259 if (this.dir_.fullPath == |
1276 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { | 1260 '/' + DirectoryModel.DOWNLOADS_DIRECTORY) { |
1277 metrics.recordMediumCount('DownloadsCount', this.list_.length); | 1261 metrics.recordMediumCount('DownloadsCount', this.list_.length); |
1278 } | 1262 } |
1279 }; | 1263 }; |
OLD | NEW |