blob: b619d2cdb8ed52a153b0f740db76786970996233 [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.
// Closure compiler won't let this be declared inside cr.define().
/** @enum {string} */
const SourceType = {
WEBSTORE: 'webstore',
POLICY: 'policy',
SIDELOADED: 'sideloaded',
UNPACKED: 'unpacked',
UNKNOWN: 'unknown',
};
cr.define('extensions', function() {
/**
* Returns true if the extension is enabled, including terminated
* extensions.
* @param {!chrome.developerPrivate.ExtensionState} state
* @return {boolean}
*/
function isEnabled(state) {
switch (state) {
case chrome.developerPrivate.ExtensionState.ENABLED:
case chrome.developerPrivate.ExtensionState.TERMINATED:
return true;
case chrome.developerPrivate.ExtensionState.BLACKLISTED:
case chrome.developerPrivate.ExtensionState.DISABLED:
return false;
}
assertNotReached();
}
/**
* @param {!chrome.developerPrivate.ExtensionInfo} extensionInfo
* @return {boolean} Whether the extension is controlled.
*/
function isControlled(extensionInfo) {
return !!extensionInfo.controlledInfo;
}
/**
* Returns true if the user can change whether or not the extension is
* enabled.
* @param {!chrome.developerPrivate.ExtensionInfo} item
* @return {boolean}
*/
function userCanChangeEnablement(item) {
// User doesn't have permission.
if (!item.userMayModify) {
return false;
}
// Item is forcefully disabled.
if (item.disableReasons.corruptInstall ||
item.disableReasons.suspiciousInstall ||
item.disableReasons.updateRequired) {
return false;
}
// An item with dependent extensions can't be disabled (it would bork the
// dependents).
if (item.dependentExtensions.length > 0) {
return false;
}
// Blacklisted can't be enabled, either.
if (item.state == chrome.developerPrivate.ExtensionState.BLACKLISTED) {
return false;
}
return true;
}
/**
* @param {!chrome.developerPrivate.ExtensionInfo} item
* @return {SourceType}
*/
function getItemSource(item) {
if (item.controlledInfo &&
item.controlledInfo.type ==
chrome.developerPrivate.ControllerType.POLICY) {
return SourceType.POLICY;
}
switch (item.location) {
case chrome.developerPrivate.Location.THIRD_PARTY:
return SourceType.SIDELOADED;
case chrome.developerPrivate.Location.UNPACKED:
return SourceType.UNPACKED;
case chrome.developerPrivate.Location.UNKNOWN:
return SourceType.UNKNOWN;
case chrome.developerPrivate.Location.FROM_STORE:
return SourceType.WEBSTORE;
}
assertNotReached(item.location);
}
/**
* @param {SourceType} source
* @return {string}
*/
function getItemSourceString(source) {
switch (source) {
case SourceType.POLICY:
return loadTimeData.getString('itemSourcePolicy');
case SourceType.SIDELOADED:
return loadTimeData.getString('itemSourceSideloaded');
case SourceType.UNPACKED:
return loadTimeData.getString('itemSourceUnpacked');
case SourceType.WEBSTORE:
return loadTimeData.getString('itemSourceWebstore');
case SourceType.UNKNOWN:
// Nothing to return. Calling code should use
// chrome.developerPrivate.ExtensionInfo's |locationText| instead.
return '';
}
assertNotReached();
}
/**
* Computes the human-facing label for the given inspectable view.
* @param {!chrome.developerPrivate.ExtensionView} view
* @return {string}
*/
function computeInspectableViewLabel(view) {
// Trim the "chrome-extension://<id>/".
const url = new URL(view.url);
let label = view.url;
if (url.protocol == 'chrome-extension:') {
label = url.pathname.substring(1);
}
if (label == '_generated_background_page.html') {
label = loadTimeData.getString('viewBackgroundPage');
}
// Add any qualifiers.
if (view.incognito) {
label += ' ' + loadTimeData.getString('viewIncognito');
}
if (view.renderProcessId == -1) {
label += ' ' + loadTimeData.getString('viewInactive');
}
if (view.isIframe) {
label += ' ' + loadTimeData.getString('viewIframe');
}
return label;
}
return {
isControlled: isControlled,
isEnabled: isEnabled,
userCanChangeEnablement: userCanChangeEnablement,
getItemSource: getItemSource,
getItemSourceString: getItemSourceString,
computeInspectableViewLabel: computeInspectableViewLabel
};
});