Extensions: Deprecate the plugins requirement.
NPAPI plugin support has been removed from chrome and the "plugins" extension
manifest key is effectively deprecated. This CL deprecates the plugins
requirement. Extensions which specify the plugins requirements will now get an
install warning. Extensions explicitly requesting the npapi requirement (by
setting requirements.plugins.npapi to true) in their manifest will get a load
error.
BUG=732590
Change-Id: I874ca17b5143516f1746fff90197243eb6ac2999
Reviewed-on: https://chromium-review.googlesource.com/795361
Reviewed-by: Devlin <[email protected]>
Commit-Queue: Karan Bhatia <[email protected]>
Cr-Commit-Position: refs/heads/master@{#521122}
diff --git a/chrome/common/extensions/docs/templates/articles/manifest/requirements.html b/chrome/common/extensions/docs/templates/articles/manifest/requirements.html
index 1c68cee2..89c3596d 100644
--- a/chrome/common/extensions/docs/templates/articles/manifest/requirements.html
+++ b/chrome/common/extensions/docs/templates/articles/manifest/requirements.html
@@ -28,6 +28,10 @@
}
</pre>
+<p class="warning">
+NPAPI Plugin support for extension has been <a href="http://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html">discontinued</a>. As part of this, the <b>"plugins"</b> requirement described below has been deprecated.
+</p>
+
<p>
The "plugins" requirement indicates
if an app or extension requires NPAPI to run.
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
index 3479135..7b56ef53e 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_requirements_unittest.cc
@@ -33,15 +33,6 @@
Testcase("requirements_invalid_3d_no_features.json",
ErrorUtils::FormatErrorMessage(
errors::kInvalidRequirement, "3D")),
- Testcase("requirements_invalid_plugins.json",
- ErrorUtils::FormatErrorMessage(
- errors::kInvalidRequirement, "plugins")),
- Testcase("requirements_invalid_plugins_key.json",
- ErrorUtils::FormatErrorMessage(
- errors::kInvalidRequirement, "plugins")),
- Testcase("requirements_invalid_plugins_value.json",
- ErrorUtils::FormatErrorMessage(
- errors::kInvalidRequirement, "plugins"))
};
RunTestcases(testcases, arraysize(testcases), EXPECT_TYPE_ERROR);
@@ -53,39 +44,27 @@
"requirements_valid_empty.json"));
ASSERT_TRUE(extension.get());
EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, false);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, false);
// Test loading all the requirements.
extension = LoadAndExpectSuccess("requirements_valid_full.json");
ASSERT_TRUE(extension.get());
EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, true);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, true);
}
-// When an npapi plugin is present, the default of the "npapi" requirement
-// changes.
-TEST_F(RequirementsManifestTest, RequirementsNpapiDefault) {
- scoped_refptr<Extension> extension(LoadAndExpectSuccess(
- "requirements_npapi_empty.json"));
- ASSERT_TRUE(extension.get());
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, false);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, true);
+// Tests the deprecated plugin requirement.
+TEST_F(RequirementsManifestTest, RequirementsPlugin) {
+ // Using the plugins requirement should cause an install warning.
+ RunTestcase({"requirements_invalid_plugins_value.json",
+ errors::kPluginsRequirementDeprecated},
+ EXPECT_TYPE_WARNING);
+ RunTestcase(
+ {"requirements_npapi_false.json", errors::kPluginsRequirementDeprecated},
+ EXPECT_TYPE_WARNING);
- extension = LoadAndExpectSuccess(
- "requirements_npapi_empty_plugins_empty.json");
- ASSERT_TRUE(extension.get());
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, false);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, false);
-
- extension = LoadAndExpectSuccess("requirements_npapi.json");
- ASSERT_TRUE(extension.get());
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, false);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, false);
-
- extension = LoadAndExpectSuccess("requirements_npapi_plugins_empty.json");
- ASSERT_TRUE(extension.get());
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).webgl, false);
- EXPECT_EQ(RequirementsInfo::GetRequirements(extension.get()).npapi, true);
+ // Explicitly requesting the npapi requirement should cause an error.
+ RunTestcase(
+ {"requirements_npapi_true.json", errors::kNPAPIPluginsNotSupported},
+ EXPECT_TYPE_ERROR);
}
} // namespace extensions
diff --git a/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/manifest.json b/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/manifest.json
index cd1abce..84abd4e 100644
--- a/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/manifest.json
+++ b/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/manifest.json
@@ -11,13 +11,5 @@
"js": ["content_script.js"],
"run_at": "document_start"
}],
- "permissions": [ "<all_urls>" ],
- "plugins": [
- {"path": "plugin.dll", "public": true}
- ],
- "requirements": {
- "plugins": {
- "npapi": false
- }
- }
+ "permissions": [ "<all_urls>" ]
}
diff --git a/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/plugin.dll b/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/plugin.dll
deleted file mode 100755
index 8b13789..0000000
--- a/chrome/test/data/extensions/api_test/cross_origin_xhr/all_urls/plugin.dll
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins.json b/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins.json
deleted file mode 100644
index a2b08ae..0000000
--- a/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "Requirements Manifest Test",
- "version": "1.0",
- "manifest_version": 2,
- "requirements": {
- "plugins": false
- }
-}
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins_key.json b/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins_key.json
deleted file mode 100644
index 0d75b85d..0000000
--- a/chrome/test/data/extensions/manifest_tests/requirements_invalid_plugins_key.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "Requirements Manifest Test",
- "version": "1.0",
- "manifest_version": 2,
- "requirements": {
- "plugins": {
- "foo": false
- }
- }
-}
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty.json b/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty.json
deleted file mode 100644
index 4edb888..0000000
--- a/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "Requirements Manifest Test",
- "version": "1.0",
- "manifest_version": 2,
- "plugins": [
- {"path": "foo.dll", "public": true}
- ]
-}
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty_plugins_empty.json b/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty_plugins_empty.json
deleted file mode 100644
index 0591973..0000000
--- a/chrome/test/data/extensions/manifest_tests/requirements_npapi_empty_plugins_empty.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "Requirements Manifest Test",
- "version": "1.0",
- "manifest_version": 2,
- "plugins": [
- ]
-}
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_npapi.json b/chrome/test/data/extensions/manifest_tests/requirements_npapi_false.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/requirements_npapi.json
rename to chrome/test/data/extensions/manifest_tests/requirements_npapi_false.json
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_npapi_plugins_empty.json b/chrome/test/data/extensions/manifest_tests/requirements_npapi_true.json
similarity index 100%
rename from chrome/test/data/extensions/manifest_tests/requirements_npapi_plugins_empty.json
rename to chrome/test/data/extensions/manifest_tests/requirements_npapi_true.json
diff --git a/chrome/test/data/extensions/manifest_tests/requirements_valid_full.json b/chrome/test/data/extensions/manifest_tests/requirements_valid_full.json
index 7eefc47..8bcefa2 100644
--- a/chrome/test/data/extensions/manifest_tests/requirements_valid_full.json
+++ b/chrome/test/data/extensions/manifest_tests/requirements_valid_full.json
@@ -5,9 +5,6 @@
"requirements": {
"3D": {
"features": ["css3d", "webgl"]
- },
- "plugins": {
- "npapi": true
}
}
}
diff --git a/extensions/browser/preload_check.h b/extensions/browser/preload_check.h
index 7ddf4a1..8c92a23 100644
--- a/extensions/browser/preload_check.h
+++ b/extensions/browser/preload_check.h
@@ -27,7 +27,6 @@
BLACKLISTED_ID,
BLACKLISTED_UNKNOWN,
DISALLOWED_BY_POLICY,
- NPAPI_NOT_SUPPORTED,
WEBGL_NOT_SUPPORTED,
WINDOW_SHAPE_NOT_SUPPORTED,
};
diff --git a/extensions/browser/requirements_checker.cc b/extensions/browser/requirements_checker.cc
index a70b043..68b9da9 100644
--- a/extensions/browser/requirements_checker.cc
+++ b/extensions/browser/requirements_checker.cc
@@ -30,11 +30,6 @@
const RequirementsInfo& requirements =
RequirementsInfo::GetRequirements(extension());
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
- if (requirements.npapi)
- errors_.insert(NPAPI_NOT_SUPPORTED);
-#endif
-
#if !defined(USE_AURA)
if (requirements.window_shape)
errors_.insert(WINDOW_SHAPE_NOT_SUPPORTED);
@@ -55,12 +50,6 @@
base::string16 RequirementsChecker::GetErrorMessage() const {
// Join the error messages into one string.
std::vector<std::string> messages;
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
- if (errors_.count(NPAPI_NOT_SUPPORTED)) {
- messages.push_back(
- l10n_util::GetStringUTF8(IDS_EXTENSION_NPAPI_NOT_SUPPORTED));
- }
-#endif
if (errors_.count(WEBGL_NOT_SUPPORTED)) {
messages.push_back(
l10n_util::GetStringUTF8(IDS_EXTENSION_WEBGL_NOT_SUPPORTED));
diff --git a/extensions/browser/requirements_checker_unittest.cc b/extensions/browser/requirements_checker_unittest.cc
index c2754322..3bd077f 100644
--- a/extensions/browser/requirements_checker_unittest.cc
+++ b/extensions/browser/requirements_checker_unittest.cc
@@ -36,14 +36,6 @@
false;
#endif
-// Whether this build supports the plugins.npapi requirement.
-const bool kSupportsNPAPI =
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
- false;
-#else
- true;
-#endif
-
// Returns true if a WebGL check might not fail immediately.
bool MightSupportWebGL() {
return content::GpuDataManager::GetInstance()->GpuAccessAllowed(nullptr);
@@ -87,10 +79,6 @@
manifest_dict_->SetBoolean("requirements.window.shape", true);
}
- void RequireNPAPI() {
- manifest_dict_->SetBoolean("requirements.plugins.npapi", true);
- }
-
void RequireFeature(const char feature[]) {
if (!manifest_dict_->HasKey(kFeaturesKey))
manifest_dict_->Set(kFeaturesKey, std::make_unique<base::ListValue>());
@@ -120,8 +108,7 @@
TEST_F(RequirementsCheckerTest, RequirementsSuccess) {
if (kSupportsWindowShape)
RequireWindowShape();
- if (kSupportsNPAPI)
- RequireNPAPI();
+
RequireFeature(kFeatureCSS3d);
CreateExtension();
@@ -138,10 +125,6 @@
RequireWindowShape();
expected_errors++;
}
- if (!kSupportsNPAPI) {
- RequireNPAPI();
- expected_errors++;
- }
if (!MightSupportWebGL()) {
RequireFeature(kFeatureWebGL);
expected_errors++;
diff --git a/extensions/common/common_manifest_handlers.cc b/extensions/common/common_manifest_handlers.cc
index 7abe61f..8c48684 100644
--- a/extensions/common/common_manifest_handlers.cc
+++ b/extensions/common/common_manifest_handlers.cc
@@ -64,7 +64,7 @@
(new OAuth2ManifestHandler)->Register();
(new OfflineEnabledHandler)->Register();
(new PluginsHandler)->Register();
- (new RequirementsHandler)->Register(); // Depends on plugins.
+ (new RequirementsHandler)->Register();
(new SandboxedPageHandler)->Register();
(new SharedModuleHandler)->Register();
(new SocketsManifestHandler)->Register();
diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc
index 5219c7b..add3746 100644
--- a/extensions/common/manifest_constants.cc
+++ b/extensions/common/manifest_constants.cc
@@ -739,6 +739,7 @@
"An extension cannot override more than one page.";
const char kNoWildCardsInPaths[] =
"Wildcards are not allowed in extent URL pattern paths.";
+const char kNPAPIPluginsNotSupported[] = "NPAPI plugins are not supported.";
const char kOneUISurfaceOnly[] =
"Only one of 'browser_action', 'page_action', and 'app' can be specified.";
const char kPermissionMustBeOptional[] =
@@ -749,6 +750,8 @@
"Permission '*' cannot be specified in the manifest.";
const char kPermissionUnknownOrMalformed[] =
"Permission '*' is unknown or URL pattern is malformed.";
+const char kPluginsRequirementDeprecated[] =
+ "The \"plugins\" requirement is deprecated.";
const char kReservedMessageFound[] =
"Reserved key * found in message catalog.";
const char kRulesFileIsInvalid[] =
diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h
index bc43887a..cc6c6eb 100644
--- a/extensions/common/manifest_constants.h
+++ b/extensions/common/manifest_constants.h
@@ -495,11 +495,13 @@
extern const char kMissingFile[];
extern const char kMultipleOverrides[];
extern const char kNoWildCardsInPaths[];
+extern const char kNPAPIPluginsNotSupported[];
extern const char kOneUISurfaceOnly[];
extern const char kPermissionMustBeOptional[];
extern const char kPermissionNotAllowed[];
extern const char kPermissionNotAllowedInManifest[];
extern const char kPermissionUnknownOrMalformed[];
+extern const char kPluginsRequirementDeprecated[];
extern const char kReservedMessageFound[];
extern const char kRulesFileIsInvalid[];
extern const char kUnrecognizedManifestKey[];
diff --git a/extensions/common/manifest_handlers/requirements_info.cc b/extensions/common/manifest_handlers/requirements_info.cc
index 0acbf7b..4b97d17 100644
--- a/extensions/common/manifest_handlers/requirements_info.cc
+++ b/extensions/common/manifest_handlers/requirements_info.cc
@@ -18,15 +18,7 @@
namespace errors = manifest_errors;
RequirementsInfo::RequirementsInfo(const Manifest* manifest)
- : webgl(false),
- npapi(false),
- window_shape(false) {
- // Before parsing requirements from the manifest, automatically default the
- // NPAPI plugin requirement based on whether it includes NPAPI plugins.
- const base::ListValue* list_value = NULL;
- npapi = manifest->GetList(keys::kPlugins, &list_value) &&
- !list_value->empty();
-}
+ : webgl(false), window_shape(false) {}
RequirementsInfo::~RequirementsInfo() {
}
@@ -49,10 +41,6 @@
RequirementsHandler::~RequirementsHandler() {
}
-const std::vector<std::string> RequirementsHandler::PrerequisiteKeys() const {
- return SingleKey(keys::kPlugins);
-}
-
const std::vector<std::string> RequirementsHandler::Keys() const {
return SingleKey(keys::kRequirements);
}
@@ -87,22 +75,17 @@
return false;
}
+ // The plugins requirement is deprecated. Raise an install warning. If the
+ // extension explicitly requires npapi plugins, raise an error.
if (iter.key() == "plugins") {
- for (base::DictionaryValue::Iterator plugin_iter(*requirement_value);
- !plugin_iter.IsAtEnd(); plugin_iter.Advance()) {
- bool plugin_required = false;
- if (!plugin_iter.value().GetAsBoolean(&plugin_required)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidRequirement, iter.key());
- return false;
- }
- if (plugin_iter.key() == "npapi") {
- requirements->npapi = plugin_required;
- } else {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidRequirement, iter.key());
- return false;
- }
+ extension->AddInstallWarning(
+ InstallWarning(errors::kPluginsRequirementDeprecated));
+ bool requires_npapi = false;
+ if (requirement_value->GetBooleanWithoutPathExpansion("npapi",
+ &requires_npapi) &&
+ requires_npapi) {
+ *error = base::ASCIIToUTF16(errors::kNPAPIPluginsNotSupported);
+ return false;
}
} else if (iter.key() == "3D") {
const base::ListValue* features = NULL;
diff --git a/extensions/common/manifest_handlers/requirements_info.h b/extensions/common/manifest_handlers/requirements_info.h
index 64d107cd..2e4173e 100644
--- a/extensions/common/manifest_handlers/requirements_info.h
+++ b/extensions/common/manifest_handlers/requirements_info.h
@@ -21,7 +21,6 @@
~RequirementsInfo() override;
bool webgl;
- bool npapi;
bool window_shape;
static const RequirementsInfo& GetRequirements(const Extension* extension);
@@ -37,8 +36,6 @@
bool AlwaysParseForType(Manifest::Type type) const override;
- const std::vector<std::string> PrerequisiteKeys() const override;
-
private:
const std::vector<std::string> Keys() const override;
diff --git a/extensions/strings/extensions_strings.grd b/extensions/strings/extensions_strings.grd
index 7ec32bab..88c0a3f 100644
--- a/extensions/strings/extensions_strings.grd
+++ b/extensions/strings/extensions_strings.grd
@@ -311,11 +311,6 @@
<message name="IDS_EXTENSION_INSTALL_PROCESS_CRASHED" desc="Error message in case package fails to install because a utility process crashed.">
Could not install package because a utility process crashed. Try restarting Chrome and trying again.
</message>
- <if expr="is_posix and not is_macosx">
- <message name="IDS_EXTENSION_NPAPI_NOT_SUPPORTED" desc="Error message when an extension has a requirement for plugins that the system does not support.">
- NPAPI plugins are not supported.
- </message>
- </if>
<message name="IDS_EXTENSION_PACKAGE_ERROR_CODE" desc="Error message in cases where we fail to install the extension because the crx file is invalid. For example, because the crx header or signature is invalid.">
Package is invalid: '<ph name="ERROR_CODE">$1<ex>error</ex></ph>'.
</message>