diff options
author | aboxhall@chromium.org <aboxhall@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 05:20:44 +0000 |
---|---|---|
committer | aboxhall@chromium.org <aboxhall@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-06 05:20:44 +0000 |
commit | c7df0e15c762774bfa4dd720defda5ee6598d2cb (patch) | |
tree | a662ed68cc61b7eb7a9e39ca53d15107f8d22fbe | |
parent | c4672c70d2d2f18233d2c87ac08c3398aecfdd8a (diff) | |
download | chromium_src-c7df0e15c762774bfa4dd720defda5ee6598d2cb.zip chromium_src-c7df0e15c762774bfa4dd720defda5ee6598d2cb.tar.gz chromium_src-c7df0e15c762774bfa4dd720defda5ee6598d2cb.tar.bz2 |
Implement manifest parsing for Automation permissions.
Nothing is wired up yet other than checking for automation permission in general, but the parsing all works, so it's just a matter of enforcing these permissions going forward.
BUG=309681
Review URL: https://codereview.chromium.org/261873002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268433 0039d316-1c4b-4281-b951-d872f2087c98
27 files changed, 578 insertions, 15 deletions
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index e9b1dbe..57157b9 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -179,6 +179,8 @@ 'common/extensions/manifest_handlers/app_isolation_info.h', 'common/extensions/manifest_handlers/app_launch_info.cc', 'common/extensions/manifest_handlers/app_launch_info.h', + 'common/extensions/manifest_handlers/automation.h', + 'common/extensions/manifest_handlers/automation.cc', 'common/extensions/manifest_handlers/content_scripts_handler.cc', 'common/extensions/manifest_handlers/content_scripts_handler.h', 'common/extensions/manifest_handlers/mime_types_handler.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index ecff96e..4f78568 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1810,6 +1810,7 @@ 'common/extensions/extension_icon_set_unittest.cc', 'common/extensions/extension_unittest.cc', 'common/extensions/feature_switch_unittest.cc', + 'common/extensions/manifest_handlers/automation_unittest.cc', 'common/extensions/manifest_handlers/content_scripts_manifest_unittest.cc', 'common/extensions/manifest_handlers/exclude_matches_manifest_unittest.cc', 'common/extensions/manifest_handlers/settings_overrides_handler_unittest.cc', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index a1df50b..f072603 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -93,11 +93,11 @@ }, "automationInternal": { "internal": true, - "dependencies": ["permission:automation"], + "dependencies": ["manifest:automation"], "contexts": ["blessed_extension"] }, "automation": { - "dependencies": ["permission:automation"], + "dependencies": ["manifest:automation"], "contexts": ["blessed_extension"] }, "autotestPrivate": { diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json index 39e0155..caeb592 100644 --- a/chrome/common/extensions/api/_manifest_features.json +++ b/chrome/common/extensions/api/_manifest_features.json @@ -29,6 +29,10 @@ "channel": "stable", "extension_types": "all" }, + "automation": { + "channel": "trunk", + "extension_types": ["extension", "legacy_packaged_app"] + }, "bluetooth": { // Note: The "bluetooth" manifest permission is used by the // chrome.bluetooth, chrome.bluetoothSocket and chrome.bluetoothLowEnergy diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 5052702..08396be 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -83,10 +83,6 @@ ] } ], - "automation": { - "channel": "trunk", - "extension_types": ["extension", "legacy_packaged_app", "platform_app"] - }, "autotestPrivate": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"], diff --git a/chrome/common/extensions/api/manifest_types.json b/chrome/common/extensions/api/manifest_types.json index 03f6ab8..94544ec 100644 --- a/chrome/common/extensions/api/manifest_types.json +++ b/chrome/common/extensions/api/manifest_types.json @@ -177,6 +177,34 @@ } } } + }, + { + "id": "automation", + "description": "This API provides programmatic access to the user interface elements of Chrome. This includes everything in the web view, and optionally Chrome's full user interface.", + "choices": [ + { "type": "boolean", + "description": "If true, enables non-interactive access to the automation tree only for the sites for which the extension has a <a href='https://developer.chrome.com/extensions/declare_permissions#host-permissions'>host permission</a> or <a href='https://developer.chrome.com/extensions/declare_permissions#activeTab'>activeTab permission</a>)." }, + { "type": "object", + "properties": { + "desktop": { + "description": "Whether to request permission to the whole ChromeOS desktop. If granted, this gives the extension access to every aspect of the desktop, and every site and app. If this permission is requested, all other permissions are implicitly included and do not need to be requested separately.", + "optional": true, + "type": "boolean" + }, + "matches": { + "description": "A list of URL patterns for which this extension may request an automation tree. If not specified, automation permission will be granted for the sites for which the extension has a <a href='https://developer.chrome.com/extensions/declare_permissions#host-permissions'>host permission</a> or <a href='https://developer.chrome.com/extensions/declare_permissions#activeTab'>activeTab permission</a>).", + "optional": true, + "type": "array", + "items": { "type": "string" } + }, + "interact": { + "description": "Whether the extension is allowed interactive access (true) or read-only access (false; default) to the automation tree.", + "optional": true, + "type": "boolean" + } + } + } + ] } ] } diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc index df546cc..136149e 100644 --- a/chrome/common/extensions/chrome_manifest_handlers.cc +++ b/chrome/common/extensions/chrome_manifest_handlers.cc @@ -26,6 +26,7 @@ #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" +#include "chrome/common/extensions/manifest_handlers/automation.h" #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" #include "chrome/common/extensions/manifest_handlers/mime_types_handler.h" #include "chrome/common/extensions/manifest_handlers/minimum_chrome_version_checker.h" @@ -46,6 +47,7 @@ void RegisterChromeManifestHandlers() { #if defined(ENABLE_EXTENSIONS) (new AppIsolationHandler)->Register(); (new AppLaunchManifestHandler)->Register(); + (new AutomationHandler)->Register(); (new BluetoothManifestHandler)->Register(); (new BrowserActionHandler)->Register(); (new CommandsHandler)->Register(); diff --git a/chrome/common/extensions/manifest_handlers/automation.cc b/chrome/common/extensions/manifest_handlers/automation.cc new file mode 100644 index 0000000..0338cd6 --- /dev/null +++ b/chrome/common/extensions/manifest_handlers/automation.cc @@ -0,0 +1,152 @@ +// Copyright 2014 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. + +#include "chrome/common/extensions/manifest_handlers/automation.h" + +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/common/extensions/api/manifest_types.h" +#include "extensions/common/error_utils.h" +#include "extensions/common/manifest_constants.h" +#include "extensions/common/permissions/api_permission_set.h" +#include "extensions/common/permissions/permissions_data.h" +#include "extensions/common/url_pattern.h" + +namespace extensions { + +namespace automation_errors { +const char kErrorDesktopTrueInteractFalse[] = + "Cannot specify interactive=false if desktop=true is specified; " + "interactive=false will be ignored."; +const char kErrorDesktopTrueMatchesSpecified[] = + "Cannot specify matches for Automation if desktop=true is specified; " + "matches will be ignored."; +const char kErrorInvalidMatch[] = "Invalid match pattern '*': *"; +const char kErrorNoMatchesProvided[] = "No valid match patterns provided."; +} + +namespace errors = manifest_errors; +namespace keys = extensions::manifest_keys; +using api::manifest_types::Automation; + +AutomationHandler::AutomationHandler() { +} + +AutomationHandler::~AutomationHandler() { +} + +bool AutomationHandler::Parse(Extension* extension, base::string16* error) { + const base::Value* automation = NULL; + CHECK(extension->manifest()->Get(keys::kAutomation, &automation)); + std::vector<InstallWarning> install_warnings; + scoped_ptr<AutomationInfo> info = + AutomationInfo::FromValue(*automation, &install_warnings, error); + if (!error->empty()) + return false; + + extension->AddInstallWarnings(install_warnings); + + if (!info) + return true; + + extension->SetManifestData(keys::kAutomation, info.release()); + return true; +} + +const std::vector<std::string> AutomationHandler::Keys() const { + return SingleKey(keys::kAutomation); +} + +// static +const AutomationInfo* AutomationInfo::Get(const Extension* extension) { + return static_cast<AutomationInfo*>( + extension->GetManifestData(keys::kAutomation)); +} + +// static +scoped_ptr<AutomationInfo> AutomationInfo::FromValue( + const base::Value& value, + std::vector<InstallWarning>* install_warnings, + base::string16* error) { + scoped_ptr<Automation> automation = Automation::FromValue(value, error); + if (!automation) + return scoped_ptr<AutomationInfo>(); + + if (automation->as_boolean) { + if (*automation->as_boolean) + return make_scoped_ptr(new AutomationInfo()); + return scoped_ptr<AutomationInfo>(); + } + const Automation::Object& automation_object = *automation->as_object; + + bool desktop = false; + bool interact = false; + if (automation_object.desktop && *automation_object.desktop) { + desktop = true; + interact = true; + if (automation_object.interact && !*automation_object.interact) { + // TODO(aboxhall): Do we want to allow this? + install_warnings->push_back( + InstallWarning(automation_errors::kErrorDesktopTrueInteractFalse)); + } + } else if (automation_object.interact && *automation_object.interact) { + interact = true; + } + + URLPatternSet matches; + bool specified_matches = false; + if (automation_object.matches) { + if (desktop) { + install_warnings->push_back( + InstallWarning(automation_errors::kErrorDesktopTrueMatchesSpecified)); + } else { + specified_matches = true; + for (std::vector<std::string>::iterator it = + automation_object.matches->begin(); + it != automation_object.matches->end(); + ++it) { + // TODO(aboxhall): Refactor common logic from content_scripts_handler, + // manifest_url_handler and user_script.cc into a single location and + // re-use here. + URLPattern pattern(URLPattern::SCHEME_ALL & + ~URLPattern::SCHEME_CHROMEUI); + URLPattern::ParseResult parse_result = pattern.Parse(*it); + if (parse_result != URLPattern::PARSE_SUCCESS) { + install_warnings->push_back( + InstallWarning(ErrorUtils::FormatErrorMessage( + automation_errors::kErrorInvalidMatch, + *it, + URLPattern::GetParseResultString(parse_result)))); + continue; + } + + matches.AddPattern(pattern); + } + } + } + if (specified_matches && matches.is_empty()) + install_warnings->push_back( + InstallWarning(automation_errors::kErrorNoMatchesProvided)); + + return make_scoped_ptr( + new AutomationInfo(desktop, matches, interact, specified_matches)); +} + +AutomationInfo::AutomationInfo() + : desktop(false), interact(false), specified_matches(false) { +} +AutomationInfo::AutomationInfo(bool desktop, + const URLPatternSet& matches, + bool interact, + bool specified_matches) + : desktop(desktop), + matches(matches), + interact(interact), + specified_matches(specified_matches) { +} + +AutomationInfo::~AutomationInfo() { +} + +} // namespace extensions diff --git a/chrome/common/extensions/manifest_handlers/automation.h b/chrome/common/extensions/manifest_handlers/automation.h new file mode 100644 index 0000000..3890d59 --- /dev/null +++ b/chrome/common/extensions/manifest_handlers/automation.h @@ -0,0 +1,80 @@ +// Copyright 2014 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. + +#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_ +#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest_handler.h" +#include "extensions/common/url_pattern_set.h" +#include "extensions/common/user_script.h" + +namespace extensions { + +class URLPatternSet; + +namespace automation_errors { +extern const char kErrorInvalidMatchPattern[]; +extern const char kErrorDesktopTrueInteractFalse[]; +extern const char kErrorDesktopTrueMatchesSpecified[]; +extern const char kErrorURLMalformed[]; +extern const char kErrorInvalidMatch[]; +extern const char kErrorNoMatchesProvided[]; +} + +// Parses the automation manifest entry. +class AutomationHandler : public ManifestHandler { + public: + AutomationHandler(); + virtual ~AutomationHandler(); + + virtual bool Parse(Extension* extensions, base::string16* error) OVERRIDE; + + private: + virtual const std::vector<std::string> Keys() const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(AutomationHandler); +}; + +// The parsed form of the automation manifest entry. +struct AutomationInfo : public Extension::ManifestData { + public: + static const AutomationInfo* Get(const Extension* extension); + static scoped_ptr<AutomationInfo> FromValue( + const base::Value& value, + std::vector<InstallWarning>* install_warnings, + base::string16* error); + + virtual ~AutomationInfo(); + + // true if the extension has requested 'desktop' permission. + const bool desktop; + + // Returns the list of hosts that this extension can request an automation + // tree from. + const URLPatternSet matches; + + // Whether the extension is allowed interactive access (true) or read-only + // access (false) to the automation tree. + const bool interact; + + // Whether any matches were specified (false if automation was specified as a + // boolean, or no matches key was provided. + const bool specified_matches; + + private: + AutomationInfo(); + AutomationInfo(bool desktop, + const URLPatternSet& matches, + bool interact, + bool specified_matches); + DISALLOW_COPY_AND_ASSIGN(AutomationInfo); +}; + +} // namespace extensions + +#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_AUTOMATION_H_ diff --git a/chrome/common/extensions/manifest_handlers/automation_unittest.cc b/chrome/common/extensions/manifest_handlers/automation_unittest.cc new file mode 100644 index 0000000..7a3062d0 --- /dev/null +++ b/chrome/common/extensions/manifest_handlers/automation_unittest.cc @@ -0,0 +1,204 @@ +// Copyright 2014 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. + +#include "base/strings/utf_string_conversions.h" +#include "chrome/common/extensions/manifest_handlers/automation.h" +#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h" +#include "extensions/common/error_utils.h" +#include "extensions/common/manifest_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { + +class AutomationManifestTest : public ExtensionManifestTest { + public: + AutomationManifestTest() : channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {} + + protected: + AutomationInfo* GetAutomationInfo(scoped_refptr<Extension> extension) { + return static_cast<AutomationInfo*>( + extension->GetManifestData(manifest_keys::kAutomation)); + } + + private: + ScopedCurrentChannel channel_; +}; + +TEST_F(AutomationManifestTest, AsBooleanFalse) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_boolean_false.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_FALSE(info); +} + +TEST_F(AutomationManifestTest, AsBooleanTrue) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_boolean_true.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_FALSE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, InteractTrue) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_interact_true.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_TRUE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, Matches) { + scoped_refptr<Extension> extension = LoadAndExpectWarning( + "automation_matches.json", + ErrorUtils::FormatErrorMessage( + automation_errors::kErrorInvalidMatch, + "www.badpattern.com", + URLPattern::GetParseResultString( + URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR))); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_FALSE(info->interact); + EXPECT_TRUE(info->specified_matches); + EXPECT_FALSE(info->matches.is_empty()); + + EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com/"))); + EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.google.com"))); + EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com/"))); + EXPECT_TRUE(info->matches.MatchesURL(GURL("http://www.twitter.com"))); + + EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com/"))); + EXPECT_FALSE(info->matches.MatchesURL(GURL("http://www.bing.com"))); +} + +TEST_F(AutomationManifestTest, EmptyMatches) { + scoped_refptr<Extension> extension = + LoadAndExpectWarning("automation_empty_matches.json", + automation_errors::kErrorNoMatchesProvided); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_FALSE(info->interact); + EXPECT_TRUE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, NoValidMatches) { + std::string error; + scoped_refptr<Extension> extension = + LoadExtension(Manifest("automation_no_valid_matches.json"), &error); + ASSERT_TRUE(extension.get()); + EXPECT_EQ("", error); + EXPECT_EQ(2u, extension->install_warnings().size()); + EXPECT_EQ(ErrorUtils::FormatErrorMessage( + automation_errors::kErrorInvalidMatch, + "www.badpattern.com", + URLPattern::GetParseResultString( + URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR)), + extension->install_warnings()[0].message); + EXPECT_EQ(automation_errors::kErrorNoMatchesProvided, + extension->install_warnings()[1].message); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_FALSE(info->interact); + EXPECT_TRUE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, DesktopFalse) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_desktop_false.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_FALSE(info->desktop); + EXPECT_FALSE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, DesktopTrue) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_desktop_true.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_TRUE(info->desktop); + EXPECT_TRUE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, Desktop_InteractTrue) { + scoped_refptr<Extension> extension = + LoadAndExpectSuccess("automation_desktop_interact_true.json"); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_TRUE(info->desktop); + EXPECT_TRUE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, Desktop_InteractFalse) { + scoped_refptr<Extension> extension = + LoadAndExpectWarning("automation_desktop_interact_false.json", + automation_errors::kErrorDesktopTrueInteractFalse); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_TRUE(info->desktop); + EXPECT_TRUE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +TEST_F(AutomationManifestTest, Desktop_MatchesSpecified) { + scoped_refptr<Extension> extension = LoadAndExpectWarning( + "automation_desktop_matches_specified.json", + automation_errors::kErrorDesktopTrueMatchesSpecified); + ASSERT_TRUE(extension.get()); + + const AutomationInfo* info = AutomationInfo::Get(extension.get()); + ASSERT_TRUE(info); + + EXPECT_TRUE(info->desktop); + EXPECT_TRUE(info->interact); + EXPECT_FALSE(info->specified_matches); + EXPECT_TRUE(info->matches.is_empty()); +} + +} // namespace extensions diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 0c948ed..aa9eaab 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc @@ -96,10 +96,6 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() {APIPermission::kActiveTab, "activeTab"}, {APIPermission::kAdView, "adview"}, {APIPermission::kAlarms, "alarms"}, - {APIPermission::kAutomation, "automation", - APIPermissionInfo::kFlagCannotBeOptional, - IDS_EXTENSION_PROMPT_WARNING_AUTOMATION, - PermissionMessage::kAutomation}, {APIPermission::kBookmark, "bookmarks", APIPermissionInfo::kFlagNone, IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS, PermissionMessage::kBookmarks}, {APIPermission::kBrailleDisplayPrivate, "brailleDisplayPrivate", diff --git a/chrome/test/data/extensions/api_test/automation/basic/manifest.json b/chrome/test/data/extensions/api_test/automation/basic/manifest.json index cc9ae5c..c741f86 100644 --- a/chrome/test/data/extensions/api_test/automation/basic/manifest.json +++ b/chrome/test/data/extensions/api_test/automation/basic/manifest.json @@ -6,5 +6,6 @@ "background": { "scripts": [ "background.js" ] }, - "permissions": ["automation", "tabs", "http://a.com/"] + "permissions": ["tabs", "http://a.com/"], + "automation": true } diff --git a/chrome/test/data/extensions/api_test/automation/tests/manifest.json b/chrome/test/data/extensions/api_test/automation/tests/manifest.json index f6e4536..41ece7e 100644 --- a/chrome/test/data/extensions/api_test/automation/tests/manifest.json +++ b/chrome/test/data/extensions/api_test/automation/tests/manifest.json @@ -10,6 +10,6 @@ "run_at": "document_end" } ], - - "permissions": ["automation", "tabs", "http://a.com/"] + "permissions": ["tabs", "http://a.com/"], + "automation": true } diff --git a/chrome/test/data/extensions/manifest_tests/automation_boolean_false.json b/chrome/test/data/extensions/manifest_tests/automation_boolean_false.json new file mode 100644 index 0000000..4cbeb7c --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_boolean_false.json @@ -0,0 +1,9 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.AsBooleanFalse", + "version": "1", + "manifest_version": 2, + "permissions": [ + "http://www.google.com" + ], + "automation": false +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_boolean_true.json b/chrome/test/data/extensions/manifest_tests/automation_boolean_true.json new file mode 100644 index 0000000..3885688 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_boolean_true.json @@ -0,0 +1,6 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.AsBooleanTrue", + "version": "1", + "manifest_version": 2, + "automation": true +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_desktop_false.json b/chrome/test/data/extensions/manifest_tests/automation_desktop_false.json new file mode 100644 index 0000000..d17eeb1 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_desktop_false.json @@ -0,0 +1,8 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.DesktopFalse", + "version": "1", + "manifest_version": 2, + "automation": { + "desktop": false + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_false.json b/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_false.json new file mode 100644 index 0000000..1297307 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_false.json @@ -0,0 +1,9 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.Desktop_InteractFalse", + "version": "1", + "manifest_version": 2, + "automation": { + "desktop": true, + "interact": false + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_true.json b/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_true.json new file mode 100644 index 0000000..abb9ee9 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_desktop_interact_true.json @@ -0,0 +1,9 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.Desktop_InteractTrue", + "version": "1", + "manifest_version": 2, + "automation": { + "desktop": true, + "interact": true + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_desktop_matches_specified.json b/chrome/test/data/extensions/manifest_tests/automation_desktop_matches_specified.json new file mode 100644 index 0000000..87c5cd0 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_desktop_matches_specified.json @@ -0,0 +1,11 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.Desktop_MatchesSpecified", + "version": "1", + "manifest_version": 2, + "automation": { + "desktop": true, + "matches": [ + "http://www.google.com" + ] + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_desktop_true.json b/chrome/test/data/extensions/manifest_tests/automation_desktop_true.json new file mode 100644 index 0000000..36ad19c --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_desktop_true.json @@ -0,0 +1,8 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.DesktopTrue", + "version": "1", + "manifest_version": 2, + "automation": { + "desktop": true + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_empty_matches.json b/chrome/test/data/extensions/manifest_tests/automation_empty_matches.json new file mode 100644 index 0000000..f0a24d4 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_empty_matches.json @@ -0,0 +1,8 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.EmptyMatches", + "version": "1", + "manifest_version": 2, + "automation": { + "matches": [] + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_interact_true.json b/chrome/test/data/extensions/manifest_tests/automation_interact_true.json new file mode 100644 index 0000000..49f2324 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_interact_true.json @@ -0,0 +1,8 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.InteractTrue", + "version": "1", + "manifest_version": 2, + "automation": { + "interact": true + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_matches.json b/chrome/test/data/extensions/manifest_tests/automation_matches.json new file mode 100644 index 0000000..e2e91a0 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_matches.json @@ -0,0 +1,10 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.Matches", + "version": "1", + "manifest_version": 2, + "automation": { + "matches": [ "http://www.google.com/", + "http://www.twitter.com/", + "www.badpattern.com" ] + } +} diff --git a/chrome/test/data/extensions/manifest_tests/automation_no_valid_matches.json b/chrome/test/data/extensions/manifest_tests/automation_no_valid_matches.json new file mode 100644 index 0000000..1d1eaa3 --- /dev/null +++ b/chrome/test/data/extensions/manifest_tests/automation_no_valid_matches.json @@ -0,0 +1,8 @@ +{ + "name": "unit_tests --gtest_filter=AutomationManifestTest.NoValidMatches", + "version": "1", + "manifest_version": 2, + "automation": { + "matches": [ "www.badpattern.com" ] + } +} diff --git a/extensions/common/manifest_constants.cc b/extensions/common/manifest_constants.cc index 03129a3..cc574d9 100644 --- a/extensions/common/manifest_constants.cc +++ b/extensions/common/manifest_constants.cc @@ -11,6 +11,7 @@ namespace manifest_keys { const char kAllFrames[] = "all_frames"; const char kAltKey[] = "altKey"; const char kApp[] = "app"; +const char kAutomation[] = "automation"; const char kBackgroundAllowJsAccess[] = "background.allow_js_access"; const char kBackgroundPage[] = "background.page"; const char kBackgroundPageLegacy[] = "background_page"; diff --git a/extensions/common/manifest_constants.h b/extensions/common/manifest_constants.h index 15bff25..4579852 100644 --- a/extensions/common/manifest_constants.h +++ b/extensions/common/manifest_constants.h @@ -13,6 +13,7 @@ namespace manifest_keys { extern const char kAllFrames[]; extern const char kAltKey[]; extern const char kApp[]; +extern const char kAutomation[]; extern const char kBackgroundAllowJsAccess[]; extern const char kBackgroundPage[]; extern const char kBackgroundPageLegacy[]; diff --git a/extensions/common/manifest_handlers/externally_connectable.cc b/extensions/common/manifest_handlers/externally_connectable.cc index 1261ad8..859e520 100644 --- a/extensions/common/manifest_handlers/externally_connectable.cc +++ b/extensions/common/manifest_handlers/externally_connectable.cc @@ -64,8 +64,9 @@ bool ExternallyConnectableHandler::Parse(Extension* extension, &externally_connectable)); std::vector<InstallWarning> install_warnings; scoped_ptr<ExternallyConnectableInfo> info = - ExternallyConnectableInfo::FromValue( - *externally_connectable, &install_warnings, error); + ExternallyConnectableInfo::FromValue(*externally_connectable, + &install_warnings, + error); if (!info) return false; if (!info->matches.is_empty()) { |