// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
import 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
import 'chrome://resources/cr_elements/icons_lit.html.js';
import './icons.html.js';
import './strings.m.js';
import {I18nMixinLit} from 'chrome://resources/cr_elements/i18n_mixin_lit.js';
import {WebUiListenerMixinLit} from 'chrome://resources/cr_elements/web_ui_listener_mixin_lit.js';
// <if expr="is_chromeos">
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
// </if>
import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
// clang-format off
import type {Application, BrowserReportingResponse, Extension, ManagementBrowserProxy, ThreatProtectionInfo} from './management_browser_proxy.js';
import { ManagementBrowserProxyImpl, ReportingType} from './management_browser_proxy.js';
// <if expr="is_chromeos">
import type {DeviceReportingResponse} from './management_browser_proxy.js';
import { DeviceReportingType} from './management_browser_proxy.js';
// </if>
import {getCss} from './management_ui.css.js';
import {getHtml} from './management_ui.html.js';
// clang-format on
interface BrowserReportingData {
messageIds: string[];
icon?: string;
}
const ManagementUiElementBase =
WebUiListenerMixinLit(I18nMixinLit(CrLitElement));
export class ManagementUiElement extends ManagementUiElementBase {
static get is() {
return 'management-ui';
}
static override get styles() {
return getCss();
}
override render() {
return getHtml.bind(this)();
}
static override get properties() {
return {
/**
* List of messages related to application reporting.
*/
applications_: {type: Array},
/**
* Title of subsection for application reporting.
*/
applicationReportingSubtitle_: {type: String},
/**
* List of messages related to browser reporting.
*/
browserReportingInfo_: {type: Array},
/**
* List of messages related to profile reporting.
*/
profileReportingInfo_: {type: Array},
/**
* List of messages related to extension reporting.
*/
extensions_: {type: Array},
/**
* Title of subsection for extension reporting.
*/
extensionReportingSubtitle_: {type: String},
/**
* List of messages related to managed websites reporting.
*/
managedWebsites_: {type: Array},
managedWebsitesSubtitle_: {type: String},
// <if expr="is_chromeos">
/**
* List of messages related to device reporting.
*/
deviceReportingInfo_: {type: Array},
/**
* Message stating if the Trust Roots are configured.
*/
localTrustRoots_: {type: String},
/**
* Message stating if uploading of downloads or screenshots to cloud
* storage is configured.
*/
filesUploadToCloud_: {type: String},
customerLogo_: {type: String},
managementOverview_: {type: String},
pluginVmDataCollectionEnabled_: {type: Boolean},
eolAdminMessage_: {type: String},
eolMessage_: {type: String},
showMonitoredNetworkPrivacyDisclosure_: {type: Boolean},
// </if>
subtitle_: {type: String},
// <if expr="not chromeos_ash">
managementNoticeHtml_: {type: String},
// </if>
managed_: {type: Boolean},
threatProtectionInfo_: {type: Object},
};
}
protected applications_: Application[]|null = null;
protected browserReportingInfo_: BrowserReportingData[]|null = null;
protected profileReportingInfo_: BrowserReportingData[]|null = null;
protected extensions_: Extension[]|null = null;
protected managedWebsites_: string[]|null = null;
protected managedWebsitesSubtitle_: string = '';
// <if expr="is_chromeos">
protected deviceReportingInfo_: DeviceReportingResponse[]|null = null;
protected localTrustRoots_: string = '';
protected filesUploadToCloud_: string = '';
protected customerLogo_: string = '';
protected managementOverview_: string = '';
protected pluginVmDataCollectionEnabled_: boolean = false;
protected eolAdminMessage_: string = '';
protected eolMessage_: string = '';
protected showMonitoredNetworkPrivacyDisclosure_: boolean = false;
// </if>
protected subtitle_: string = '';
// <if expr="not chromeos_ash">
protected managementNoticeHtml_: TrustedHTML = window.trustedTypes!.emptyHTML;
// </if>
protected managed_: boolean = false;
protected applicationReportingSubtitle_: string = '';
protected extensionReportingSubtitle_: string = '';
protected threatProtectionInfo_: ThreatProtectionInfo|null = null;
private browserProxy_: ManagementBrowserProxy =
ManagementBrowserProxyImpl.getInstance();
/** @override */
override connectedCallback() {
super.connectedCallback();
document.documentElement.classList.remove('loading');
this.updateManagedFields_();
this.initReportingInfo_();
this.getThreatProtectionInfo_();
this.addWebUiListener(
'browser-reporting-info-updated',
(reportingInfo: BrowserReportingResponse[]) =>
this.onBrowserReportingInfoReceived_(reportingInfo));
this.addWebUiListener(
'profile-reporting-info-updated',
(reportingInfo: BrowserReportingResponse[]) =>
this.onProfileReportingInfoReceived_(reportingInfo));
// <if expr="is_chromeos">
this.addWebUiListener(
'plugin-vm-data-collection-updated',
(enabled: boolean) => this.pluginVmDataCollectionEnabled_ = enabled);
// </if>
this.addWebUiListener('managed_data_changed', () => {
this.updateManagedFields_();
});
this.addWebUiListener(
'threat-protection-info-updated',
(info: ThreatProtectionInfo) => this.threatProtectionInfo_ = info);
this.getExtensions_();
this.getManagedWebsites_();
this.getApplications_();
// <if expr="is_chromeos">
this.getDeviceReportingInfo_();
this.getPluginVmDataCollectionStatus_();
this.getLocalTrustRootsInfo_();
this.getFilesUploadToCloudInfo_();
// </if>
}
private initReportingInfo_() {
this.browserProxy_.initBrowserReportingInfo().then(
reportingInfo => this.onBrowserReportingInfoReceived_(reportingInfo));
this.browserProxy_.initProfileReportingInfo().then(
reportingInfo => this.onProfileReportingInfoReceived_(reportingInfo));
}
private onBrowserReportingInfoReceived_(reportingInfo:
BrowserReportingResponse[]) {
const reportingInfoMap = reportingInfo.reduce((info, response) => {
info[response.reportingType] = info[response.reportingType] || {
icon: this.getIconForReportingType_(response.reportingType),
messageIds: [],
};
info[response.reportingType]!.messageIds.push(response.messageId);
return info;
}, {} as {[k: string]: {icon: string, messageIds: string[]}});
const reportingTypeOrder: {[k: string]: number} = {
[ReportingType.URL]: 1,
[ReportingType.SECURITY]: 2,
[ReportingType.EXTENSIONS]: 3,
[ReportingType.USER]: 4,
[ReportingType.USER_ACTIVITY]: 5,
[ReportingType.DEVICE]: 6,
[ReportingType.LEGACY_TECH]: 7,
};
this.browserReportingInfo_ =
Object.keys(reportingInfoMap)
.sort((a, b) => reportingTypeOrder[a]! - reportingTypeOrder[b]!)
.map(reportingType => reportingInfoMap[reportingType]) as
BrowserReportingData[];
}
private onProfileReportingInfoReceived_(reportingInfo:
BrowserReportingResponse[]) {
this.profileReportingInfo_ =
reportingInfo.map((info) => ({
messageIds: [info.messageId],
}));
}
private getExtensions_() {
this.browserProxy_.getExtensions().then(extensions => {
this.extensions_ = extensions;
});
}
private getManagedWebsites_() {
this.browserProxy_.getManagedWebsites().then(managedWebsites => {
this.managedWebsites_ = managedWebsites;
});
}
private getApplications_() {
this.browserProxy_.getApplications().then(applications => {
this.applications_ = applications;
});
}
private getThreatProtectionInfo_() {
this.browserProxy_.getThreatProtectionInfo().then(info => {
this.threatProtectionInfo_ = info;
});
}
/**
* @return Whether there is threat protection info to show.
*/
protected showThreatProtectionInfo_(): boolean {
return !!this.threatProtectionInfo_ &&
this.threatProtectionInfo_.info.length > 0;
}
// <if expr="is_chromeos">
private getLocalTrustRootsInfo_() {
this.browserProxy_.getLocalTrustRootsInfo().then(trustRootsConfigured => {
this.localTrustRoots_ = trustRootsConfigured ?
loadTimeData.getString('managementTrustRootsConfigured') :
'';
});
}
private getFilesUploadToCloudInfo_() {
this.browserProxy_.getFilesUploadToCloudInfo().then(info => {
this.filesUploadToCloud_ = info;
});
}
private getDeviceReportingInfo_() {
this.browserProxy_.getDeviceReportingInfo().then(reportingInfo => {
this.deviceReportingInfo_ = reportingInfo;
});
}
private getPluginVmDataCollectionStatus_() {
this.browserProxy_.getPluginVmDataCollectionStatus().then(
pluginVmDataCollectionEnabled => {
this.pluginVmDataCollectionEnabled_ = pluginVmDataCollectionEnabled;
});
}
/**
* @return Whether there are device reporting info to show.
*/
protected showDeviceReportingInfo_(): boolean {
return !!this.deviceReportingInfo_ && this.deviceReportingInfo_.length > 0;
}
/**
* @param eolAdminMessage The device return instructions
* @return Whether there are device return instructions from the
* admin in case an update is required after reaching end of life.
*/
protected isEolAdminMessageEmpty_(): boolean {
return !this.eolAdminMessage_ || this.eolAdminMessage_.trim().length === 0;
}
/**
* @return The associated icon.
*/
protected getIconForDeviceReportingType_(reportingType: DeviceReportingType):
string {
switch (reportingType) {
case DeviceReportingType.SUPERVISED_USER:
return 'management:supervised-user';
case DeviceReportingType.DEVICE_ACTIVITY:
return 'management:timelapse';
case DeviceReportingType.STATISTIC:
return 'management:bar-chart';
case DeviceReportingType.DEVICE:
return 'cr:computer';
case DeviceReportingType.CRASH_REPORT:
return 'management:crash';
case DeviceReportingType.APP_INFO_AND_ACTIVITY:
return 'management:timelapse';
case DeviceReportingType.LOGS:
return 'management:report';
case DeviceReportingType.PRINT:
return 'cr:print';
case DeviceReportingType.PRINT_JOBS:
return 'cr:print';
case DeviceReportingType.DLP_EVENTS:
return 'management:policy';
case DeviceReportingType.CROSTINI:
return 'management:linux';
case DeviceReportingType.USERNAME:
return 'management:account-circle';
case DeviceReportingType.EXTENSION:
return 'cr:extension';
case DeviceReportingType.ANDROID_APPLICATION:
return 'management:play-store';
case DeviceReportingType.LOGIN_LOGOUT:
return 'management:timelapse';
case DeviceReportingType.CRD_SESSIONS:
return 'management:timelapse';
case DeviceReportingType.PERIPHERALS:
return 'management:usb';
case DeviceReportingType.LEGACY_TECH:
return 'management:legacy-tech';
case DeviceReportingType.WEBSITE_INFO_AND_ACTIVITY:
return 'management:web';
case DeviceReportingType.FILE_EVENTS:
return 'management:policy';
default:
return 'cr:computer';
}
}
protected getDeviceReportingHtmlContent_(response: DeviceReportingResponse):
TrustedHTML {
return this.i18nAdvanced(
response.messageId, {substitutions: response.messageParams});
}
// </if>
/**
* @return Whether there are browser reporting info to show.
*/
protected showBrowserReportingInfo_(): boolean {
return !!this.browserReportingInfo_ &&
this.browserReportingInfo_.length > 0;
}
/**
* @return Whether there are profile reporting info to show with new format.
*/
protected showProfileReportingInfo_(): boolean {
return !!this.profileReportingInfo_ &&
this.profileReportingInfo_.length > 0;
}
/**
* @return Whether there are extension reporting info to show.
*/
protected showExtensionReportingInfo_(): boolean {
return !!this.extensions_ && this.extensions_.length > 0;
}
/**
* @return Whether there are application reporting info to show.
*/
protected showApplicationReportingInfo_(): boolean {
return !!this.applications_ && this.applications_.length > 0;
}
/**
* @return Whether there is managed websites info to show.
*/
protected showManagedWebsitesInfo_(): boolean {
return !!this.managedWebsites_ && this.managedWebsites_.length > 0;
}
/**
* @return The associated icon.
*/
private getIconForReportingType_(reportingType: ReportingType): string {
switch (reportingType) {
case ReportingType.SECURITY:
return 'cr:security';
case ReportingType.DEVICE:
return 'cr:computer';
case ReportingType.EXTENSIONS:
return 'cr:extension';
case ReportingType.USER:
return 'management:account-circle';
case ReportingType.USER_ACTIVITY:
return 'management:public';
case ReportingType.LEGACY_TECH:
return 'management:legacy-tech';
case ReportingType.URL:
return 'management:link';
default:
return 'cr:security';
}
}
/**
* Handles the 'search-changed' event fired from the toolbar.
* Redirects to the settings page initialized the the current
* search query.
*/
protected onSearchChanged_(e: CustomEvent<string>) {
const query = e.detail;
window.location.href =
`chrome://settings?search=${encodeURIComponent(query)}`;
}
protected onTapBack_() {
if (history.length > 1) {
history.back();
} else {
window.location.href = 'chrome://settings/help';
}
}
private updateManagedFields_() {
this.browserProxy_.getContextualManagedData().then(data => {
this.managed_ = data.managed;
this.extensionReportingSubtitle_ = data.extensionReportingSubtitle;
this.managedWebsitesSubtitle_ = data.managedWebsitesSubtitle;
this.applicationReportingSubtitle_ = data.applicationReportingSubtitle;
this.subtitle_ = data.pageSubtitle;
// <if expr="chromeos_ash">
this.customerLogo_ = data.customerLogo;
this.managementOverview_ = data.overview;
this.eolMessage_ = data.eolMessage;
this.showMonitoredNetworkPrivacyDisclosure_ =
data.showMonitoredNetworkPrivacyDisclosure;
try {
// Sanitizing the message could throw an error if it contains non
// supported markup.
sanitizeInnerHtml(data.eolAdminMessage);
this.eolAdminMessage_ = data.eolAdminMessage;
} catch (e) {
this.eolAdminMessage_ = '';
}
// </if>
// <if expr="not chromeos_ash">
this.managementNoticeHtml_ = sanitizeInnerHtml(
data.browserManagementNotice, {attrs: ['aria-label']});
// </if>
});
}
}
customElements.define(ManagementUiElement.is, ManagementUiElement);