Bug 1827910 - Show deprecation warnings for browser_style in MV3 r=willdurand

This patch has no observable changes, other than printing deprecation
messages when browser_style is effectively true in MV3.

This patch does include the full logic for all stages of the deprecation
process behind prefs, which will follow the schedule described at:
https://bugzilla.mozilla.org/show_bug.cgi?id=1827910#c1.

All combinations of these prefs are fully covered by unit tests in
toolkit/components/extensions/test/xpcshell/test_ext_browser_style_deprecation.js
The next test tasks confirm the behavior of the current patch:
- browser_style_never_deprecated_in_MV2
- supported_with_browser_style_false
- supported_with_browser_style_true
- supported_with_mv2_defaults

Differential Revision: https://phabricator.services.mozilla.com/D176811
This commit is contained in:
Rob Wu 2023-05-04 16:29:07 +00:00
parent a0f42962d7
commit bcc6eb3ead
9 changed files with 357 additions and 10 deletions

View file

@ -25,7 +25,7 @@
"browser_style": {
"type": "boolean",
"optional": true,
"default": true
"description": "Defaults to true in Manifest V2; Deprecated in Manifest V3."
},
"default_panel": {
"type": "string",

View file

@ -105,6 +105,7 @@ add_task(async function test_v3_action_context_menu() {
action: {
default_title: "Test Action",
default_popup: "test.html",
// TODO bug 1830712: Remove this. Probably not even needed for the test.
browser_style: true,
},
},

View file

@ -1946,6 +1946,14 @@ pref("extensions.manifestV3.enabled", true);
// Install origins restriction.
pref("extensions.install_origins.enabled", false);
// browser_style deprecation - bug 1827910.
// TODO bug 1830711: set to false (after bug 1830710).
// TODO bug 1830712: remove pref.
pref("extensions.browser_style_mv3.supported", true);
// TODO bug 1830710: set to false.
// TODO bug 1830712: remove pref.
pref("extensions.browser_style_mv3.same_as_mv2", true);
// Middle-mouse handling
pref("middlemouse.paste", false);
pref("middlemouse.contentLoadURL", false);

View file

@ -153,6 +153,28 @@ XPCOMUtils.defineLazyPreferenceGetter(
false
);
// Deprecation of browser_style, through .supported & .same_as_mv2 prefs:
// - true true = warn only: deprecation message only (no behavioral changes).
// - true false = deprecate: default to false, even if default was true in MV2.
// - false = remove: always use false, even when true is specified.
// (if .same_as_mv2 is set, also warn if the default changed)
// Deprecation plan: https://bugzilla.mozilla.org/show_bug.cgi?id=1827910#c1
// Bug 1830711 will set browser_style_mv3.supported to false.
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"browserStyleMV3supported",
"extensions.browser_style_mv3.supported",
false
);
// Bug 1830710 will set browser_style_mv3.same_as_mv2 to true.
// Bug 1830711 will then set browser_style_mv3.supported to false.
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"browserStyleMV3sameAsMV2",
"extensions.browser_style_mv3.same_as_mv2",
false
);
var {
GlobalManager,
IconDetails,
@ -1289,6 +1311,51 @@ class ExtensionData {
return lazy.Schemas.normalize(this.rawManifest, manifestType, context);
}
#parseBrowserStyleInManifest(manifest, manifestKey, defaultValueInMV2) {
const obj = manifest[manifestKey];
if (!obj) {
return;
}
const browserStyleIsVoid = obj.browser_style == null;
obj.browser_style ??= defaultValueInMV2;
if (this.manifestVersion < 3 || !obj.browser_style) {
// MV2 (true or false), or MV3 (false set explicitly or default false).
// No changes in observed behavior, return now to avoid logspam.
return;
}
// Now there are two cases (MV3 only):
// - browser_style was not specified, but defaults to true.
// - browser_style was set to true by the extension.
//
// These will eventually be deprecated. For the deprecation plan, see
// https://bugzilla.mozilla.org/show_bug.cgi?id=1827910#c1
let warning;
if (!lazy.browserStyleMV3supported) {
obj.browser_style = false;
if (browserStyleIsVoid && !lazy.browserStyleMV3sameAsMV2) {
// defaultValueInMV2 is true, but there was no intent to use these
// defaults. Don't warn.
return;
}
warning = `"browser_style:true" is no longer supported in Manifest Version 3.`;
} else {
warning = `"browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future.`;
}
if (browserStyleIsVoid) {
warning += ` While "${manifestKey}.browser_style" was not explicitly specified in manifest.json, its default value was true.`;
if (!lazy.browserStyleMV3sameAsMV2) {
obj.browser_style = false;
warning += ` The default value of "${manifestKey}.browser_style" has changed from true to false in Manifest Version 3.`;
} else {
warning += ` Its default will change to false in Manifest Version 3 starting from Firefox 115.`;
}
}
this.manifestWarning(
`Warning processing ${manifestKey}.browser_style: ${warning}`
);
}
async initializeAddonTypeAndID() {
if (this.type) {
// Already initialized.
@ -1429,6 +1496,15 @@ class ExtensionData {
);
}
this.#parseBrowserStyleInManifest(manifest, "options_ui", true);
if (this.manifestVersion < 3) {
this.#parseBrowserStyleInManifest(manifest, "browser_action", false);
} else {
this.#parseBrowserStyleInManifest(manifest, "action", false);
}
this.#parseBrowserStyleInManifest(manifest, "page_action", false);
this.#parseBrowserStyleInManifest(manifest, "sidebar_action", true);
let apiNames = new Set();
let dependencies = new Set();
let originPermissions = new Set();

View file

@ -36,7 +36,7 @@
"browser_style": {
"type": "boolean",
"optional": true,
"default": false
"description": "Deprecated in Manifest V3."
},
"default_area": {
"description": "Defines the location the browserAction will appear by default. The default location is navbar.",

View file

@ -183,22 +183,20 @@
"browser_style": {
"type": "boolean",
"optional": true,
"default": true
"description": "Defaults to true in Manifest V2; Deprecated in Manifest V3."
},
"chrome_style": {
"type": "boolean",
"optional": true
"optional": true,
"max_manifest_version": 2,
"description": "chrome_style is ignored in Firefox. Its replacement (browser_style) has been deprecated."
},
"open_in_tab": {
"type": "boolean",
"optional": true
}
},
"additionalProperties": {
"type": "any",
"deprecated": "An unexpected property was found in the WebExtension manifest"
}
"additionalProperties": { "$ref": "UnrecognizedProperty" }
},
"content_scripts": {

View file

@ -31,7 +31,7 @@
"browser_style": {
"type": "boolean",
"optional": true,
"default": false
"description": "Deprecated in Manifest V3."
},
"show_matches": {
"type": "array",

View file

@ -0,0 +1,263 @@
"use strict";
AddonTestUtils.init(this);
// This test expects and checks deprecation warnings.
ExtensionTestUtils.failOnSchemaWarnings(false);
const PREF_SUPPORTED = "extensions.browser_style_mv3.supported";
const PREF_SAME_AS_MV2 = "extensions.browser_style_mv3.same_as_mv2";
// Set the prefs to the defaults at the end of the deprecation process.
// TODO bug 1830711: remove these two lines.
Services.prefs.setBoolPref(PREF_SUPPORTED, false);
Services.prefs.setBoolPref(PREF_SAME_AS_MV2, false);
function checkBrowserStyleInManifestKey(extension, key, expected) {
let actual = extension.extension.manifest[key].browser_style;
Assert.strictEqual(actual, expected, `Expected browser_style of "${key}"`);
}
const BROWSER_STYLE_MV2_DEFAULTS = "BROWSER_STYLE_MV2_DEFAULTS";
async function checkBrowserStyle({
manifest_version = 3,
browser_style_in_manifest = null,
expected_browser_style,
expected_warnings,
}) {
const actionKey = manifest_version === 2 ? "browser_action" : "action";
// sidebar_action is implemented in browser/ and therefore only available to
// Firefox desktop and not other toolkit apps such as Firefox for Android,
// Thunderbird, etc.
const IS_SIDEBAR_SUPPORTED = AppConstants.MOZ_BUILD_APP === "browser";
const extension = ExtensionTestUtils.loadExtension({
manifest: {
manifest_version,
options_ui: {
page: "options.html",
browser_style: browser_style_in_manifest,
},
[actionKey]: {
browser_style: browser_style_in_manifest,
},
page_action: {
browser_style: browser_style_in_manifest,
},
sidebar_action: {
default_panel: "sidebar.html",
browser_style: browser_style_in_manifest,
},
},
});
await extension.startup();
if (expected_browser_style === BROWSER_STYLE_MV2_DEFAULTS) {
checkBrowserStyleInManifestKey(extension, "options_ui", true);
checkBrowserStyleInManifestKey(extension, actionKey, false);
checkBrowserStyleInManifestKey(extension, "page_action", false);
if (IS_SIDEBAR_SUPPORTED) {
checkBrowserStyleInManifestKey(extension, "sidebar_action", true);
}
} else {
let value = expected_browser_style;
checkBrowserStyleInManifestKey(extension, "options_ui", value);
checkBrowserStyleInManifestKey(extension, actionKey, value);
checkBrowserStyleInManifestKey(extension, "page_action", value);
if (IS_SIDEBAR_SUPPORTED) {
checkBrowserStyleInManifestKey(extension, "sidebar_action", value);
}
}
if (!IS_SIDEBAR_SUPPORTED) {
expected_warnings = expected_warnings.filter(
msg => !msg.includes("sidebar_action")
);
expected_warnings.unshift(
`Reading manifest: Warning processing sidebar_action: An unexpected property was found in the WebExtension manifest.`
);
}
const warnings = extension.extension.warnings;
await extension.unload();
Assert.deepEqual(
warnings,
expected_warnings,
`Got expected warnings for MV${manifest_version} extension with browser_style:${browser_style_in_manifest}.`
);
}
async function repeatTestIndependentOfPref_browser_style_same_as_mv2(testFn) {
for (let same_as_mv2 of [true, false]) {
await runWithPrefs([[PREF_SAME_AS_MV2, same_as_mv2]], testFn);
}
}
add_task(async function browser_style_never_deprecated_in_MV2() {
async function check_browser_style_never_deprecated_in_MV2() {
await checkBrowserStyle({
manifest_version: 2,
browser_style_in_manifest: true,
expected_browser_style: true,
expected_warnings: [],
});
await checkBrowserStyle({
manifest_version: 2,
browser_style_in_manifest: false,
expected_browser_style: false,
expected_warnings: [],
});
await checkBrowserStyle({
manifest_version: 2,
browser_style_in_manifest: null,
expected_browser_style: "BROWSER_STYLE_MV2_DEFAULTS",
expected_warnings: [],
});
}
// Regardless of all potential test configurations, browser_style is never
// deprecated in MV2.
for (let supported of [true, false]) {
for (let same_as_mv2 of [true, false]) {
await runWithPrefs(
[
[PREF_SUPPORTED, supported],
[PREF_SAME_AS_MV2, same_as_mv2],
],
check_browser_style_never_deprecated_in_MV2
);
}
}
});
// Disable browser_style:true - bug 1830711.
add_task(async function unsupported_and_browser_style_true() {
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: true,
expected_browser_style: false,
expected_warnings: [
// TODO bug 1830712: Update warnings when max_manifest_version:2 is used.
`Reading manifest: Warning processing options_ui.browser_style: "browser_style:true" is no longer supported in Manifest Version 3.`,
`Reading manifest: Warning processing action.browser_style: "browser_style:true" is no longer supported in Manifest Version 3.`,
`Reading manifest: Warning processing page_action.browser_style: "browser_style:true" is no longer supported in Manifest Version 3.`,
`Reading manifest: Warning processing sidebar_action.browser_style: "browser_style:true" is no longer supported in Manifest Version 3.`,
],
});
});
add_task(async function unsupported_and_browser_style_false() {
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: false,
expected_browser_style: false,
// TODO bug 1830712: Add warnings when max_manifest_version:2 is used.
expected_warnings: [],
});
});
add_task(async function unsupported_and_browser_style_default() {
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: null,
expected_browser_style: false,
expected_warnings: [],
});
});
add_task(
{ pref_set: [[PREF_SUPPORTED, true]] },
async function supported_with_browser_style_true() {
await repeatTestIndependentOfPref_browser_style_same_as_mv2(async () => {
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: true,
expected_browser_style: true,
expected_warnings: [
`Reading manifest: Warning processing options_ui.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future.`,
`Reading manifest: Warning processing action.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future.`,
`Reading manifest: Warning processing page_action.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future.`,
`Reading manifest: Warning processing sidebar_action.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future.`,
],
});
});
}
);
add_task(
{ pref_set: [[PREF_SUPPORTED, true]] },
async function supported_with_browser_style_false() {
await repeatTestIndependentOfPref_browser_style_same_as_mv2(async () => {
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: false,
expected_browser_style: false,
expected_warnings: [],
});
});
}
);
// Initial prefs - warn only - https://bugzilla.mozilla.org/show_bug.cgi?id=1827910#c1
add_task(
{
pref_set: [
[PREF_SUPPORTED, true],
[PREF_SAME_AS_MV2, true],
],
},
async function supported_with_mv2_defaults() {
const makeWarning = manifestKey =>
`Reading manifest: Warning processing ${manifestKey}.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future. While "${manifestKey}.browser_style" was not explicitly specified in manifest.json, its default value was true. Its default will change to false in Manifest Version 3 starting from Firefox 115.`;
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: null,
expected_browser_style: "BROWSER_STYLE_MV2_DEFAULTS",
expected_warnings: [
makeWarning("options_ui"),
makeWarning("sidebar_action"),
],
});
}
);
// Deprecation + change defaults - bug 1830710.
add_task(
{
pref_set: [
[PREF_SUPPORTED, true],
[PREF_SAME_AS_MV2, false],
],
},
async function supported_with_browser_style_default_false() {
const makeWarning = manifestKey =>
`Reading manifest: Warning processing ${manifestKey}.browser_style: "browser_style:true" has been deprecated in Manifest Version 3 and will be unsupported in the near future. While "${manifestKey}.browser_style" was not explicitly specified in manifest.json, its default value was true. The default value of "${manifestKey}.browser_style" has changed from true to false in Manifest Version 3.`;
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: null,
expected_browser_style: false,
expected_warnings: [
makeWarning("options_ui"),
makeWarning("sidebar_action"),
],
});
}
);
// While we are not planning to set this pref combination, users can do so if
// they desire.
add_task(
{
pref_set: [
[PREF_SUPPORTED, false],
[PREF_SAME_AS_MV2, true],
],
},
async function unsupported_with_mv2_defaults() {
const makeWarning = manifestKey =>
`Reading manifest: Warning processing ${manifestKey}.browser_style: "browser_style:true" is no longer supported in Manifest Version 3. While "${manifestKey}.browser_style" was not explicitly specified in manifest.json, its default value was true. Its default will change to false in Manifest Version 3 starting from Firefox 115.`;
await checkBrowserStyle({
manifest_version: 3,
browser_style_in_manifest: null,
expected_browser_style: false,
expected_warnings: [
makeWarning("options_ui"),
makeWarning("sidebar_action"),
],
});
}
);

View file

@ -41,6 +41,7 @@ skip-if =
skip-if =
os == "win" && os_version == "6.1" # Skip on Azure - frequent failure
[test_ext_browsingData_cookies_cookieStoreId.js]
[test_ext_browser_style_deprecation.js]
[test_ext_cache_api.js]
[test_ext_captivePortal.js]
# As with test_captive_portal_service.js, we use the same limits here.