Commit c8954af8 authored by Karan Bhatia's avatar Karan Bhatia Committed by Commit Bot

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/795361Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Commit-Queue: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521122}
parent 871e1bd9
......@@ -28,6 +28,10 @@ as demonstrated in the following example:
}
</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.
......
......@@ -33,15 +33,6 @@ TEST_F(RequirementsManifestTest, RequirementsInvalid) {
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 @@ TEST_F(RequirementsManifestTest, RequirementsValid) {
"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);
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);
// 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.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
......@@ -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>" ]
}
{
"name": "Requirements Manifest Test",
"version": "1.0",
"manifest_version": 2,
"requirements": {
"plugins": false
}
}
{
"name": "Requirements Manifest Test",
"version": "1.0",
"manifest_version": 2,
"requirements": {
"plugins": {
"foo": false
}
}
}
{
"name": "Requirements Manifest Test",
"version": "1.0",
"manifest_version": 2,
"plugins": [
{"path": "foo.dll", "public": true}
]
}
{
"name": "Requirements Manifest Test",
"version": "1.0",
"manifest_version": 2,
"plugins": [
]
}
......@@ -5,9 +5,6 @@
"requirements": {
"3D": {
"features": ["css3d", "webgl"]
},
"plugins": {
"npapi": true
}
}
}
......@@ -27,7 +27,6 @@ class PreloadCheck {
BLACKLISTED_ID,
BLACKLISTED_UNKNOWN,
DISALLOWED_BY_POLICY,
NPAPI_NOT_SUPPORTED,
WEBGL_NOT_SUPPORTED,
WINDOW_SHAPE_NOT_SUPPORTED,
};
......
......@@ -30,11 +30,6 @@ void RequirementsChecker::Start(ResultCallback callback) {
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 @@ void RequirementsChecker::Start(ResultCallback callback) {
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));
......
......@@ -36,14 +36,6 @@ const bool kSupportsWindowShape =
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 @@ class RequirementsCheckerTest : public ExtensionsTest {
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, RequirementsEmpty) {
TEST_F(RequirementsCheckerTest, RequirementsSuccess) {
if (kSupportsWindowShape)
RequireWindowShape();
if (kSupportsNPAPI)
RequireNPAPI();
RequireFeature(kFeatureCSS3d);
CreateExtension();
......@@ -138,10 +125,6 @@ TEST_F(RequirementsCheckerTest, RequirementsFailMultiple) {
RequireWindowShape();
expected_errors++;
}
if (!kSupportsNPAPI) {
RequireNPAPI();
expected_errors++;
}
if (!MightSupportWebGL()) {
RequireFeature(kFeatureWebGL);
expected_errors++;
......
......@@ -64,7 +64,7 @@ void RegisterCommonManifestHandlers() {
(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();
......
......@@ -739,6 +739,7 @@ const char kMultipleOverrides[] =
"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 @@ const char kPermissionNotAllowedInManifest[] =
"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[] =
......
......@@ -495,11 +495,13 @@ extern const char kManifestUnreadable[];
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[];
......
......@@ -18,15 +18,7 @@ namespace keys = manifest_keys;
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() {
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 @@ bool RequirementsHandler::Parse(Extension* extension, base::string16* error) {
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;
......
......@@ -21,7 +21,6 @@ struct RequirementsInfo : public Extension::ManifestData {
~RequirementsInfo() override;
bool webgl;
bool npapi;
bool window_shape;
static const RequirementsInfo& GetRequirements(const Extension* extension);
......@@ -37,8 +36,6 @@ class RequirementsHandler : public ManifestHandler {
bool AlwaysParseForType(Manifest::Type type) const override;
const std::vector<std::string> PrerequisiteKeys() const override;
private:
const std::vector<std::string> Keys() const override;
......
......@@ -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>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment