;'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;iMAX_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;i2||(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;iMath.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});}});};};});}}