blob: 10bc849c4241c18f78643ca60eaecfdbf30e9b5c [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import './strings.m.js';
import {addWebUIListener} from 'chrome://resources/js/cr.m.js';
import {$, createElementWithClassName} from 'chrome://resources/js/util.m.js';
/**
* @typedef {{
* name: string,
* shortName: string,
* packageName: string,
* id: string,
* shellApkVersion: number,
* versionCode: number,
* uri: string,
* scope: string,
* manifestUrl: string,
* manifestStartUrl: string,
* displayMode: string,
* orientation: string,
* themeColor: string,
* backgroundColor: string,
* lastUpdateCheckTimeMs: number,
* lastUpdateCompletionTimeMs: number,
* relaxUpdates: boolean,
* backingBrowser: string,
* isBackingBrowser: boolean,
* updateStatus: string,
* }}
*/
let WebApkInfo;
/**
* @typedef {{
* id: string,
* status: string,
* }}
*/
let UpdateStatus;
const UPDATE_TIMEOUT = 60 * 1000; // milliseconds.
/**
* Creates and returns an element (with |text| as content) assigning it the
* |className| class.
*
* @param {string} text Text to be shown in the span.
* @param {string} type Type of element to be added such as 'div'.
* @param {string} className Class to be assigned to the new element.
* @return {Element} The created element.
*/
function createElementWithTextAndClass(text, type, className) {
const element = createElementWithClassName(type, className);
element.textContent = text;
return element;
}
/**
* @param {HTMLElement} webApkList List of elements which contain WebAPK
* attributes.
* @param {string} label Text that identifies the new element.
* @param {string} value Text to set in the new element.
*/
function addWebApkField(webApkList, label, value) {
const divElement =
createElementWithTextAndClass(label, 'div', 'app-property-label');
divElement.appendChild(
createElementWithTextAndClass(value, 'span', 'app-property-value'));
webApkList.appendChild(divElement);
}
/**
* @param {HTMLElement} webApkList List of elements which contain WebAPK
* attributes.
* @param {string} text For the button.
* @param {function()} callback Invoked on click.
* @return {Element} The button that was created.
*/
function addWebApkButton(webApkList, text, callback) {
const divElement =
createElementWithTextAndClass(text, 'button', 'update-button');
divElement.onclick = callback;
webApkList.appendChild(divElement);
return divElement;
}
/**
* Adds a new entry to the page with the information of a WebAPK.
*
* @param {!WebApkInfo} webApkInfo Information about an installed WebAPK.
*/
function addWebApk(webApkInfo) {
/** @type {HTMLElement} */ const webApkList = $('webapk-list');
webApkList.appendChild(
createElementWithTextAndClass(webApkInfo.name, 'span', 'app-name'));
webApkList.appendChild(createElementWithTextAndClass(
'Short name: ', 'span', 'app-property-label'));
webApkList.appendChild(document.createTextNode(webApkInfo.shortName));
addWebApkField(webApkList, 'Package name: ', webApkInfo.packageName);
addWebApkField(
webApkList, 'Shell APK version: ', '' + webApkInfo.shellApkVersion);
addWebApkField(webApkList, 'Version code: ', '' + webApkInfo.versionCode);
addWebApkField(webApkList, 'URI: ', webApkInfo.uri);
addWebApkField(webApkList, 'Scope: ', webApkInfo.scope);
addWebApkField(webApkList, 'Manifest URL: ', webApkInfo.manifestUrl);
addWebApkField(
webApkList, 'Manifest Start URL: ', webApkInfo.manifestStartUrl);
addWebApkField(webApkList, 'Display Mode: ', webApkInfo.displayMode);
addWebApkField(webApkList, 'Orientation: ', webApkInfo.orientation);
addWebApkField(webApkList, 'Theme color: ', webApkInfo.themeColor);
addWebApkField(webApkList, 'Background color: ', webApkInfo.backgroundColor);
addWebApkField(
webApkList, 'Last Update Check Time: ',
new Date(webApkInfo.lastUpdateCheckTimeMs).toString());
addWebApkField(
webApkList, 'Last Update Completion Time: ',
new Date(webApkInfo.lastUpdateCompletionTimeMs).toString());
addWebApkField(
webApkList, 'Check for Updates Less Frequently: ',
webApkInfo.relaxUpdates.toString());
addWebApkField(webApkList, 'Owning Browser: ', webApkInfo.backingBrowser);
addWebApkField(webApkList, 'Update Status: ', webApkInfo.updateStatus);
// TODO(ckitagawa): Convert to an enum using mojom handlers.
if (webApkInfo.updateStatus == 'Not updatable' ||
!webApkInfo.isBackingBrowser) {
return;
}
const buttonElement =
addWebApkButton(webApkList, 'Update ' + webApkInfo.name, () => {
alert(
'The WebAPK will check for an update the next time it launches. ' +
'If an update is available, the "Update Status" on this page ' +
'will switch to "Scheduled". The update will be installed once ' +
'the WebAPK is closed (this may take a few minutes).');
chrome.send('requestWebApkUpdate', [webApkInfo.id]);
});
// Prevent updates in the WebAPK server caching window as they will fail.
const msSinceLastUpdate = Date.now() - webApkInfo.lastUpdateCompletionTimeMs;
if (msSinceLastUpdate < UPDATE_TIMEOUT) {
buttonElement.disabled = true;
window.setTimeout(() => {
buttonElement.disabled = false;
}, UPDATE_TIMEOUT - msSinceLastUpdate);
}
}
document.addEventListener('DOMContentLoaded', function() {
// Add a WebUI listener for the 'web-apk-info' event emmitted from the
// backend. This will be triggered once per WebAPK.
addWebUIListener('web-apk-info', addWebApk);
chrome.send('requestWebApksInfo');
});