Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/apps/system/js/update_manager.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/system/js/update_manager.js')
-rw-r--r--apps/system/js/update_manager.js623
1 files changed, 0 insertions, 623 deletions
diff --git a/apps/system/js/update_manager.js b/apps/system/js/update_manager.js
deleted file mode 100644
index 8e37733..0000000
--- a/apps/system/js/update_manager.js
+++ /dev/null
@@ -1,623 +0,0 @@
-'use strict';
-
-/*
- * The UpdateManager is a central component for apps *and* system updates.
- * The user can start or cancel all downloads at once.
- * This component also makes sure of bothering the user to a minimum by
- * showing active notifications for new updates/errors only once.
- *
- * It maintains 2 queues of Updatable objects.
- * - updatesQueue for available updates
- * - downloadsQueue for active downloads
- */
-
-var UpdateManager = {
- _mgmt: null,
- _downloading: false,
- _uncompressing: false,
- _downloadedBytes: 0,
- _errorTimeout: null,
- _wifiLock: null,
- _systemUpdateDisplayed: false,
- _isDataConnectionWarningDialogEnabled: true,
- _settings: null,
- _conn: null,
- NOTIFICATION_BUFFERING_TIMEOUT: 30 * 1000,
- TOASTER_TIMEOUT: 1200,
-
- container: null,
- message: null,
- toaster: null,
- toasterMessage: null,
- laterButton: null,
- notnowButton: null,
- downloadButton: null,
- downloadViaDataConnectionButton: null,
- downloadDialog: null,
- downloadViaDataConnectionDialog: null,
- downloadDialogTitle: null,
- downloadDialogList: null,
- lastUpdatesAvailable: 0,
- _notificationTimeout: null,
-
- updatableApps: [],
- systemUpdatable: null,
- updatesQueue: [],
- downloadsQueue: [],
-
- init: function um_init() {
- if (!this._mgmt) {
- this._mgmt = navigator.mozApps.mgmt;
- }
-
- this._mgmt.getAll().onsuccess = (function gotAll(evt) {
- var apps = evt.target.result;
- apps.forEach(function appIterator(app) {
- new AppUpdatable(app);
- });
- }).bind(this);
-
- this._settings = navigator.mozSettings;
-
- this.systemUpdatable = new SystemUpdatable();
-
- this.container = document.getElementById('update-manager-container');
- this.message = this.container.querySelector('.message');
-
- this.toaster = document.getElementById('update-manager-toaster');
- this.toasterMessage = this.toaster.querySelector('.message');
-
- this.laterButton = document.getElementById('updates-later-button');
- this.notnowButton =
- document.getElementById('updates-viaDataConnection-notnow-button');
- this.downloadButton = document.getElementById('updates-download-button');
- this.downloadViaDataConnectionButton =
- document.getElementById('updates-viaDataConnection-download-button');
- this.downloadDialog = document.getElementById('updates-download-dialog');
- this.downloadDialogTitle = this.downloadDialog.querySelector('h1');
- this.downloadDialogList = this.downloadDialog.querySelector('ul');
- this.downloadViaDataConnectionDialog =
- document.getElementById('updates-viaDataConnection-dialog');
-
- this.container.onclick = this.containerClicked.bind(this);
- this.laterButton.onclick = this.cancelPrompt.bind(this);
- this.downloadButton.onclick = this.requestDownloads.bind(this);
- this.downloadDialogList.onchange = this.updateDownloadButton.bind(this);
- this.notnowButton.onclick =
- this.cancelDataConnectionUpdatesPrompt.bind(this);
- this.downloadViaDataConnectionButton.onclick =
- this.requestDownloads.bind(this);
-
- window.addEventListener('mozChromeEvent', this);
- window.addEventListener('applicationinstall', this);
- window.addEventListener('applicationuninstall', this);
- window.addEventListener('online', this);
- window.addEventListener('offline', this);
-
- SettingsListener.observe('gaia.system.checkForUpdates', false,
- this.checkForUpdates.bind(this));
-
- // We maintain the the edge and nowifi data attributes to show
- // a warning on the download dialog
- window.addEventListener('wifi-statuschange', this);
- this.updateWifiStatus();
- this.updateOnlineStatus();
-
- this._conn = window.navigator.mozMobileConnection;
- if (this._conn) {
- this._conn.addEventListener('datachange', this);
- this.updateDataStatus();
- }
-
- window.asyncStorage.
- getItem('gaia.system.isDataConnectionWarningDialogEnabled',
- (function(value) {
- value = value || true;
- this._isDataConnectionWarningDialogEnabled = true;
- this.downloadDialog.dataset.dataConnectionInlineWarning = !value;
- }).bind(this));
- },
-
- requestDownloads: function um_requestDownloads(evt) {
- evt.preventDefault();
-
- if (evt.target == this.downloadViaDataConnectionButton) {
- window.asyncStorage.
- setItem('gaia.system.isDataConnectionWarningDialogEnabled', false);
- this._isDataConnectionWarningDialogEnabled = false;
- this.downloadDialog.dataset.dataConnectionInlineWarning = true;
- this.startDownloads();
- } else {
- if (this._isDataConnectionWarningDialogEnabled &&
- this.downloadDialog.dataset.nowifi) {
- this.downloadViaDataConnectionDialog.classList.add('visible');
- } else {
- this.startDownloads();
- }
- }
- },
-
- startDownloads: function um_startDownloads() {
- this.downloadDialog.classList.remove('visible');
- this.downloadViaDataConnectionDialog.classList.remove('visible');
-
- UtilityTray.show();
-
- var checkValues = {};
- var dialog = this.downloadDialogList;
- var checkboxes = dialog.querySelectorAll('input[type="checkbox"]');
- for (var i = 0; i < checkboxes.length; i++) {
- var checkbox = checkboxes[i];
- checkValues[checkbox.dataset.position] = checkbox.checked;
- }
-
- this.updatesQueue.forEach(function(updatable, index) {
- // The user opted out of the download
- if (updatable.app && !checkValues[index]) {
- return;
- }
-
- updatable.download();
- });
-
- this._downloadedBytes = 0;
- this.render();
- },
-
- cancelAllDownloads: function um_cancelAllDownloads() {
- CustomDialog.hide();
-
- // We're emptying the array while iterating
- while (this.downloadsQueue.length) {
- var updatable = this.downloadsQueue[0];
- updatable.cancelDownload();
- this.removeFromDownloadsQueue(updatable);
- }
- },
-
- requestErrorBanner: function um_requestErrorBanner() {
- if (this._errorTimeout)
- return;
-
- var _ = navigator.mozL10n.get;
- var self = this;
- this._errorTimeout = setTimeout(function waitForMore() {
- SystemBanner.show(_('downloadError'));
- self._errorTimeout = null;
- }, this.NOTIFICATION_BUFFERING_TIMEOUT);
- },
-
- containerClicked: function um_containerClicker() {
- var _ = navigator.mozL10n.get;
-
- if (this._downloading) {
- var cancel = {
- title: _('no'),
- callback: this.cancelPrompt.bind(this)
- };
-
- var confirm = {
- title: _('yes'),
- callback: this.cancelAllDownloads.bind(this)
- };
-
- CustomDialog.show(_('cancelAllDownloads'), _('wantToCancelAll'),
- cancel, confirm);
- } else {
- this.showDownloadPrompt();
- }
-
- UtilityTray.hide();
- },
-
- showDownloadPrompt: function um_showDownloadPrompt() {
- var _ = navigator.mozL10n.get;
-
- this._systemUpdateDisplayed = false;
- this.downloadDialogTitle.textContent = _('numberOfUpdates', {
- n: this.updatesQueue.length
- });
-
- var updateList = '';
-
- // System update should always be on top
- this.updatesQueue.sort(function sortUpdates(updatable, otherUpdatable) {
- if (!updatable.app)
- return -1;
- if (!otherUpdatable.app)
- return 1;
-
- if (updatable.name < otherUpdatable.name)
- return -1;
- if (updatable.name > otherUpdatable.name)
- return 1;
- return 0;
- });
-
- this.downloadDialogList.innerHTML = '';
- this.updatesQueue.forEach(function updatableIterator(updatable, index) {
- var listItem = document.createElement('li');
-
- // The user can choose not to update an app
- var checkContainer = document.createElement('label');
- if (updatable instanceof SystemUpdatable) {
- checkContainer.textContent = _('required');
- checkContainer.classList.add('required');
- this._systemUpdateDisplayed = true;
- } else {
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.dataset.position = index;
- checkbox.checked = true;
-
- var span = document.createElement('span');
-
- checkContainer.appendChild(checkbox);
- checkContainer.appendChild(span);
- }
- listItem.appendChild(checkContainer);
-
- var name = document.createElement('div');
- name.classList.add('name');
- name.textContent = updatable.name;
- listItem.appendChild(name);
-
- if (updatable.size) {
- var sizeItem = document.createElement('div');
- sizeItem.textContent = this._humanizeSize(updatable.size);
- listItem.appendChild(sizeItem);
- } else {
- listItem.classList.add('nosize');
- }
-
- this.downloadDialogList.appendChild(listItem);
- }, this);
-
- this.downloadDialog.classList.add('visible');
- },
-
- updateDownloadButton: function() {
- if (this._systemUpdateDisplayed) {
- this.downloadButton.disabled = false;
- return;
- }
-
- var disabled = true;
-
- var dialog = this.downloadDialogList;
- var checkboxes = dialog.querySelectorAll('input[type="checkbox"]');
- for (var i = 0; i < checkboxes.length; i++) {
- if (checkboxes[i].checked) {
- disabled = false;
- break;
- }
- }
-
- this.downloadButton.disabled = disabled;
- },
-
- cancelPrompt: function um_cancelPrompt() {
- CustomDialog.hide();
- this.downloadDialog.classList.remove('visible');
- },
-
- cancelDataConnectionUpdatesPrompt: function um_cancelDCUpdatesPrompt() {
- CustomDialog.hide();
- this.downloadViaDataConnectionDialog.classList.remove('visible');
- this.downloadDialog.classList.remove('visible');
- },
-
- downloadProgressed: function um_downloadProgress(bytes) {
- if (bytes > 0) {
- this._downloadedBytes += bytes;
- this.render();
- }
- },
-
- startedUncompressing: function um_startedUncompressing() {
- this._uncompressing = true;
- this.render();
- },
-
- render: function um_render() {
- var _ = navigator.mozL10n.get;
-
- this.toasterMessage.innerHTML =
- _('updateAvailableInfo', {
- n: this.updatesQueue.length - this.lastUpdatesAvailable
- });
-
- var message = '';
- if (this._downloading) {
- if (this._uncompressing && this.downloadsQueue.length === 1) {
- message = _('uncompressingMessage');
- } else {
- var humanProgress = this._humanizeSize(this._downloadedBytes);
- message = _('downloadingUpdateMessage', {
- progress: humanProgress
- });
- }
- } else {
- message = _('updateAvailableInfo', {
- n: this.updatesQueue.length
- });
- }
-
- this.message.innerHTML = message;
- var css = this.container.classList;
- this._downloading ? css.add('downloading') : css.remove('downloading');
- },
-
- addToUpdatableApps: function um_addtoUpdatableapps(updatableApp) {
- this.updatableApps.push(updatableApp);
- },
-
- removeFromAll: function um_removeFromAll(updatableApp) {
- var removeIndex = this.updatableApps.indexOf(updatableApp);
- if (removeIndex === -1)
- return;
-
- var removedApp = this.updatableApps[removeIndex];
- this.removeFromUpdatesQueue(removedApp);
-
- removedApp.uninit();
- this.updatableApps.splice(removeIndex, 1);
- },
-
- addToUpdatesQueue: function um_addToUpdatesQueue(updatable) {
- if (this._downloading) {
- return;
- }
-
- if (updatable.app &&
- updatable.app.installState !== 'installed') {
- return;
- }
-
- if (updatable.app &&
- this.updatableApps.indexOf(updatable) === -1) {
- return;
- }
-
- var alreadyThere = this.updatesQueue.some(function lookup(u) {
- return (u.app === updatable.app);
- });
- if (alreadyThere) {
- return;
- }
-
- this.updatesQueue.push(updatable);
-
- if (this._notificationTimeout === null) {
- this._notificationTimeout = setTimeout(this.displayNotificationAndToaster.bind(this),
- this.NOTIFICATION_BUFFERING_TIMEOUT);
- }
- this.render();
- },
-
- displayNotificationAndToaster: function um_displayNotificationAndToaster() {
- this._notificationTimeout = null;
- if (this.updatesQueue.length && !this._downloading) {
- this.lastUpdatesAvailable = this.updatesQueue.length;
- StatusBar.updateNotificationUnread(true);
- this.displayNotificationIfHidden();
- this.toaster.classList.add('displayed');
- var self = this;
- setTimeout(function waitToHide() {
- self.toaster.classList.remove('displayed');
- }, this.TOASTER_TIMEOUT);
- }
- },
-
- removeFromUpdatesQueue: function um_removeFromUpdatesQueue(updatable) {
- var removeIndex = this.updatesQueue.indexOf(updatable);
- if (removeIndex === -1)
- return;
-
- this.updatesQueue.splice(removeIndex, 1);
- this.lastUpdatesAvailable = this.updatesQueue.length;
-
- if (this.updatesQueue.length === 0) {
- this.hideNotificationIfDisplayed();
- }
-
- this.render();
- },
-
- addToDownloadsQueue: function um_addToDownloadsQueue(updatable) {
- if (updatable.app &&
- this.updatableApps.indexOf(updatable) === -1) {
- return;
- }
-
- var alreadyThere = this.downloadsQueue.some(function lookup(u) {
- return (u.app === updatable.app);
- });
- if (alreadyThere) {
- return;
- }
-
- this.downloadsQueue.push(updatable);
-
- if (this.downloadsQueue.length === 1) {
- this._downloading = true;
- StatusBar.incSystemDownloads();
- this._wifiLock = navigator.requestWakeLock('wifi');
-
- this.displayNotificationIfHidden();
- this.render();
- }
- },
-
- removeFromDownloadsQueue: function um_removeFromDownloadsQueue(updatable) {
- var removeIndex = this.downloadsQueue.indexOf(updatable);
- if (removeIndex === -1)
- return;
-
- this.downloadsQueue.splice(removeIndex, 1);
-
- if (this.downloadsQueue.length === 0) {
- this._downloading = false;
- StatusBar.decSystemDownloads();
- this._downloadedBytes = 0;
- this.checkStatuses();
-
- if (this._wifiLock) {
- try {
- this._wifiLock.unlock();
- } catch (e) {
- // this can happen if the lock is already unlocked
- console.error('error during unlock', e);
- }
-
- this._wifiLock = null;
- }
-
- this.render();
- }
- },
-
- hideNotificationIfDisplayed: function() {
- if (this.container.classList.contains('displayed')) {
- this.container.classList.remove('displayed');
- NotificationScreen.decExternalNotifications();
- }
- },
-
- displayNotificationIfHidden: function() {
- if (!this.container.classList.contains('displayed')) {
- this.container.classList.add('displayed');
- NotificationScreen.incExternalNotifications();
- }
- },
-
- checkStatuses: function um_checkStatuses() {
- this.updatableApps.forEach(function(updatableApp) {
- var app = updatableApp.app;
- if (app.downloadAvailable) {
- this.addToUpdatesQueue(updatableApp);
- }
- }, this);
- },
-
- oninstall: function um_oninstall(evt) {
- var app = evt.application;
- var updatableApp = new AppUpdatable(app);
- },
-
- onuninstall: function um_onuninstall(evt) {
- this.updatableApps.some(function appIterator(updatableApp, index) {
- // The application object we get from the event
- // has only origin and manifestURL properties
- if (updatableApp.app.manifestURL === evt.application.manifestURL) {
- this.removeFromAll(updatableApp);
- return true;
- }
- return false;
- }, this);
- },
-
- handleEvent: function um_handleEvent(evt) {
- if (!evt.type)
- return;
-
- switch (evt.type) {
- case 'applicationinstall':
- this.oninstall(evt.detail);
- break;
- case 'applicationuninstall':
- this.onuninstall(evt.detail);
- break;
- case 'datachange':
- this.updateDataStatus();
- break;
- case 'offline':
- this.updateOnlineStatus();
- break;
- case 'online':
- this.updateOnlineStatus();
- break;
- case 'wifi-statuschange':
- this.updateWifiStatus();
- break;
- }
-
- if (evt.type !== 'mozChromeEvent')
- return;
-
- var detail = evt.detail;
-
- if (detail.type && detail.type === 'update-available') {
- this.systemUpdatable.size = detail.size;
- this.systemUpdatable.rememberKnownUpdate();
- this.addToUpdatesQueue(this.systemUpdatable);
- }
- },
-
- updateOnlineStatus: function su_updateOnlineStatus() {
- var online = (navigator && 'onLine' in navigator) ? navigator.onLine : true;
- this.downloadDialog.dataset.online = online;
-
- if (online) {
- this.laterButton.classList.remove('full');
- } else {
- this.laterButton.classList.add('full');
- }
- },
-
- updateWifiStatus: function su_updateWifiStatus() {
- var wifiManager = window.navigator.mozWifiManager;
- if (!wifiManager)
- return;
-
- this.downloadDialog.dataset.nowifi =
- (wifiManager.connection.status != 'connected');
- },
-
- checkForUpdates: function su_checkForUpdates(shouldCheck) {
- if (!shouldCheck) {
- return;
- }
-
- this._dispatchEvent('force-update-check');
-
- if (!this._settings) {
- return;
- }
-
- var lock = this._settings.createLock();
- lock.set({
- 'gaia.system.checkForUpdates': false
- });
- },
-
- _dispatchEvent: function um_dispatchEvent(type, result) {
- var event = document.createEvent('CustomEvent');
- var data = { type: type };
- if (result) {
- data.result = result;
- }
-
- event.initCustomEvent('mozContentEvent', true, true, data);
- window.dispatchEvent(event);
- },
-
- // This is going to be part of l10n.js
- _humanizeSize: function um_humanizeSize(bytes) {
- var _ = navigator.mozL10n.get;
- var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
-
- if (!bytes)
- return '0.00 ' + _(units[0]);
-
- var e = Math.floor(Math.log(bytes) / Math.log(1024));
- return (bytes / Math.pow(1024, Math.floor(e))).toFixed(2) + ' ' +
- _(units[e]);
- }
-};
-
-window.addEventListener('localized', function startup(evt) {
- window.removeEventListener('localized', startup);
-
- UpdateManager.init();
-});