Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
55
assets/webapps/fl.gaiamobile.org/js/download.js
Normal file
55
assets/webapps/fl.gaiamobile.org/js/download.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
;'use strict';window.addEventListener('load',function(){navigator.mozL10n.once(function(){navigator.mozSetMessageHandler('activity',view);});});function view(activity){debug('view() invoked for activity',activity.source.name,'with data',JSON.stringify(activity.source.data));var descriptor={};var mimeType;var isImage=false;var isAudio=false;var installType;var hasDescriptor;var activityType=normalizeMimeType(activity.source.data.type);if(activityType==='application/vnd.oma.drm.message'){hasDescriptor=false;var url=(activity.source.data.url||'');descriptor.name=getFileNameFromURL(url);descriptor.size=0;descriptor.types=['application/vnd.oma.drm.message'];descriptor.objectURI=url;displayDownloadProgress();}else{hasDescriptor=true;downloadDescriptor(activity.source.data.url);}
|
||||
function normalizeMimeType(type){type=type.split(';')[0];type=type.toLowerCase();if(type in MimeTypeAliases){type=MimeTypeAliases[type];}
|
||||
return type;}
|
||||
function askSongOrRingtone(aCallback){showDialog({message:_('ringtone-or-song-question'),okText:_('ringtone-response'),cancelText:_('song-response'),okCallback:aCallback.bind(undefined,RINGTONE),cancelCallback:aCallback.bind(undefined,SONG)});}
|
||||
function getFileNameFromURL(aUri){var name='';if(aUri){name=aUri.split('/').pop();if(name.endsWith('.dm')){name=name.slice(0,-3);}
|
||||
if(name.length>18){name=name.substring(0,15)+'\u2026';}}
|
||||
return name;}
|
||||
function getFileNameFromHeader(aHeader){var regexp=/filename="([^"]*)"/i;var match=regexp.exec(aHeader);var name=match&&match[1];if(name){name=getFileNameFromURL(name);}
|
||||
return name;}
|
||||
function reportError(type,errorID,downloadStatus,details){console.error(type,errorID,downloadStatus,details);if(downloadStatus){sendStatus(downloadStatus);}
|
||||
details='['+(details?errorID+': '+details:errorID)+']';showDialog({title:_(type)||type,message:_(errorID),details:details,okCallback:function(){activity.postError(errorID);}});}
|
||||
function reportSuccess(successID){sendStatus(OMADownloadStatus.success);showDialog({message:_(successID)||successID,okCallback:function(){activity.postResult({success:true});}});}
|
||||
function sendStatus(status,callback){if(descriptor.installNotifyURI){var xhr=new XMLHttpRequest(systemXHR);xhr.open('POST',descriptor.installNotifyURI);xhr.timeout=1000;xhr.send(status);if(callback){xhr.onloadend=function(){callback();};}}else if(callback){callback();}}
|
||||
function downloadDescriptor(descriptorURL){debug('Step 1: downloading descriptor from',descriptorURL);var xhr=new XMLHttpRequest(systemXHR);xhr.open('GET',descriptorURL);xhr.responseType='document';xhr.send();xhr.onerror=function(e){reportError(DOWNLOAD_ERROR,ERR_DESCRIPTOR_DOWNLOAD_FAILED,null,xhr.status+' '+xhr.statusText);};xhr.onload=function(){setTimeout(function(){parse(xhr.response);});};}
|
||||
function parse(document){var types=document.getElementsByTagName('type');if(types){descriptor.types=[];for(var i=0;i<types.length;i++){descriptor.types.push(normalizeMimeType(types[i].textContent.trim()));}}
|
||||
function get(tag){var elts=document.getElementsByTagName(tag);if(elts&&elts.length){descriptor[tag]=elts[0].textContent.trim();}}
|
||||
get('size');get('objectURI');get('installNotifyURI');get('DDVersion');get('name');get('description');get('vendor');debug('Step 2: parse descriptor:',JSON.stringify(descriptor));if(!descriptor.types||descriptor.types.length===0||!descriptor.size||!descriptor.objectURI){reportError(DOWNLOAD_ERROR,ERR_BAD_DESCRIPTOR,OMADownloadStatus.INVALID_DESCRIPTOR);return;}
|
||||
if(descriptor.size>MAX_DOWNLOAD_SIZE){MediaUtils.getLocalizedSize(descriptor.size).then((msg)=>{reportError(DOWNLOAD_ERROR,ERR_TOO_BIG,OMADownloadStatus.INSUFFICIENT_MEMORY,msg);});return;}
|
||||
if(!descriptor.name){descriptor.name=getFileNameFromURL(descriptor.objectURI);}
|
||||
if(descriptor.DDVersion&&parseInt(descriptor.DDVersion)>1){reportError(DOWNLOAD_ERROR,ERR_BAD_DESCRIPTOR,OMADownloadStatus.INVALID_DDVERSION);return;}
|
||||
checkTypes();}
|
||||
function checkTypes(){debug('Step 3: check types');var types=descriptor.types;for(var i=0;i<types.length;i++){var type=types[i];if(type==='application/vnd.oma.drm.message'){continue;}
|
||||
mimeType=type;if(type in SupportedImageTypes){isImage=true;}else if(type in SupportedAudioTypes){isAudio=true;}else{mimeType=undefined;reportError(DOWNLOAD_ERROR,ERR_UNSUPPORTED_TYPE,OMADownloadStatus.NON_ACCEPTABLE_CONTENT,type);return;}}
|
||||
if(types.length<1||types.length>2||(isAudio&&isImage)||(!isAudio&&!isImage)){reportError(DOWNLOAD_ERROR,ERR_BAD_TYPE,OMADownloadStatus.NON_ACCEPTABLE_CONTENT);return;}
|
||||
if(isImage){installType=WALLPAPER;confirmDownload();}else{askSongOrRingtone(function(response){installType=response;confirmDownload();});}}
|
||||
function confirmDownload(){debug('Step 4: confirm download');var titleElement=$('download-confirmation-title');titleElement.textContent=_('download-confirmation-title-'+installType);$('download-confirmation-name').textContent=descriptor.name;$('download-confirmation-type').textContent=mimeType;MediaUtils.getLocalizedSizeTokens(descriptor.size).then((args)=>{navigator.mozL10n.setAttributes($('download-confirmation-size'),'fileSize',args);});$('download-confirmation-description').textContent=descriptor.description;var lca;if(descriptor.vendor){lca=_('locked-content-advisory',{vendor:descriptor.vendor});}else{lca=_('locked-content-advisory-generic');}
|
||||
$('locked-content-advisory-text').textContent=lca;$('download-confirm').onclick=function(e){e.target.disabled=true;displayDownloadProgress();};$('download-cancel').onclick=function(e){debug('download cancelled');$('download-confirmation').hidden=true;sendStatus(OMADownloadStatus.USER_CANCELLED,function(){activity.postError('cancelled');});};$('download-confirmation').hidden=false;}
|
||||
function displayDownloadProgress(){debug('Step 5: download content and display progress');var bar;var contentLength;if(!hasDescriptor){$('direct-download').hidden=false;bar=$('direct-download-progress');bar.max=100;}else{var titleElement=$('download-confirmation-title');titleElement.textContent=_('downloading-'+installType);$('download-confirmation').hidden=false;bar=$('download-progress');bar.max=descriptor.size;}
|
||||
bar.style.visibility='visible';bar.value=0;debug('starting download for',descriptor.objectURI);var download=new XMLHttpRequest(systemXHR);download.open('GET',descriptor.objectURI);download.responseType='arraybuffer';download.send();download.onprogress=function(e){if(contentLength===undefined){contentLength=download.getResponseHeader('Content-Length');bar.max=contentLength&&parseInt(contentLength)||bar.max;}
|
||||
if(descriptor.size||contentLength){bar.value=e.loaded;}else{bar.value=(bar.value+10)%bar.max;}};download.onerror=function(){$('download-confirmation').hidden=true;reportError(DOWNLOAD_ERROR,ERR_CONTENT_DOWNLOAD_FAILED,OMADownloadStatus.LOADER_ERROR,download.status+' '+download.statusText);};download.onload=function(){$('download-cancel').disabled=true;$('download-confirmation').hidden=true;var cdHeader=download.getResponseHeader('Content-Disposition');if(cdHeader&&!hasDescriptor){descriptor.name=getFileNameFromHeader(cdHeader)||descriptor.name;}
|
||||
var type=normalizeMimeType(download.getResponseHeader('Content-Type'));extractContent(type,download.response);};$('download-cancel').addEventListener('click',function(){download.abort();});}
|
||||
function extractContent(type,buffer){debug('Step 6a: extractContent',type,buffer.byteLength);if(type!=='application/vnd.oma.drm.message'){previewContent(type,buffer);return;}
|
||||
var dataString=new BinaryStringView(buffer);dataString=dataString.trim();function malformed(why){if(why){debug('malformed drm message:',why);}
|
||||
reportError(DOWNLOAD_ERROR,ERR_BAD_DRM_MESSAGE,OMADownloadStatus.ATTRIBUTE_MISMATCH);}
|
||||
if(dataString.slice(-2).toString()!=='--'){return malformed('missing trailing --');}
|
||||
var end=dataString.lastIndexOf('\r\n');if(end===-1){return malformed('missing final \r\n');}
|
||||
var boundaryString=dataString.slice(end+2,-2).toString()+'\r\n';dataString=dataString.slice(0,end);debug('Boundary string is',boundaryString);var headerStart=dataString.indexOf(boundaryString)+boundaryString.length;if(headerStart===-1){return malformed('missing boundary string at start');}
|
||||
if(dataString.indexOf(boundaryString,headerStart)!==-1){return malformed('more than one part');}
|
||||
var contentStart=dataString.indexOf('\r\n\r\n',headerStart);if(contentStart===-1){return malformed('missing header separator');}
|
||||
var headers=dataString.slice(headerStart,contentStart).toString().split('\r\n');var content=dataString.slice(contentStart+4);debug('got first part headers:',JSON.stringify(headers));var contentType;for(var i=0;i<headers.length;i++){var header=headers[i].toLowerCase();if(header.startsWith('content-type:')){contentType=normalizeMimeType(header.substring(13).trim());}}
|
||||
if(!contentType){return malformed('no content-type header found in first part');}
|
||||
debug('Found content in drm message file',contentType,content.length);previewContent(contentType,content.toArrayBuffer());}
|
||||
function previewContent(type,bytes){if(!hasDescriptor){mimeType=type;if(type in SupportedImageTypes){isImage=true;}else if(type in SupportedAudioTypes){isAudio=true;}else{mimeType=undefined;reportError(DOWNLOAD_ERROR,ERR_UNSUPPORTED_TYPE,OMADownloadStatus.NON_ACCEPTABLE_CONTENT,type);return;}}else{if(type!==mimeType){reportError(DOWNLOAD_ERROR,ERR_BAD_DRM_MESSAGE,OMADownloadStatus.ATTRIBUTE_MISMATCH);return;}}
|
||||
if(isImage){installType=WALLPAPER;previewImage(type,bytes);}else{if(!hasDescriptor){askSongOrRingtone(function(response){installType=response;previewAudio(type,bytes);});}else{previewAudio(type,bytes);}}}
|
||||
function previewImage(type,bytes){$('download-confirmation').hidden=true;$('preview-image-screen').hidden=false;var blob=new Blob([bytes],{type:type});var url=URL.createObjectURL(blob);var image=new Image();image.src=url;image.onerror=function(){URL.revokeObjectURL(url);reportError(INSTALL_ERROR,ERR_BAD_IMAGE,OMADownloadStatus.NON_ACCEPTABLE_CONTENT);return;};image.onload=function(){var preview=$('preview-image');preview.style.backgroundImage='url('+url+')';$('preview-image-install').disabled=false;};$('preview-image-install').onclick=function(){URL.revokeObjectURL(url);installContent(bytes);};$('preview-image-cancel').onclick=function(){URL.revokeObjectURL(url);sendStatus(OMADownloadStatus.USER_CANCELLED,function(){activity.postError('cancelled');});};}
|
||||
function previewAudio(type,bytes){$('download-confirmation').hidden=true;$('preview-audio-screen').hidden=false;var blob=new Blob([bytes],{type:type});var url=URL.createObjectURL(blob);var player=$('preview-audio');player.src=url;player.onerror=function(){cleanup();reportError(INSTALL_ERROR,ERR_BAD_AUDIO,OMADownloadStatus.NON_ACCEPTABLE_CONTENT);return;};player.oncanplay=function(){$('preview-audio-install').disabled=false;};player.ontimeupdate=player.ondurationchange=function(){if(player.currentTime>Math.max(5,player.duration/2)){player.pause();player.currentTime=0;}};$('preview-audio-install').onclick=function(){cleanup();installContent(bytes);};$('preview-audio-cancel').onclick=function(){cleanup();sendStatus(OMADownloadStatus.USER_CANCELLED,function(){activity.postError('cancelled');});};function cleanup(){player.pause();player.removeAttribute('src');player.load();URL.revokeObjectURL(url);}}
|
||||
function installContent(bytes){switch(installType){case SONG:installSong(bytes);return;case RINGTONE:case WALLPAPER:install(installType,bytes,descriptor);return;}}
|
||||
function installSong(buffer){debug('installSong');ForwardLock.getOrCreateKey(function(secret){debug('got secret key');var blob=ForwardLock.lockBuffer(secret,buffer,mimeType,{vendor:descriptor.vendor,name:descriptor.name,description:descriptor.description});debug('encrypted song');getStorageIfAvailable('music',blob.size,storageSuccess,storageError);function storageError(err){debug('storageError:',err);if(err==='unavailable'){reportError(INSTALL_ERROR,ERR_NO_SDCARD,OMADownloadStatus.INSUFFICIENT_MEMORY);}else if(err==='shared'){reportError(INSTALL_ERROR,ERR_SDCARD_IN_USE,OMADownloadStatus.INSUFFICIENT_MEMORY);}else{reportError(INSTALL_ERROR,ERR_NO_SPACE,OMADownloadStatus.INSUFFICIENT_MEMORY,err);}}
|
||||
function storageSuccess(storage){debug('got music storage');var filename='locked/';if(descriptor.vendor){filename+=fixPath(descriptor.vendor)+'/';}
|
||||
filename+=fixPath(descriptor.name)+'.lcka';debug('trying filename',filename);function fixPath(s){return s.replace(/[\/\\\.\,\?\*\:]/g,'');}
|
||||
getUnusedFilename(storage,filename,function(filename){debug('using filename',filename);var addreq=storage.addNamed(blob,filename);addreq.onerror=function(){reportError(INSTALL_ERROR,ERR_DS_SAVE_FAILURE,OMADownloadStatus.LOADER_ERROR,addreq.error.name);};addreq.onsuccess=function(){reportSuccess(SUCCESS_SONG);};});}});}
|
||||
function install(installType,buffer,descriptor){ForwardLock.getOrCreateKey();var objectStoreName=installType===RINGTONE?'ringtones':'wallpapers';var blob=new Blob([buffer],{type:mimeType});objectStore.readwrite(objectStoreName,function(store){var req=store.add({blob:blob,descriptor:descriptor});req.onerror=function(){reportError(INSTALL_ERROR,ERR_DB_STORE_FAILURE,OMADownloadStatus.LOADER_ERROR,req.error.name);};req.onsuccess=function(){sendStatus(OMADownloadStatus.SUCCESS);var lock=navigator.mozSettings.createLock();var settings={};if(installType===RINGTONE){settings[RINGTONE_KEY]=blob;settings[RINGTONE_NAME_KEY]=descriptor.name;settings[RINGTONE_ID_KEY]=req.result;}
|
||||
else{settings[WALLPAPER_KEY]=blob;}
|
||||
lock.set(settings).onsuccess=function(){var msgid;if(installType===RINGTONE){msgid=SUCCESS_RINGTONE;}else{msgid=SUCCESS_WALLPAPER;}
|
||||
showDialog({message:_(msgid),okCallback:function(){activity.postResult({success:true});}});};};});}}
|
||||
Loading…
Reference in a new issue