Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
1010 lines
28 KiB
JavaScript
Executable file
1010 lines
28 KiB
JavaScript
Executable file
var gListening = false;
|
|
|
|
function humanBytes(bytes) {
|
|
var s = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB', '??'];
|
|
if (bytes == 0) {
|
|
return '0 bytes';
|
|
}
|
|
var e = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + ' ' + s[e];
|
|
}
|
|
|
|
var gStorageType;
|
|
var gStorageTypes = ['pictures', 'sdcard', 'videos', 'music']
|
|
var gDefaultStorage;
|
|
var gVolumeStorages;
|
|
var gListenerStorages;
|
|
|
|
function ds_getStorageType() {
|
|
var typeElt = document.getElementById('ds.type');
|
|
var typeIdx = typeElt.selectedIndex;
|
|
return typeElt.options[typeIdx].value;
|
|
}
|
|
|
|
function ds_changeHandler(storageType, storageName, e) {
|
|
var label = storageType + '/' + storageName;
|
|
switch (e.reason) {
|
|
case 'created':
|
|
case 'modified':
|
|
case 'deleted':
|
|
log('[' + label + "] change path = '" + e.path + "' reason: " + e.reason);
|
|
break;
|
|
case 'available':
|
|
case 'unavailable':
|
|
case 'shared':
|
|
log('[' + label + "] change storageName '" + e.path +
|
|
"' reason: " + e.reason);
|
|
break;
|
|
default:
|
|
log('[' + label + '] change: ' + e.reason);
|
|
break;
|
|
}
|
|
}
|
|
|
|
function ds_defaultStorageChanged(setting) {
|
|
log(setting.settingName + " changed to '" + setting.settingValue + "'");
|
|
}
|
|
|
|
function AddListeners() {
|
|
gListenerStorages = [];
|
|
for (st = 0; st < gStorageTypes.length; st++) {
|
|
var storageType = gStorageTypes[st];
|
|
storages = navigator.getDeviceStorages(storageType);
|
|
for (i = 0; i < storages.length; i++) {
|
|
var storage = storages[i];
|
|
gListenerStorages.push(storage);
|
|
log('Adding listener for ' + storageType + '/' + storage.storageName);
|
|
storage.addEventListener('change',
|
|
ds_changeHandler.bind(this, storageType, storage.storageName));
|
|
}
|
|
}
|
|
navigator.mozSettings.addObserver('device.storage.writable.name', ds_defaultStorageChanged);
|
|
}
|
|
|
|
function RemoveListeners() {
|
|
for (i = 0; i < gListenerStorages.length; i++) {
|
|
gListenerStorages[i].removeEventListener('change', ds_changeHandler);
|
|
}
|
|
navigator.mozSettings.removeObserver('device.storage.writable.name', ds_defaultStorageChanged);
|
|
}
|
|
|
|
function UpdateStorage() {
|
|
var storageType = ds_getStorageType();
|
|
if (storageType == gStorageType) {
|
|
// Update the default storage, since the user can change it in the settings
|
|
// app, and we want to reflect those changes. This app doesn't setup
|
|
// listeners on the default storage, so we don't need to worry about
|
|
// anything there.
|
|
gDefaultStorage = navigator.getDeviceStorage(gStorageType);
|
|
return;
|
|
}
|
|
|
|
if (gListening) {
|
|
RemoveListeners();
|
|
}
|
|
|
|
gStorageType = storageType;
|
|
gDefaultStorage = navigator.getDeviceStorage(gStorageType);
|
|
gVolumeStorages = navigator.getDeviceStorages(gStorageType);
|
|
|
|
if (gListening) {
|
|
AddListeners();
|
|
}
|
|
}
|
|
|
|
function processStorages(obj, storages) {
|
|
var storage;
|
|
var storageIndex = -1;
|
|
|
|
obj.storageType = gStorageType;
|
|
|
|
function processNext(obj) {
|
|
try {
|
|
storageIndex += 1;
|
|
if (storageIndex >= storages.length) {
|
|
if (obj.done) {
|
|
obj.done();
|
|
}
|
|
return;
|
|
}
|
|
obj.storage = storages[storageIndex].storage;
|
|
obj.label = storages[storageIndex].label;
|
|
obj.filename = storages[storageIndex].filename;
|
|
log('Processing ' + obj.label);
|
|
if (storages[storageIndex].storage) {
|
|
obj.storageName = storages[storageIndex].storageName;
|
|
} else {
|
|
obj.storageName = '';
|
|
}
|
|
req = obj.request();
|
|
req.onsuccess = function report_onsuccess(e) {
|
|
try {
|
|
if (obj.onnext) {
|
|
if (e.target.result) {
|
|
obj.onnext(e);
|
|
e.target.continue();
|
|
} else {
|
|
if (obj.onnextdone) {
|
|
obj.onnextdone();
|
|
}
|
|
processNext(obj);
|
|
}
|
|
} else {
|
|
if (obj.onsuccess) {
|
|
obj.onsuccess(e);
|
|
}
|
|
processNext(obj);
|
|
}
|
|
} catch (e) {
|
|
log('report_onsuccess: caught an error');
|
|
log(e);
|
|
log(e.stack);
|
|
}
|
|
};
|
|
req.onerror = function report_onerror(e) {
|
|
if (obj.onerror) {
|
|
obj.onerror(e);
|
|
} else {
|
|
log('report_onerror');
|
|
log(e.target.error.name);
|
|
}
|
|
processNext(obj);
|
|
};
|
|
} catch (e) {
|
|
log('processNext caught an error');
|
|
log(e);
|
|
log(e.stack);
|
|
}
|
|
}
|
|
|
|
if (obj.init) {
|
|
obj.init();
|
|
}
|
|
processNext(obj);
|
|
}
|
|
|
|
function report(obj) {
|
|
UpdateStorage();
|
|
var storages = [];
|
|
for (i = 0; i < gVolumeStorages.length; i++) {
|
|
log('Testing storage [' + gVolumeStorages[i].storageName + ']');
|
|
storages = storages.concat({storage: gVolumeStorages[i],
|
|
label: gVolumeStorages[i].storageName});
|
|
}
|
|
processStorages(obj, storages);
|
|
}
|
|
|
|
function processFile(obj, testAbsolute) {
|
|
if (typeof testAbsolute === 'undefined') {
|
|
testAbsolute = true;
|
|
}
|
|
UpdateStorage();
|
|
var storages = [];
|
|
// Test using a relative path on the default storage area
|
|
log('Testing default storage with a relative path');
|
|
storages = storages.concat({storage: gDefaultStorage,
|
|
label: 'default with relative path',
|
|
storageName: '',
|
|
filename: 'rel-default'});
|
|
|
|
// Test using just a relative filename on the storage objects
|
|
for (i = 0; i < gVolumeStorages.length; i++) {
|
|
log('Testing storage [' + gVolumeStorages[i].storageName +
|
|
'] with a relative path');
|
|
storages = storages.concat({storage: gVolumeStorages[i],
|
|
label: gVolumeStorages[i].storageName +
|
|
' with relative path',
|
|
storageName: '',
|
|
filename: 'rel-' +
|
|
gVolumeStorages[i].storageName});
|
|
}
|
|
if (testAbsolute) {
|
|
// Test the default storage area using an absolute /volume/filename on the
|
|
// storage object.
|
|
for (i = 0; i < gVolumeStorages.length; i++) {
|
|
log('Testing default storage with absolute path');
|
|
storages =
|
|
storages.concat({storage: gDefaultStorage,
|
|
label: 'default with an absolute path',
|
|
storageName: gVolumeStorages[i].storageName,
|
|
filename: 'abs-def-' +
|
|
gVolumeStorages[i].storageName});
|
|
}
|
|
// Test using an absolute /volume/filename on the storage object
|
|
for (i = 0; i < gVolumeStorages.length; i++) {
|
|
log('Testing storage [' + gVolumeStorages[i].storageName +
|
|
'] with absolute path');
|
|
storages =
|
|
storages.concat({storage: gVolumeStorages[i],
|
|
label: gVolumeStorages[i].storageName +
|
|
' with an absolute path',
|
|
storageName: gVolumeStorages[i].storageName,
|
|
filename: 'abs-' +
|
|
gVolumeStorages[i].storageName});
|
|
}
|
|
}
|
|
processStorages(obj, storages);
|
|
}
|
|
|
|
function translateError(err) {
|
|
switch (err) {
|
|
case 'NoModificationAllowedError':
|
|
return 'File Exists';
|
|
case 'NotFoundError':
|
|
return 'File does not exist';
|
|
case 'TypeMismatchError':
|
|
return 'File not enumerable/illegal type';
|
|
case 'SecurityError':
|
|
return 'Permission Denied';
|
|
case 'Unknown':
|
|
return 'Unknown';
|
|
}
|
|
return '*** Unknown ***';
|
|
}
|
|
|
|
function FreeSpace() {}
|
|
FreeSpace.prototype = {
|
|
init: function freeSpace_init() {
|
|
log("Free Space for type '" + this.storageType + "'");
|
|
},
|
|
request: function freeSpace_request() {
|
|
return this.storage.freeSpace();
|
|
},
|
|
onsuccess: function freeSpace_onsuccess(e) {
|
|
log(' ' + this.label + ' = ' + humanBytes(e.target.result));
|
|
}
|
|
};
|
|
|
|
function UsedSpace() {}
|
|
UsedSpace.prototype = {
|
|
init: function usedSpace_init() {
|
|
log("Used Space for type '" + this.storageType + "'");
|
|
},
|
|
request: function usedSpace_request() {
|
|
return this.storage.usedSpace();
|
|
},
|
|
onsuccess: function usedSpace_onsuccess(e) {
|
|
log(' [' + this.label + '] = ' + humanBytes(e.target.result));
|
|
}
|
|
};
|
|
|
|
function Available() {}
|
|
Available.prototype = {
|
|
init: function availSpace_init() {
|
|
log("Available status for type '" + this.storageType + "'");
|
|
},
|
|
request: function availSpace_request() {
|
|
return this.storage.available();
|
|
},
|
|
onsuccess: function availSpace_onsuccess(e) {
|
|
log(' [' + this.label + '] = ' + e.target.result);
|
|
}
|
|
};
|
|
|
|
function Enumerate(dir) {
|
|
this.dir = dir;
|
|
}
|
|
Enumerate.prototype = {
|
|
init: function enumerate_init() {
|
|
log("Enumerate for type '" + this.storageType + "' dir = '" +
|
|
this.dir + "'");
|
|
},
|
|
request: function enumerate_request() {
|
|
log("Enumerate for type '" + this.storageType + "' " + this.label);
|
|
this.fileCount = 0;
|
|
return this.storage.enumerate(this.dir);
|
|
},
|
|
onnext: function enumerate_next(e) {
|
|
log(' ' + e.target.result.name + ' ' + e.target.result.type);
|
|
this.fileCount += 1;
|
|
},
|
|
onnextdone: function enumerate_onnextdone() {
|
|
if (this.fileCount == 0) {
|
|
log(' *** No files found ***');
|
|
}
|
|
}
|
|
};
|
|
|
|
function EnumerateFileSizes() {}
|
|
EnumerateFileSizes.prototype = Object.create(Enumerate.prototype, {
|
|
onnext: {
|
|
value: function enum_fileSizes_next(e) {
|
|
log(' ' + e.target.result.name + ' t:' + e.target.result.type +
|
|
' s:' + e.target.result.size);
|
|
this.fileCount += 1;
|
|
},
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true
|
|
}
|
|
});
|
|
|
|
function AddFile() {}
|
|
AddFile.prototype = {
|
|
request: function addFile_request() {
|
|
this.name = 'test-' + this.filename + '.txt';
|
|
if (this.storageName != '') {
|
|
this.name = '/' + this.storageName + '/' + this.name;
|
|
}
|
|
var now = new Date();
|
|
this.dateStr = now.toString();
|
|
var blob = new Blob([this.dateStr + '\n'], {type: 'text/plain'});
|
|
//log("Adding file '" + this.name + "' with contents '" +
|
|
// this.dateStr + "'");
|
|
return this.storage.addNamed(blob, this.name);
|
|
},
|
|
onsuccess: function addFile_success(e) {
|
|
//log("Added file '" + this.name + "' with contents '" +
|
|
// this.dateStr + "'");
|
|
log("Added file '" + this.name + "' e.target.result = '" +
|
|
e.target.result + "'");
|
|
},
|
|
onerror: function addFile_onerror(e) {
|
|
log("Add file '" + this.name + "' failed");
|
|
log('Reason: ' + e.target.error.name + ' (or ' +
|
|
translateError(e.target.error.name) + ')');
|
|
}
|
|
};
|
|
|
|
function AddUnnamedFile() {}
|
|
AddUnnamedFile.prototype = {
|
|
fileName: [],
|
|
request: function addUnnamedFile_request() {
|
|
this.name = 'test-' + this.filename + '.txt';
|
|
if (this.storageName != '') {
|
|
this.name = '/' + this.storageName + '/' + this.name;
|
|
}
|
|
var now = new Date();
|
|
this.dateStr = now.toString();
|
|
var blob = new Blob([this.dateStr + '\n'], {type: 'text/plain'});
|
|
log('Adding file to storage [' + this.label + ']');
|
|
return this.storage.add(blob);
|
|
},
|
|
onsuccess: function addUnnamedFile_success(e) {
|
|
log(" Added: '" + e.target.result + "'");
|
|
this.fileName.push(e.target.result);
|
|
},
|
|
onerror: function addUnnamedFile_onerror(e) {
|
|
log(" Add '" + e.target.result + "' failed");
|
|
log(' Reason: ' + e.target.error.name + ' (or ' +
|
|
translateError(e.target.error.name) + ')');
|
|
},
|
|
done: function addUnnamedFile_done() {
|
|
if (this.fileName.length == 0) {
|
|
return;
|
|
}
|
|
var filename = this.fileName.shift();
|
|
var req = this.storage.delete(filename);
|
|
function onsuccess(e) {
|
|
log('Deleted ' + e.target.result);
|
|
this.done();
|
|
};
|
|
req.onsuccess = onsuccess.bind(this);
|
|
req.onerror = function(e) {
|
|
log('Delete of ' + e.target.result + ' failed');
|
|
log('Reason: ' + e.target.error.name + ' (or ' +
|
|
translateError(e.target.error.name) + ')');
|
|
};
|
|
}
|
|
};
|
|
|
|
function DelFile() {}
|
|
DelFile.prototype = {
|
|
request: function delFile_request() {
|
|
this.name = 'test-' + this.filename + '.txt';
|
|
if (this.storageName != '') {
|
|
this.name = '/' + this.storageName + '/' + this.name;
|
|
}
|
|
//log("Deleting file '" + this.name);
|
|
return this.storage.delete(this.name);
|
|
},
|
|
onsuccess: function delFile_success(e) {
|
|
log("Deleted file '" + this.name + "'");
|
|
},
|
|
onerror: function delFile_onerror(e) {
|
|
log("Delete file '" + this.name + "' failed");
|
|
log('Reason: ' + e.target.error.name + ' (or ' +
|
|
translateError(e.target.error.name) + ')');
|
|
}
|
|
};
|
|
|
|
function enumerateAll(storages, dir, options) {
|
|
var storageIndex = 0;
|
|
var ds_cursor = null;
|
|
|
|
var cursor = {
|
|
continue: function cursor_continue() {
|
|
ds_cursor.continue();
|
|
}
|
|
};
|
|
|
|
function enumerateNextStorage() {
|
|
ds_cursor = storages[storageIndex].enumerate(dir, options);
|
|
ds_cursor.onsuccess = onsuccess;
|
|
ds_cursor.onerror = onerror;
|
|
};
|
|
|
|
function onsuccess(e) {
|
|
cursor.result = e.target.result;
|
|
if (!cursor.result) {
|
|
storageIndex++;
|
|
if (storageIndex < storages.length) {
|
|
enumerateNextStorage();
|
|
return;
|
|
}
|
|
// If we've run out of storages, then we fall through and call
|
|
// onsuccess with the null result.
|
|
}
|
|
if (cursor.onsuccess) {
|
|
try {
|
|
cursor.onsuccess(e);
|
|
} catch (err) {
|
|
console.warn('enumerateAll onsuccess threw', err);
|
|
}
|
|
}
|
|
};
|
|
|
|
function onerror(e) {
|
|
cursor.error = e.target.error;
|
|
if (cursor.onerror) {
|
|
try {
|
|
cursor.onerror(e);
|
|
} catch (err) {
|
|
console.warn('enumerateAll onerror threw', err);
|
|
}
|
|
}
|
|
};
|
|
|
|
enumerateNextStorage();
|
|
return cursor;
|
|
}
|
|
|
|
function ds_test_enumerate_all() {
|
|
log('ds_test_enumerate_all');
|
|
UpdateStorage();
|
|
var cursor = enumerateAll(gVolumeStorages, '');
|
|
cursor.onsuccess = function() {
|
|
var file = cursor.result;
|
|
if (file) {
|
|
log(' ' + file.name);
|
|
cursor.continue();
|
|
}
|
|
};
|
|
cursor.onerror = function() {
|
|
log("cursor.onerror() called error = '" + cursor.error + "'");
|
|
};
|
|
}
|
|
|
|
function ShowFile() {}
|
|
ShowFile.prototype = {
|
|
request: function showFile_request() {
|
|
this.name = 'test-' + this.filename + '.txt';
|
|
if (this.storageName != '') {
|
|
this.name = '/' + this.storageName + '/' + this.name;
|
|
}
|
|
//log("Showing file '" + this.name);
|
|
return this.storage.get(this.name);
|
|
},
|
|
onsuccess: function showFile_success(e) {
|
|
log('Showing contents of: ' + e.target.result.name);
|
|
var reader = new FileReader();
|
|
reader.readAsText(e.target.result);
|
|
function onloadend(e) {
|
|
log(" '" + e.target.result + "'");
|
|
};
|
|
reader.onloadend = onloadend.bind(this);
|
|
},
|
|
onerror: function showFile_onerror(e) {
|
|
log("Show file '" + this.name + "' failed");
|
|
log('Reason: ' + e.target.error.name + ' (or ' +
|
|
translateError(e.target.error.name) + ')');
|
|
}
|
|
};
|
|
|
|
function ds_showStorages(storages) {
|
|
log('Found ' + storages.length + ' storages');
|
|
for (var i = 0; i < storages.length; i++) {
|
|
var storage = storages[i];
|
|
if (storage) {
|
|
log('storage[' + i + "].storageName = '" + storage.storageName +
|
|
"' default = " + storage.default + ' canBeShared = ' + storage.canBeShared);
|
|
} else {
|
|
log('storage[' + i + '] = null');
|
|
}
|
|
}
|
|
}
|
|
|
|
function ds_addListener() {
|
|
if (gListening) {
|
|
log('Already listening');
|
|
return;
|
|
}
|
|
UpdateStorage();
|
|
AddListeners();
|
|
log('Listener added');
|
|
gListening = true;
|
|
}
|
|
|
|
function ds_removeListener() {
|
|
if (!gListening) {
|
|
log("We weren't listening");
|
|
return;
|
|
}
|
|
UpdateStorage();
|
|
RemoveListeners();
|
|
log('Listener removed');
|
|
gListening = false;
|
|
}
|
|
|
|
function ds_getDeviceStorage() {
|
|
log('ds_getDeviceStorage');
|
|
UpdateStorage();
|
|
ds_showStorages([gDefaultStorage]);
|
|
}
|
|
|
|
function ds_getDeviceStorages() {
|
|
log('ds_getDeviceStorages');
|
|
UpdateStorage();
|
|
ds_showStorages(gVolumeStorages);
|
|
}
|
|
|
|
var logElt;
|
|
function log(msg) {
|
|
//console.log(msg);
|
|
dump(msg + '\n');
|
|
if (!logElt) {
|
|
logElt = document.getElementById('log');
|
|
}
|
|
msgStr = '' + msg;
|
|
msg2 = msgStr.replace(/^\s+/, function(m) {
|
|
return m.replace(/\s/g, ' ');
|
|
});
|
|
logElt.innerHTML += msg2 + '<br>';
|
|
}
|
|
|
|
function ds_doit() {
|
|
try {
|
|
var cmdElt = document.getElementById('ds.cmd');
|
|
var cmdIdx = cmdElt.selectedIndex;
|
|
var cmd = cmdElt.options[cmdIdx].value;
|
|
|
|
switch (cmd) {
|
|
case 'getDeviceStorage':
|
|
ds_getDeviceStorage();
|
|
break;
|
|
case 'getDeviceStorages':
|
|
ds_getDeviceStorages();
|
|
break;
|
|
case 'free-space':
|
|
report(new FreeSpace());
|
|
break;
|
|
case 'used-space':
|
|
report(new UsedSpace());
|
|
break;
|
|
case 'available':
|
|
report(new Available());
|
|
break;
|
|
case 'enumerate':
|
|
report(new Enumerate());
|
|
break;
|
|
case 'enumerate-dcim':
|
|
report(new Enumerate('DCIM'));
|
|
break;
|
|
case 'enumerate-filesizes':
|
|
report(new EnumerateFileSizes());
|
|
break;
|
|
case 'enumerate-all':
|
|
ds_test_enumerate_all();
|
|
break;
|
|
case 'add-unnamed-file':
|
|
processFile(new AddUnnamedFile(), false);
|
|
break;
|
|
case 'add-file':
|
|
processFile(new AddFile());
|
|
break;
|
|
case 'del-file':
|
|
processFile(new DelFile());
|
|
break;
|
|
case 'mod-file':
|
|
log('mod-file not implemented yet');
|
|
break;
|
|
case 'show-file':
|
|
processFile(new ShowFile());
|
|
break;
|
|
case 'add-listener':
|
|
ds_addListener();
|
|
break;
|
|
case 'remove-listener':
|
|
ds_removeListener();
|
|
break;
|
|
case 'test':
|
|
//ds_test();
|
|
//ds_test_enumerate();
|
|
//ds_test_enumerate_dcim();
|
|
ds_test_enumerate_since();
|
|
//ds_test_dotdot();
|
|
//ds_test_watch();
|
|
//ds_test_823965();
|
|
log('Done');
|
|
break;
|
|
default:
|
|
log("Unrecognized command: '" + cmd + "'");
|
|
}
|
|
} catch (e) {
|
|
log('doit: caught an error');
|
|
log(e);
|
|
log(e.stack);
|
|
}
|
|
}
|
|
|
|
function ds_clearLog() {
|
|
logElt.innerHTML = '';
|
|
}
|
|
|
|
/**
|
|
* Gives feedback that the app is running.
|
|
*/
|
|
window.onload = function() {
|
|
log('Running');
|
|
document.getElementById('doit').onclick = function() { ds_doit(); };
|
|
document.getElementById('clear-log').onclick = function() { ds_clearLog(); };
|
|
};
|
|
|
|
function _logResult(test, passString, failString) {
|
|
var isError = !test.result == !test.todo;
|
|
var resultString = test.result ? passString : failString;
|
|
var url = 'dummy-url';
|
|
var diagnostic = test.name + (test.diag ? ' - ' + test.diag : '');
|
|
var msg = [resultString, url, diagnostic].join(' | ');
|
|
log(msg);
|
|
}
|
|
|
|
function ok(condition, name, diag) {
|
|
var test = {'result': !!condition, 'name': name, 'diag': diag};
|
|
_logResult(test, 'TEST-PASS', 'TEST-UNEXPECTED-FAIL');
|
|
}
|
|
|
|
function getRandomBuffer() {
|
|
var size = 1024;
|
|
var buffer = new ArrayBuffer(size);
|
|
var view = new Uint8Array(buffer);
|
|
for (var i = 0; i < size; i++) {
|
|
view[i] = parseInt(Math.random() * 255);
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
function createRandomBlob(mime) {
|
|
return blob = new Blob([getRandomBuffer()], {type: mime});
|
|
}
|
|
|
|
function randomFilename(l) {
|
|
var set = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ';
|
|
var result = '';
|
|
for (var i = 0; i < l; i++) {
|
|
var r = Math.floor(set.length * Math.random());
|
|
result += set.substring(r, r + 1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function ds_test() {
|
|
ok(navigator.getDeviceStorage, 'Should have getDeviceStorage');
|
|
|
|
var storage;
|
|
|
|
var throws = false;
|
|
try {
|
|
storage = navigator.getDeviceStorage();
|
|
} catch (e) { throws = true; }
|
|
ok(throws, 'getDeviceStorage takes one arg');
|
|
|
|
storage = navigator.getDeviceStorage('');
|
|
ok(!storage, 'empty string - Should not have this type of storage');
|
|
|
|
storage = navigator.getDeviceStorage('kilimanjaro');
|
|
ok(!storage, 'kilimanjaro - Should not have this type of storage');
|
|
|
|
storage = navigator.getDeviceStorage('pictures');
|
|
ok(storage, 'pictures - Should have getDeviceStorage');
|
|
|
|
storage = navigator.getDeviceStorage('music');
|
|
ok(storage, 'music - Should have getDeviceStorage');
|
|
|
|
storage = navigator.getDeviceStorage('videos');
|
|
ok(storage, 'videos - Should have getDeviceStorage');
|
|
|
|
var cursor = storage.enumerate();
|
|
ok(cursor, 'Should have a non-null cursor');
|
|
}
|
|
|
|
function ds_test_enumerate() {
|
|
var files;
|
|
|
|
function enumerateSuccess(e) {
|
|
if (e.target.result == null) {
|
|
ok(files.length == 0, "when the enumeration is done, we shouldn't " +
|
|
'have any files in this array');
|
|
dump('We still have length = ' + files.length + '\n');
|
|
//devicestorage_cleanup();
|
|
return;
|
|
}
|
|
|
|
var filename = e.target.result.name;
|
|
// Remove storageName, and prefix which will show up on FirefoxOS platforms.
|
|
if (filename[0] == '/') {
|
|
// We got /storgaeName/prefix/filename (which FirefoxOS does)
|
|
// Remove the storageName and prefix
|
|
filename = filename.substring(1); // Remove leading slash
|
|
var slashIndex = filename.indexOf('/');
|
|
if (slashIndex >= 0) {
|
|
filename = filename.substring(slashIndex + 1); // Remove storageName
|
|
}
|
|
}
|
|
if (filename.startsWith(prefix)) {
|
|
filename = filename.substring(prefix.length + 1); // Remove prefix
|
|
}
|
|
var index = files.indexOf(filename);
|
|
|
|
//files.remove(index);
|
|
files.splice(index, 1);
|
|
|
|
ok(index > -1, 'filename should be in the enumeration : ' + filename);
|
|
|
|
// clean up
|
|
var cleanup = storage.delete(e.target.result.name);
|
|
cleanup.onsuccess = function(e) {}; // todo - can i remove this?
|
|
|
|
e.target.continue();
|
|
}
|
|
|
|
function handleError(e) {
|
|
ok(false, 'handleError was called : ' + e.target.error.name);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
function addSuccess(e) {
|
|
addedSoFar = addedSoFar + 1;
|
|
if (addedSoFar == files.length) {
|
|
|
|
var cursor = storage.enumerate(prefix);
|
|
cursor.onsuccess = enumerateSuccess;
|
|
cursor.onerror = handleError;
|
|
}
|
|
}
|
|
|
|
function addError(e) {
|
|
ok(false, 'addError was called : ' + e.target.error.name);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
ok(navigator.getDeviceStorage, 'Should have getDeviceStorage');
|
|
var prefix = 'devicestorage/' + randomFilename(12) + '.png';
|
|
|
|
files = ['a.PNG', 'b.pnG', 'c.png', 'd/a.png', 'd/b.png', 'd/c.png',
|
|
'd/d.png', 'The/quick/brown/fox/jumps/over/the/lazy/dog.png'];
|
|
var addedSoFar = 0;
|
|
|
|
|
|
for (var i = 0; i < files.length; i++) {
|
|
|
|
request = storage.addNamed(createRandomBlob('image/png'), prefix +
|
|
'/' + files[i]);
|
|
|
|
ok(request, 'Should have a non-null request');
|
|
request.onsuccess = addSuccess;
|
|
request.onerror = addError;
|
|
}
|
|
}
|
|
|
|
function ds_test_enumerate_since() {
|
|
log('ds_test_enumerate_since');
|
|
|
|
var storage = navigator.getDeviceStorage('sdcard');
|
|
var cursor = storage.enumerate();
|
|
var timestamp = null
|
|
var do_since = true;
|
|
cursor.onsuccess = function enumSuccess(e) {
|
|
if (e.target.result == null) {
|
|
if (do_since) {
|
|
do_since = false;
|
|
if (timestamp) {
|
|
log('===== since.txt timestamp = ' + timestamp + ' =====');
|
|
var cursor_since = storage.enumerate({'since' : timestamp});
|
|
cursor_since.onsuccess = cursor.onsuccess;
|
|
cursor_since.onerror = cursor.onerror;
|
|
} else {
|
|
log("since.txt file not found");
|
|
}
|
|
} else {
|
|
log('===== Done =====');
|
|
}
|
|
return;
|
|
}
|
|
log(e.target.result.name + ' - ' + e.target.result.lastModifiedDate);
|
|
if (e.target.result.name.slice(-9) == 'since.txt') {
|
|
timestamp = e.target.result.lastModifiedDate;
|
|
}
|
|
e.target.continue();
|
|
};
|
|
cursor.onerror = function enumError(e) {
|
|
log('enumError');
|
|
};
|
|
}
|
|
|
|
function ds_test_enumerate_dcim() {
|
|
|
|
log('ds_test_enumerate_dcim');
|
|
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
var cursor = storage.enumerate('DCIM');
|
|
cursor.onsuccess = function enumSuccess(e) {
|
|
if (e.target.result == null) {
|
|
return;
|
|
}
|
|
log('Found: ' + e.target.result.name);
|
|
e.target.continue();
|
|
};
|
|
cursor.onerror = function enumError(e) {
|
|
log('enumError');
|
|
};
|
|
}
|
|
|
|
function ds_test_dotdot() {
|
|
function testingStorage() {
|
|
return navigator.getDeviceStorage('pictures');
|
|
}
|
|
|
|
var tests = [
|
|
function() {
|
|
dump('About to call addNamed\n');
|
|
return testingStorage().addNamed(createRandomBlob('image/png'),
|
|
gFileName);
|
|
},
|
|
function() { return testingStorage(). delete(gFileName); },
|
|
function() { return testingStorage().get(gFileName); },
|
|
function() {
|
|
dump('About to call enumerate\n');
|
|
var r = testingStorage().enumerate('../');
|
|
return r;
|
|
}
|
|
];
|
|
|
|
var gFileName = '../owned.png';
|
|
|
|
function fail(e) {
|
|
ok(false, 'addSuccess was called');
|
|
dump(request);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
function next(e) {
|
|
|
|
if (e != undefined) {
|
|
ok(true, 'addError was called');
|
|
ok(e.target.error.name == 'SecurityError', 'Error must be SecurityError');
|
|
}
|
|
|
|
var f = tests.pop();
|
|
|
|
if (f == undefined) {
|
|
//devicestorage_cleanup();
|
|
return;
|
|
}
|
|
|
|
request = f();
|
|
request.onsuccess = fail;
|
|
request.onerror = next;
|
|
}
|
|
|
|
dump('ds_test_dotdot\n');
|
|
next();
|
|
}
|
|
|
|
function ds_test_watch() {
|
|
var gFileName = randomFilename(20) + '.png';
|
|
|
|
function addSuccess(e) {
|
|
log('addSuccess');
|
|
}
|
|
|
|
function addError(e) {
|
|
ok(false, 'addError was called : ' + e.target.error.name);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
function onChange(e) {
|
|
|
|
dump('we saw: ' + e.path + ' ' + e.reason + '\n');
|
|
|
|
if (e.path == gFileName) {
|
|
ok(true, 'we saw the file get created');
|
|
storage.removeEventListener('change', onChange);
|
|
//devicestorage_cleanup();
|
|
}
|
|
else {
|
|
ok(e.path != '', "we shouldn't see an empty filename");
|
|
// we may see other file changes during the test, and
|
|
// that is completely ok
|
|
}
|
|
}
|
|
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
ok(storage, 'Should have storage');
|
|
storage.addEventListener('change', onChange);
|
|
|
|
request = storage.addNamed(createRandomBlob('image/png'), gFileName);
|
|
ok(request, 'Should have a non-null request');
|
|
|
|
request.onsuccess = addSuccess;
|
|
request.onerror = addError;
|
|
}
|
|
|
|
function ds_test_823965() {
|
|
var gFileName = 'devicestorage/hi.png';
|
|
var gData = 'My name is Doug Turner (?!?). My IRC nick is DougT. ' +
|
|
'I like Maple cookies.';
|
|
var gDataBlob = new Blob([gData], {type: 'image/png'});
|
|
|
|
function getSuccess(e) {
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
ok(navigator.getDeviceStorage, 'Should have getDeviceStorage');
|
|
|
|
ok(e.target.result.name == gFileName, 'File name should match');
|
|
ok(e.target.result.size > 0, 'File size be greater than zero');
|
|
ok(e.target.result.type, 'File should have a mime type');
|
|
ok(e.target.result.lastModifiedDate,
|
|
'File should have a last modified date');
|
|
|
|
var mreq = storage.enumerate();
|
|
mreq.onsuccess = function() {
|
|
var storage2 = navigator.getDeviceStorage('music');
|
|
var dreq = storage2.delete(mreq.result.name);
|
|
dreq.onerror = function() {
|
|
ok(true, 'The bug has been fixed');
|
|
//devicestorage_cleanup();
|
|
};
|
|
dreq.onsuccess = function() {
|
|
ok(false, 'The bug has been fixed');
|
|
//devicestorage_cleanup();
|
|
};
|
|
};
|
|
|
|
mreq.onerror = getError;
|
|
}
|
|
|
|
function getError(e) {
|
|
ok(false, 'getError was called : ' + e.target.error.name);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
function addSuccess(e) {
|
|
|
|
ok(e.target.result == gFileName, 'File name should match');
|
|
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
dump("About to call get on '" + gFileName + '\n');
|
|
request = storage.get(gFileName);
|
|
request.onsuccess = getSuccess;
|
|
request.onerror = getError;
|
|
|
|
ok(true, 'addSuccess was called');
|
|
}
|
|
|
|
function addError(e) {
|
|
ok(false, 'addError was called : ' + e.target.error.name);
|
|
//devicestorage_cleanup();
|
|
}
|
|
|
|
ok(navigator.getDeviceStorage, 'Should have getDeviceStorage');
|
|
|
|
var storage = navigator.getDeviceStorage('pictures');
|
|
ok(storage, 'Should have gotten a storage');
|
|
|
|
request = storage.addNamed(gDataBlob, 'devicestorage/hi.png');
|
|
ok(request, 'Should have a non-null request');
|
|
|
|
request.onsuccess = addSuccess;
|
|
request.onerror = addError;
|
|
}
|