blob: 12cc0209ebba128913929de9c957cae7141dcc43 [file] [log] [blame]
// Copyright 2016 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.
/**
* @fileoverview 'settings-about-page' contains version and OS related
* information.
*/
import '../icons.m.js';
import '../prefs/prefs.m.js';
import '../settings_page/settings_section.m.js';
import '../settings_page_css.m.js';
import '../settings_shared_css.m.js';
import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.m.js';
import 'chrome://resources/cr_elements/icons.m.js';
import 'chrome://resources/cr_elements/shared_style_css.m.js';
import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import {assert} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {parseHtmlSubset} from 'chrome://resources/js/parse_html_subset.m.js';
import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {loadTimeData} from '../i18n_setup.js';
import {LifetimeBrowserProxy, LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.m.js';
import {Router} from '../router.m.js';
import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, PromoteUpdaterStatus, UpdateStatus, UpdateStatusChangedEvent} from './about_page_browser_proxy.m.js';
Polymer({
is: 'settings-about-page',
_template: html`{__html_template__}`,
behaviors: [
WebUIListenerBehavior,
I18nBehavior,
],
properties: {
/** @private {?UpdateStatusChangedEvent} */
currentUpdateStatusEvent_: {
type: Object,
value: {
message: '',
progress: 0,
rollback: false,
status: UpdateStatus.DISABLED
},
},
/**
* Whether the browser/ChromeOS is managed by their organization
* through enterprise policies.
* @private
*/
isManaged_: {
type: Boolean,
value() {
return loadTimeData.getBoolean('isManaged');
},
},
// <if expr="_google_chrome and is_macosx">
/** @private {!PromoteUpdaterStatus} */
promoteUpdaterStatus_: Object,
// </if>
// <if expr="not chromeos">
/** @private {!{obsolete: boolean, endOfLine: boolean}} */
obsoleteSystemInfo_: {
type: Object,
value() {
return {
obsolete: loadTimeData.getBoolean('aboutObsoleteNowOrSoon'),
endOfLine: loadTimeData.getBoolean('aboutObsoleteEndOfTheLine'),
};
},
},
/** @private */
showUpdateStatus_: {
type: Boolean,
value: false,
},
/** @private */
showButtonContainer_: Boolean,
/** @private */
showRelaunch_: {
type: Boolean,
value: false,
},
// </if>
},
observers: [
// <if expr="not chromeos">
'updateShowUpdateStatus_(' +
'obsoleteSystemInfo_, currentUpdateStatusEvent_)',
'updateShowRelaunch_(currentUpdateStatusEvent_)',
'updateShowButtonContainer_(showRelaunch_)',
// </if>
],
/** @private {?AboutPageBrowserProxy} */
aboutBrowserProxy_: null,
/** @private {?LifetimeBrowserProxy} */
lifetimeBrowserProxy_: null,
/** @override */
attached() {
this.aboutBrowserProxy_ = AboutPageBrowserProxyImpl.getInstance();
this.aboutBrowserProxy_.pageReady();
this.lifetimeBrowserProxy_ = LifetimeBrowserProxyImpl.getInstance();
// <if expr="not chromeos">
this.startListening_();
if (Router.getInstance().getQueryParameters().get('checkForUpdate') ==
'true') {
this.onUpdateStatusChanged_({status: UpdateStatus.CHECKING});
this.aboutBrowserProxy_.requestUpdate();
}
// </if>
},
/**
* @return {string}
* @private
*/
getPromoteUpdaterClass_() {
// <if expr="_google_chrome and is_macosx">
if (this.promoteUpdaterStatus_.disabled) {
return 'cr-secondary-text';
}
// </if>
return '';
},
// <if expr="not chromeos">
/** @private */
startListening_() {
this.addWebUIListener(
'update-status-changed', this.onUpdateStatusChanged_.bind(this));
// <if expr="_google_chrome and is_macosx">
this.addWebUIListener(
'promotion-state-changed',
this.onPromoteUpdaterStatusChanged_.bind(this));
// </if>
this.aboutBrowserProxy_.refreshUpdateStatus();
},
/**
* @param {!UpdateStatusChangedEvent} event
* @private
*/
onUpdateStatusChanged_(event) {
this.currentUpdateStatusEvent_ = event;
},
// </if>
// <if expr="_google_chrome and is_macosx">
/**
* @param {!PromoteUpdaterStatus} status
* @private
*/
onPromoteUpdaterStatusChanged_(status) {
this.promoteUpdaterStatus_ = status;
},
/**
* If #promoteUpdater isn't disabled, trigger update promotion.
* @private
*/
onPromoteUpdaterTap_() {
// This is necessary because #promoteUpdater is not a button, so by default
// disable doesn't do anything.
if (this.promoteUpdaterStatus_.disabled) {
return;
}
this.aboutBrowserProxy_.promoteUpdater();
},
// </if>
/**
* @param {!Event} event
* @private
*/
onLearnMoreTap_(event) {
// Stop the propagation of events, so that clicking on links inside
// actionable items won't trigger action.
event.stopPropagation();
},
/** @private */
onReleaseNotesTap_() {
this.aboutBrowserProxy_.launchReleaseNotes();
},
/** @private */
onHelpTap_() {
this.aboutBrowserProxy_.openHelpPage();
},
/** @private */
onRelaunchTap_() {
this.lifetimeBrowserProxy_.relaunch();
},
// <if expr="not chromeos">
/** @private */
updateShowUpdateStatus_() {
if (this.obsoleteSystemInfo_.endOfLine) {
this.showUpdateStatus_ = false;
return;
}
this.showUpdateStatus_ =
this.currentUpdateStatusEvent_.status != UpdateStatus.DISABLED;
},
/**
* Hide the button container if all buttons are hidden, otherwise the
* container displays an unwanted border (see separator class).
* @private
*/
updateShowButtonContainer_() {
this.showButtonContainer_ = this.showRelaunch_;
},
/** @private */
updateShowRelaunch_() {
this.showRelaunch_ = this.checkStatus_(UpdateStatus.NEARLY_UPDATED);
},
/**
* @return {boolean}
* @private
*/
shouldShowLearnMoreLink_() {
return this.currentUpdateStatusEvent_.status == UpdateStatus.FAILED;
},
/**
* @return {string}
* @private
*/
getUpdateStatusMessage_() {
switch (this.currentUpdateStatusEvent_.status) {
case UpdateStatus.CHECKING:
case UpdateStatus.NEED_PERMISSION_TO_UPDATE:
return this.i18nAdvanced('aboutUpgradeCheckStarted');
case UpdateStatus.NEARLY_UPDATED:
return this.i18nAdvanced('aboutUpgradeRelaunch');
case UpdateStatus.UPDATED:
return this.i18nAdvanced('aboutUpgradeUpToDate');
case UpdateStatus.UPDATING:
assert(typeof this.currentUpdateStatusEvent_.progress == 'number');
const progressPercent = this.currentUpdateStatusEvent_.progress + '%';
if (this.currentUpdateStatusEvent_.progress > 0) {
// NOTE(dbeam): some platforms (i.e. Mac) always send 0% while
// updating (they don't support incremental upgrade progress). Though
// it's certainly quite possible to validly end up here with 0% on
// platforms that support incremental progress, nobody really likes
// seeing that they're 0% done with something.
return this.i18nAdvanced('aboutUpgradeUpdatingPercent', {
substitutions: [progressPercent],
});
}
return this.i18nAdvanced('aboutUpgradeUpdating');
default:
function formatMessage(msg) {
return parseHtmlSubset('<b>' + msg + '</b>', ['br', 'pre'])
.firstChild.innerHTML;
}
let result = '';
const message = this.currentUpdateStatusEvent_.message;
if (message) {
result += formatMessage(message);
}
const connectMessage = this.currentUpdateStatusEvent_.connectionTypes;
if (connectMessage) {
result += '<div>' + formatMessage(connectMessage) + '</div>';
}
return result;
}
},
/**
* @return {?string}
* @private
*/
getUpdateStatusIcon_() {
// If this platform has reached the end of the line, display an error icon
// and ignore UpdateStatus.
if (this.obsoleteSystemInfo_.endOfLine) {
return 'cr:error';
}
switch (this.currentUpdateStatusEvent_.status) {
case UpdateStatus.DISABLED_BY_ADMIN:
return 'cr20:domain';
case UpdateStatus.FAILED:
return 'cr:error';
case UpdateStatus.UPDATED:
case UpdateStatus.NEARLY_UPDATED:
return 'settings:check-circle';
default:
return null;
}
},
/**
* @return {?string}
* @private
*/
getThrobberSrcIfUpdating_() {
if (this.obsoleteSystemInfo_.endOfLine) {
return null;
}
switch (this.currentUpdateStatusEvent_.status) {
case UpdateStatus.CHECKING:
case UpdateStatus.UPDATING:
return 'chrome://resources/images/throbber_small.svg';
default:
return null;
}
},
// </if>
/**
* @param {!UpdateStatus} status
* @return {boolean}
* @private
*/
checkStatus_(status) {
return this.currentUpdateStatusEvent_.status == status;
},
/** @private */
onManagementPageTap_() {
window.location.href = 'chrome://management';
},
// <if expr="chromeos">
/**
* @return {string}
* @private
*/
getUpdateOsSettingsLink_() {
// Note: This string contains raw HTML and thus requires i18nAdvanced().
// Since the i18n template syntax (e.g., $i18n{}) does not include an
// "advanced" version, it's not possible to inline this link directly in the
// HTML.
return this.i18nAdvanced('aboutUpdateOsSettingsLink');
},
// </if>
/** @private */
onProductLogoTap_() {
this.$['product-logo'].animate(
{
transform: ['none', 'rotate(-10turn)'],
},
{
duration: 500,
easing: 'cubic-bezier(1, 0, 0, 1)',
});
},
// <if expr="_google_chrome">
/** @private */
onReportIssueTap_() {
this.aboutBrowserProxy_.openFeedbackDialog();
},
// </if>
/**
* @return {boolean}
* @private
*/
shouldShowIcons_() {
// <if expr="not chromeos">
if (this.obsoleteSystemInfo_.endOfLine) {
return true;
}
// </if>
return this.showUpdateStatus_;
},
});