diff options
author | jstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 16:57:39 +0000 |
---|---|---|
committer | jstritar@chromium.org <jstritar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-06 16:57:39 +0000 |
commit | c333e797acdfd81708832d0d7fe3f93d439f55cc (patch) | |
tree | 010d0c21664fef2ff32493a1dffbba40ddf6bcad | |
parent | 1c9ac92646f4ab04e244a550974243aa512e40e6 (diff) | |
download | chromium_src-c333e797acdfd81708832d0d7fe3f93d439f55cc.zip chromium_src-c333e797acdfd81708832d0d7fe3f93d439f55cc.tar.gz chromium_src-c333e797acdfd81708832d0d7fe3f93d439f55cc.tar.bz2 |
Cleanup extension permissions module.
- renames ExtensionPermissionsManager to extensions::PermissionsUpdater
- PermissionsUpdaters are now created on demand (vs one per ExtensionService)
- move some includes into the *.cc files
- moves a couple common methods to extension_permissions_api_helpers.cc
BUG=none
TEST=existing
Review URL: http://codereview.chromium.org/8493017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116673 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 833 insertions, 335 deletions
diff --git a/chrome/browser/automation/automation_util.cc b/chrome/browser/automation/automation_util.cc index 45fc0bb..f913818 100644 --- a/chrome/browser/automation/automation_util.cc +++ b/chrome/browser/automation/automation_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -30,6 +30,7 @@ #include "chrome/common/extensions/extension.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "net/base/cookie_monster.h" #include "net/base/cookie_store.h" diff --git a/chrome/browser/background/background_application_list_model_unittest.cc b/chrome/browser/background/background_application_list_model_unittest.cc index 4024fad..47992ef 100644 --- a/chrome/browser/background/background_application_list_model_unittest.cc +++ b/chrome/browser/background/background_application_list_model_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -17,6 +17,7 @@ #include "base/stl_util.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_unittest.h" +#include "chrome/browser/extensions/permissions_updater.h" #include "chrome/common/extensions/extension.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/notification_registrar.h" @@ -88,14 +89,14 @@ void AddBackgroundPermission(ExtensionService* service, CreateExtension(GenerateUniqueExtensionName(), true); scoped_refptr<const ExtensionPermissionSet> permissions = temporary->GetActivePermissions(); - ExtensionPermissionsManager(service).AddPermissions( + extensions::PermissionsUpdater(service->profile()).AddPermissions( extension, permissions.get()); } void RemoveBackgroundPermission(ExtensionService* service, Extension* extension) { if (!BackgroundApplicationListModel::IsBackgroundApp(*extension)) return; - ExtensionPermissionsManager(service).RemovePermissions( + extensions::PermissionsUpdater(service->profile()).RemovePermissions( extension, extension->GetActivePermissions()); } } // namespace @@ -268,10 +269,10 @@ void RemoveExtension(ExtensionService* service, } void TogglePermission(ExtensionService* service, - ExtensionCollection* extensions, - BackgroundApplicationListModel* model, - size_t* expected, - size_t* count) { + ExtensionCollection* extensions, + BackgroundApplicationListModel* model, + size_t* expected, + size_t* count) { ExtensionCollection::iterator cursor = extensions->begin(); if (cursor == extensions->end()) { // Nothing to toggle. Just verify accounting. diff --git a/chrome/browser/debugger/devtools_window.cc b/chrome/browser/debugger/devtools_window.cc index c87473b..c775d95 100644 --- a/chrome/browser/debugger/devtools_window.cc +++ b/chrome/browser/debugger/devtools_window.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -43,6 +43,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_source.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/bindings_policy.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index 3eff442..695aeaf 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -28,6 +28,7 @@ #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/user_script.h" #include "chrome/common/pref_names.h" diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index c1de458..39ff6dd 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -20,6 +20,7 @@ #include "content/browser/renderer_host/render_view_host.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" #include "content/test/test_navigation_observer.h" #include "net/base/mock_host_resolver.h" diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 5e8dee0..f904df07 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -26,6 +26,7 @@ #include "chrome/browser/extensions/default_apps_trial.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/permissions_updater.h" #include "chrome/browser/shell_integration.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_notification_types.h" @@ -44,6 +45,7 @@ using content::BrowserThread; using content::UserMetricsAction; +using extensions::PermissionsUpdater; namespace { @@ -582,8 +584,10 @@ void CrxInstaller::ReportSuccessFromUIThread() { // the install (client_ is non NULL), or we are allowed to install this // silently. We only track granted permissions for INTERNAL extensions. if ((client_ || allow_silent_install_) && - extension_->location() == Extension::INTERNAL) - frontend_weak_->GrantPermissions(extension_); + extension_->location() == Extension::INTERNAL) { + PermissionsUpdater perms_updater(profile()); + perms_updater.GrantActivePermissions(extension_); + } // Tell the frontend about the installation and hand off ownership of // extension_ to it. diff --git a/chrome/browser/extensions/extension_event_router.cc b/chrome/browser/extensions/extension_event_router.cc index 54336ee..d2f1179 100644 --- a/chrome/browser/extensions/extension_event_router.cc +++ b/chrome/browser/extensions/extension_event_router.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -17,6 +17,7 @@ #include "chrome/browser/extensions/extension_webrequest_api.h" #include "chrome/browser/extensions/process_map.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_messages.h" diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 5bb780a..6d41e2a 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -70,6 +70,7 @@ #include "chrome/common/extensions/extension_set.h" #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/public/browser/render_process_host.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "third_party/skia/include/core/SkBitmap.h" diff --git a/chrome/browser/extensions/extension_navigation_observer.cc b/chrome/browser/extensions/extension_navigation_observer.cc index 3b0559d..d827f80 100644 --- a/chrome/browser/extensions/extension_navigation_observer.cc +++ b/chrome/browser/extensions/extension_navigation_observer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -9,6 +9,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" using content::NavigationController; using content::NavigationEntry; diff --git a/chrome/browser/extensions/extension_permissions_api.cc b/chrome/browser/extensions/extension_permissions_api.cc index 0f21f88..fe92710 100644 --- a/chrome/browser/extensions/extension_permissions_api.cc +++ b/chrome/browser/extensions/extension_permissions_api.cc @@ -1,28 +1,26 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/browser/extensions/extension_permissions_api.h" -#include "base/json/json_writer.h" +#include "base/memory/scoped_ptr.h" #include "base/values.h" -#include "chrome/browser/extensions/extension_event_router.h" -#include "chrome/browser/extensions/extension_prefs.h" +#include "chrome/browser/extensions/extension_permissions_api_helpers.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/permissions_updater.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_error_utils.h" -#include "chrome/common/extensions/extension_messages.h" -#include "chrome/common/extensions/extension_permission_set.h" #include "chrome/common/extensions/url_pattern_set.h" -#include "content/public/browser/notification_service.h" #include "googleurl/src/gurl.h" -namespace { +using extensions::PermissionsUpdater; +using extensions::permissions_api::PackPermissionsToValue; +using extensions::permissions_api::UnpackPermissionsFromValue; -const char kApisKey[] = "permissions"; -const char kOriginsKey[] = "origins"; +namespace { const char kCantRemoveRequiredPermissionsError[] = "You cannot remove required permissions."; @@ -30,15 +28,8 @@ const char kNotInOptionalPermissionsError[] = "Optional permissions must be listed in extension manifest."; const char kNotWhitelistedError[] = "The optional permissions API does not support '*'."; -const char kUnknownPermissionError[] = - "'*' is not a recognized permission."; const char kUserGestureRequiredError[] = "This function must be called during a user gesture"; -const char kInvalidOrigin[] = - "Invalid value for origin pattern *: *"; - -const char kOnAdded[] = "permissions.onAdded"; -const char kOnRemoved[] = "permissions.onRemoved"; enum AutoConfirmForTest { DO_NOT_SKIP = 0, @@ -48,193 +39,8 @@ enum AutoConfirmForTest { AutoConfirmForTest auto_confirm_for_tests = DO_NOT_SKIP; bool ignore_user_gesture_for_tests = false; -DictionaryValue* PackPermissionsToValue(const ExtensionPermissionSet* set) { - DictionaryValue* value = new DictionaryValue(); - - // Generate the list of API permissions. - ListValue* apis = new ListValue(); - ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); - for (ExtensionAPIPermissionSet::const_iterator i = set->apis().begin(); - i != set->apis().end(); ++i) - apis->Append(Value::CreateStringValue(info->GetByID(*i)->name())); - - // Generate the list of origin permissions. - URLPatternSet hosts = set->explicit_hosts(); - ListValue* origins = new ListValue(); - for (URLPatternSet::const_iterator i = hosts.begin(); i != hosts.end(); ++i) - origins->Append(Value::CreateStringValue(i->GetAsString())); - - value->Set(kApisKey, apis); - value->Set(kOriginsKey, origins); - return value; -} - -// Creates a new ExtensionPermissionSet from its |value| and passes ownership to -// the caller through |ptr|. Sets |bad_message| to true if the message is badly -// formed. Returns false if the method fails to unpack a permission set. -bool UnpackPermissionsFromValue(DictionaryValue* value, - scoped_refptr<ExtensionPermissionSet>* ptr, - bool* bad_message, - std::string* error) { - ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); - ExtensionAPIPermissionSet apis; - if (value->HasKey(kApisKey)) { - ListValue* api_list = NULL; - if (!value->GetList(kApisKey, &api_list)) { - *bad_message = true; - return false; - } - for (size_t i = 0; i < api_list->GetSize(); ++i) { - std::string api_name; - if (!api_list->GetString(i, &api_name)) { - *bad_message = true; - return false; - } - - ExtensionAPIPermission* permission = info->GetByName(api_name); - if (!permission) { - *error = ExtensionErrorUtils::FormatErrorMessage( - kUnknownPermissionError, api_name); - return false; - } - apis.insert(permission->id()); - } - } - - URLPatternSet origins; - if (value->HasKey(kOriginsKey)) { - ListValue* origin_list = NULL; - if (!value->GetList(kOriginsKey, &origin_list)) { - *bad_message = true; - return false; - } - for (size_t i = 0; i < origin_list->GetSize(); ++i) { - std::string pattern; - if (!origin_list->GetString(i, &pattern)) { - *bad_message = true; - return false; - } - - URLPattern origin(Extension::kValidHostPermissionSchemes); - URLPattern::ParseResult parse_result = origin.Parse(pattern); - if (URLPattern::PARSE_SUCCESS != parse_result) { - *error = ExtensionErrorUtils::FormatErrorMessage( - kInvalidOrigin, - pattern, - URLPattern::GetParseResultString(parse_result)); - return false; - } - origins.AddPattern(origin); - } - } - - *ptr = new ExtensionPermissionSet(apis, origins, URLPatternSet()); - return true; -} - } // namespace -ExtensionPermissionsManager::ExtensionPermissionsManager( - ExtensionService* extension_service) - : extension_service_(extension_service) {} - -ExtensionPermissionsManager::~ExtensionPermissionsManager() {} - -void ExtensionPermissionsManager::AddPermissions( - const Extension* extension, const ExtensionPermissionSet* permissions) { - scoped_refptr<const ExtensionPermissionSet> existing( - extension->GetActivePermissions()); - scoped_refptr<ExtensionPermissionSet> total( - ExtensionPermissionSet::CreateUnion(existing, permissions)); - scoped_refptr<ExtensionPermissionSet> added( - ExtensionPermissionSet::CreateDifference(total.get(), existing)); - - extension_service_->UpdateActivePermissions(extension, total.get()); - - // Update the granted permissions so we don't auto-disable the extension. - extension_service_->GrantPermissions(extension); - - NotifyPermissionsUpdated(ADDED, extension, added.get()); -} - -void ExtensionPermissionsManager::RemovePermissions( - const Extension* extension, const ExtensionPermissionSet* permissions) { - scoped_refptr<const ExtensionPermissionSet> existing( - extension->GetActivePermissions()); - scoped_refptr<ExtensionPermissionSet> total( - ExtensionPermissionSet::CreateDifference(existing, permissions)); - scoped_refptr<ExtensionPermissionSet> removed( - ExtensionPermissionSet::CreateDifference(existing, total.get())); - - // We update the active permissions, and not the granted permissions, because - // the extension, not the user, removed the permissions. This allows the - // extension to add them again without prompting the user. - extension_service_->UpdateActivePermissions(extension, total.get()); - - NotifyPermissionsUpdated(REMOVED, extension, removed.get()); -} - -void ExtensionPermissionsManager::DispatchEvent( - const std::string& extension_id, - const char* event_name, - const ExtensionPermissionSet* changed_permissions) { - Profile* profile = extension_service_->profile(); - if (profile && profile->GetExtensionEventRouter()) { - ListValue value; - value.Append(PackPermissionsToValue(changed_permissions)); - std::string json_value; - base::JSONWriter::Write(&value, false, &json_value); - profile->GetExtensionEventRouter()->DispatchEventToExtension( - extension_id, event_name, json_value, profile, GURL()); - } -} - -void ExtensionPermissionsManager::NotifyPermissionsUpdated( - EventType event_type, - const Extension* extension, - const ExtensionPermissionSet* changed) { - if (!changed || changed->IsEmpty()) - return; - - UpdatedExtensionPermissionsInfo::Reason reason; - const char* event_name = NULL; - - if (event_type == REMOVED) { - reason = UpdatedExtensionPermissionsInfo::REMOVED; - event_name = kOnRemoved; - } else { - CHECK_EQ(ADDED, event_type); - reason = UpdatedExtensionPermissionsInfo::ADDED; - event_name = kOnAdded; - } - - // Notify other APIs or interested parties. - UpdatedExtensionPermissionsInfo info = UpdatedExtensionPermissionsInfo( - extension, changed, reason); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, - content::Source<Profile>(extension_service_->profile()), - content::Details<UpdatedExtensionPermissionsInfo>(&info)); - - // Send the new permissions to the renderers. - for (content::RenderProcessHost::iterator i( - content::RenderProcessHost::AllHostsIterator()); - !i.IsAtEnd(); i.Advance()) { - content::RenderProcessHost* host = i.GetCurrentValue(); - Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); - if (extension_service_->profile()->IsSameProfile(profile)) - host->Send(new ExtensionMsg_UpdatePermissions( - static_cast<int>(reason), - extension->id(), - changed->apis(), - changed->explicit_hosts(), - changed->scriptable_hosts())); - } - - // Trigger the onAdded and onRemoved events in the extension. - DispatchEvent(extension->id(), event_name, changed); -} - bool ContainsPermissionsFunction::RunImpl() { DictionaryValue* args = NULL; EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); @@ -270,8 +76,6 @@ bool RemovePermissionsFunction::RunImpl() { CHECK(permissions.get()); const Extension* extension = GetExtension(); - ExtensionPermissionsManager* perms_manager = - profile()->GetExtensionService()->permissions_manager(); ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); // Make sure they're only trying to remove permissions supported by this API. @@ -296,7 +100,7 @@ bool RemovePermissionsFunction::RunImpl() { return false; } - perms_manager->RemovePermissions(extension, permissions.get()); + PermissionsUpdater(profile()).RemovePermissions(extension, permissions.get()); result_.reset(Value::CreateBooleanValue(true)); return true; } @@ -331,10 +135,7 @@ bool RequestPermissionsFunction::RunImpl() { return false; CHECK(requested_permissions_.get()); - extension_ = GetExtension(); ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); - ExtensionPermissionsManager* perms_manager = - profile()->GetExtensionService()->permissions_manager(); ExtensionPrefs* prefs = profile()->GetExtensionService()->extension_prefs(); // Make sure they're only requesting permissions supported by this API. @@ -350,7 +151,7 @@ bool RequestPermissionsFunction::RunImpl() { } // The requested permissions must be defined as optional in the manifest. - if (!extension_->optional_permission_set()->Contains( + if (!GetExtension()->optional_permission_set()->Contains( *requested_permissions_)) { error_ = kNotInOptionalPermissionsError; result_.reset(Value::CreateBooleanValue(false)); @@ -360,9 +161,10 @@ bool RequestPermissionsFunction::RunImpl() { // We don't need to prompt the user if the requested permissions are a subset // of the granted permissions set. const ExtensionPermissionSet* granted = - prefs->GetGrantedPermissions(extension_->id()); + prefs->GetGrantedPermissions(GetExtension()->id()); if (granted && granted->Contains(*requested_permissions_)) { - perms_manager->AddPermissions(extension_, requested_permissions_.get()); + PermissionsUpdater perms_updater(profile()); + perms_updater.AddPermissions(GetExtension(), requested_permissions_.get()); result_.reset(Value::CreateBooleanValue(true)); SendResponse(true); return true; @@ -372,8 +174,7 @@ bool RequestPermissionsFunction::RunImpl() { requested_permissions_ = ExtensionPermissionSet::CreateDifference( requested_permissions_.get(), granted); - // Balanced with Release() in InstallUIProceed() and InstallUIAbort(). - AddRef(); + AddRef(); // Balanced in InstallUIProceed() / InstallUIAbort(). // We don't need to show the prompt if there are no new warnings, or if // we're skipping the confirmation UI. All extension types but INTERNAL @@ -388,30 +189,25 @@ bool RequestPermissionsFunction::RunImpl() { CHECK_EQ(DO_NOT_SKIP, auto_confirm_for_tests); install_ui_.reset(new ExtensionInstallUI(profile())); install_ui_->ConfirmPermissions( - this, extension_, requested_permissions_.get()); + this, GetExtension(), requested_permissions_.get()); } return true; } void RequestPermissionsFunction::InstallUIProceed() { - ExtensionPermissionsManager* perms_manager = - profile()->GetExtensionService()->permissions_manager(); + PermissionsUpdater perms_updater(profile()); + perms_updater.AddPermissions(GetExtension(), requested_permissions_.get()); - install_ui_.reset(); result_.reset(Value::CreateBooleanValue(true)); - perms_manager->AddPermissions(extension_, requested_permissions_.get()); - SendResponse(true); - Release(); + Release(); // Balanced in RunImpl(). } void RequestPermissionsFunction::InstallUIAbort(bool user_initiated) { - install_ui_.reset(); result_.reset(Value::CreateBooleanValue(false)); - requested_permissions_ = NULL; - SendResponse(true); - Release(); + + Release(); // Balanced in RunImpl(). } diff --git a/chrome/browser/extensions/extension_permissions_api.h b/chrome/browser/extensions/extension_permissions_api.h index 583302e..effa7e9 100644 --- a/chrome/browser/extensions/extension_permissions_api.h +++ b/chrome/browser/extensions/extension_permissions_api.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -12,53 +12,11 @@ #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/common/extensions/extension_permission_set.h" -#include "chrome/common/chrome_notification_types.h" -#include "content/public/browser/render_process_host.h" class Extension; class ExtensionPermissionSet; class ExtensionService; -class ExtensionPermissionsManager { - public: - explicit ExtensionPermissionsManager(ExtensionService* extension_service); - ~ExtensionPermissionsManager(); - - // Adds the set of |permissions| to the |extension|'s active permission set - // and sends the relevant messages and notifications. This method assumes the - // user has already been prompted, if necessary, for the extra permissions. - void AddPermissions(const Extension* extension, - const ExtensionPermissionSet* permissions); - - // Removes the set of |permissions| from the |extension|'s active permission - // set and sends the relevant messages and notifications. - void RemovePermissions(const Extension* extension, - const ExtensionPermissionSet* permissions); - - private: - enum EventType { - ADDED, - REMOVED, - }; - - // Dispatches specified event to the extension. - void DispatchEvent(const std::string& extension_id, - const char* event_name, - const ExtensionPermissionSet* changed_permissions); - - // Issues the relevant events, messages and notifications when the - // |extension|'s permissions have |changed| (|changed| is the delta). - // Specifically, this sends the EXTENSION_PERMISSIONS_UPDATED notification, - // the ExtensionMsg_UpdatePermissions IPC message, and fires the - // onAdded/onRemoved events in the extension. - void NotifyPermissionsUpdated(EventType event_type, - const Extension* extension, - const ExtensionPermissionSet* changed); - - ExtensionService* extension_service_; -}; - - // chrome.permissions.contains class ContainsPermissionsFunction : public SyncExtensionFunction { virtual ~ContainsPermissionsFunction() {} @@ -101,7 +59,6 @@ class RequestPermissionsFunction : public AsyncExtensionFunction, private: scoped_ptr<ExtensionInstallUI> install_ui_; scoped_refptr<ExtensionPermissionSet> requested_permissions_; - const Extension* extension_; DECLARE_EXTENSION_FUNCTION_NAME("permissions.request") }; diff --git a/chrome/browser/extensions/extension_permissions_api_helpers.cc b/chrome/browser/extensions/extension_permissions_api_helpers.cc new file mode 100644 index 0000000..a63909b --- /dev/null +++ b/chrome/browser/extensions/extension_permissions_api_helpers.cc @@ -0,0 +1,113 @@ +// Copyright (c) 2012 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/browser/extensions/extension_permissions_api_helpers.h" + +#include "base/values.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_error_utils.h" +#include "chrome/common/extensions/extension_permission_set.h" +#include "chrome/common/extensions/url_pattern_set.h" + +namespace extensions { +namespace permissions_api { + +namespace { + +const char kInvalidOrigin[] = + "Invalid value for origin pattern *: *"; +const char kUnknownPermissionError[] = + "'*' is not a recognized permission."; + +const char kApisKey[] = "permissions"; +const char kOriginsKey[] = "origins"; + +} // namespace + +DictionaryValue* PackPermissionsToValue(const ExtensionPermissionSet* set) { + DictionaryValue* value = new DictionaryValue(); + + // Generate the list of API permissions. + ListValue* apis = new ListValue(); + ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); + for (ExtensionAPIPermissionSet::const_iterator i = set->apis().begin(); + i != set->apis().end(); ++i) + apis->Append(Value::CreateStringValue(info->GetByID(*i)->name())); + + // Generate the list of origin permissions. + URLPatternSet hosts = set->explicit_hosts(); + ListValue* origins = new ListValue(); + for (URLPatternSet::const_iterator i = hosts.begin(); i != hosts.end(); ++i) + origins->Append(Value::CreateStringValue(i->GetAsString())); + + value->Set(kApisKey, apis); + value->Set(kOriginsKey, origins); + return value; +} + +// Creates a new ExtensionPermissionSet from its |value| and passes ownership to +// the caller through |ptr|. Sets |bad_message| to true if the message is badly +// formed. Returns false if the method fails to unpack a permission set. +bool UnpackPermissionsFromValue(DictionaryValue* value, + scoped_refptr<ExtensionPermissionSet>* ptr, + bool* bad_message, + std::string* error) { + ExtensionPermissionsInfo* info = ExtensionPermissionsInfo::GetInstance(); + ExtensionAPIPermissionSet apis; + if (value->HasKey(kApisKey)) { + ListValue* api_list = NULL; + if (!value->GetList(kApisKey, &api_list)) { + *bad_message = true; + return false; + } + for (size_t i = 0; i < api_list->GetSize(); ++i) { + std::string api_name; + if (!api_list->GetString(i, &api_name)) { + *bad_message = true; + return false; + } + + ExtensionAPIPermission* permission = info->GetByName(api_name); + if (!permission) { + *error = ExtensionErrorUtils::FormatErrorMessage( + kUnknownPermissionError, api_name); + return false; + } + apis.insert(permission->id()); + } + } + + URLPatternSet origins; + if (value->HasKey(kOriginsKey)) { + ListValue* origin_list = NULL; + if (!value->GetList(kOriginsKey, &origin_list)) { + *bad_message = true; + return false; + } + for (size_t i = 0; i < origin_list->GetSize(); ++i) { + std::string pattern; + if (!origin_list->GetString(i, &pattern)) { + *bad_message = true; + return false; + } + + URLPattern origin(Extension::kValidHostPermissionSchemes); + URLPattern::ParseResult parse_result = origin.Parse(pattern); + if (URLPattern::PARSE_SUCCESS != parse_result) { + *error = ExtensionErrorUtils::FormatErrorMessage( + kInvalidOrigin, + pattern, + URLPattern::GetParseResultString(parse_result)); + return false; + } + origins.AddPattern(origin); + } + } + + *ptr = new ExtensionPermissionSet(apis, origins, URLPatternSet()); + return true; +} + +} // namespace permissions_api +} // namespace extensions diff --git a/chrome/browser/extensions/extension_permissions_api_helpers.h b/chrome/browser/extensions/extension_permissions_api_helpers.h new file mode 100644 index 0000000..563f99e --- /dev/null +++ b/chrome/browser/extensions/extension_permissions_api_helpers.h @@ -0,0 +1,36 @@ +// Copyright (c) 2012 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_BROWSER_EXTENSIONS_EXTENSION_PERMISSIONS_API_HELPERS_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_PERMISSIONS_API_HELPERS_H_ +#pragma once + +#include <string> + +#include "base/memory/ref_counted.h" + +namespace base { +class DictionaryValue; +} +class ExtensionPermissionSet; + +namespace extensions { + +namespace permissions_api { + +// Converts the permission |set| to a dictionary value. +base::DictionaryValue* PackPermissionsToValue( + const ExtensionPermissionSet* set); + +// Converts the |value| to a permission set. +bool UnpackPermissionsFromValue(base::DictionaryValue* value, + scoped_refptr<ExtensionPermissionSet>* ptr, + bool* bad_message, + std::string* error); + +} // namespace permissions_api + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_PERMISSIONS_API_HELPERS_H__ diff --git a/chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc b/chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc new file mode 100644 index 0000000..939db3a --- /dev/null +++ b/chrome/browser/extensions/extension_permissions_api_helpers_unittest.cc @@ -0,0 +1,157 @@ +// Copyright (c) 2012 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/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/extensions/extension_permissions_api_helpers.h" +#include "chrome/common/extensions/extension_permission_set.h" +#include "chrome/common/extensions/url_pattern_set.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +using extensions::permissions_api::PackPermissionsToValue; +using extensions::permissions_api::UnpackPermissionsFromValue; + +namespace { + +static void AddPattern(URLPatternSet* extent, const std::string& pattern) { + int schemes = URLPattern::SCHEME_ALL; + extent->AddPattern(URLPattern(schemes, pattern)); +} + +} // namespace + +// Tests that we can convert ExtensionPermissionSets to and from values. +TEST(ExtensionPermissionsAPIHelpers, Pack) { + ExtensionAPIPermissionSet apis; + apis.insert(ExtensionAPIPermission::kTab); + apis.insert(ExtensionAPIPermission::kWebRequest); + URLPatternSet hosts; + AddPattern(&hosts, "http://a.com/*"); + AddPattern(&hosts, "http://b.com/*"); + + scoped_refptr<ExtensionPermissionSet> permissions = + new ExtensionPermissionSet(apis, hosts, URLPatternSet()); + + // Pack the permission set to value and verify its contents. + scoped_ptr<DictionaryValue> value(PackPermissionsToValue(permissions)); + ListValue* api_list = NULL; + ListValue* origin_list = NULL; + ASSERT_TRUE(value->GetList("permissions", &api_list)); + ASSERT_TRUE(value->GetList("origins", &origin_list)); + + ASSERT_EQ(2u, api_list->GetSize()); + ASSERT_EQ(2u, origin_list->GetSize()); + + std::string expected_apis[] = { "tabs", "webRequest" }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_apis); ++i) { + scoped_ptr<Value> value(Value::CreateStringValue(expected_apis[i])); + ASSERT_NE(api_list->end(), api_list->Find(*value)); + } + + std::string expected_origins[] = { "http://a.com/*", "http://b.com/*" }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expected_origins); ++i) { + scoped_ptr<Value> value(Value::CreateStringValue(expected_origins[i])); + ASSERT_NE(origin_list->end(), origin_list->Find(*value)); + } + + // Unpack the value back to a permission set and make sure its equal to the + // original one. + scoped_refptr<ExtensionPermissionSet> from_value; + bool bad_message = false; + std::string error; + ASSERT_TRUE(UnpackPermissionsFromValue( + value.get(), &from_value, &bad_message, &error)); + ASSERT_FALSE(bad_message); + ASSERT_TRUE(error.empty()); + + ASSERT_EQ(*permissions, *from_value); +} + +// Tests various error conditions and edge cases when unpacking values +// into ExtensionPermissionSets. +TEST(ExtensionPermissionsAPIHelpers, Unpack) { + scoped_ptr<ListValue> apis(new ListValue()); + apis->Append(Value::CreateStringValue("tabs")); + scoped_ptr<ListValue> origins(new ListValue()); + origins->Append(Value::CreateStringValue("http://a.com/*")); + + scoped_ptr<DictionaryValue> value(new DictionaryValue()); + scoped_refptr<ExtensionPermissionSet> permissions; + bool bad_message = false; + std::string error; + + // Origins shouldn't have to be present. + value->Set("permissions", apis->DeepCopy()); + ASSERT_TRUE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_TRUE(permissions->HasAPIPermission(ExtensionAPIPermission::kTab)); + ASSERT_FALSE(bad_message); + ASSERT_TRUE(error.empty()); + + // The api permissions don't need to be present either. + value->Clear(); + value->Set("origins", origins->DeepCopy()); + ASSERT_TRUE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_FALSE(bad_message); + ASSERT_TRUE(error.empty()); + ASSERT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/"))); + + // Throw errors for non-string API permissions. + value->Clear(); + scoped_ptr<ListValue> invalid_apis(apis->DeepCopy()); + invalid_apis->Append(Value::CreateIntegerValue(3)); + value->Set("permissions", invalid_apis->DeepCopy()); + ASSERT_FALSE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_TRUE(bad_message); + bad_message = false; + + // Throw errors for non-string origins. + value->Clear(); + scoped_ptr<ListValue> invalid_origins(origins->DeepCopy()); + invalid_origins->Append(Value::CreateIntegerValue(3)); + value->Set("origins", invalid_origins->DeepCopy()); + ASSERT_FALSE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_TRUE(bad_message); + bad_message = false; + + // Throw errors when "origins" or "permissions" are not list values. + value->Clear(); + value->Set("origins", Value::CreateIntegerValue(2)); + ASSERT_FALSE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_TRUE(bad_message); + bad_message = false; + + value->Clear(); + value->Set("permissions", Value::CreateIntegerValue(2)); + ASSERT_FALSE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_TRUE(bad_message); + bad_message = false; + + // Additional fields should be allowed. + value->Clear(); + value->Set("origins", origins->DeepCopy()); + value->Set("random", Value::CreateIntegerValue(3)); + ASSERT_TRUE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_FALSE(bad_message); + ASSERT_TRUE(error.empty()); + ASSERT_TRUE(permissions->HasExplicitAccessToOrigin(GURL("http://a.com/"))); + + // Unknown permissions should throw an error but not set the bad_message bit. + value->Clear(); + invalid_apis.reset(apis->DeepCopy()); + invalid_apis->Append(Value::CreateStringValue("unknown_permission")); + value->Set("permissions", invalid_apis->DeepCopy()); + ASSERT_FALSE(UnpackPermissionsFromValue( + value.get(), &permissions, &bad_message, &error)); + ASSERT_FALSE(bad_message); + ASSERT_FALSE(error.empty()); + ASSERT_EQ(error, "'unknown_permission' is not a recognized permission."); +} diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index 5d3ffb8..2db9472 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -27,6 +27,7 @@ #include "content/browser/site_instance.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" using content::BrowserThread; diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index e1edd27..655a80e 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -57,6 +57,7 @@ #include "chrome/browser/extensions/external_extension_provider_interface.h" #include "chrome/browser/extensions/installed_loader.h" #include "chrome/browser/extensions/pending_extension_manager.h" +#include "chrome/browser/extensions/permissions_updater.h" #include "chrome/browser/extensions/settings/settings_frontend.h" #include "chrome/browser/extensions/unpacked_installer.h" #include "chrome/browser/history/history_extension_api.h" @@ -384,7 +385,6 @@ ExtensionService::ExtensionService(Profile* profile, toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), menu_manager_(profile), app_notification_manager_(new AppNotificationManager(profile)), - permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), apps_promo_(profile->GetPrefs()), event_routers_initialized_(false), extension_warnings_(profile), @@ -905,35 +905,17 @@ void ExtensionService::DisableExtension(const std::string& extension_id) { extension_warnings_.ClearWarnings(warnings); } -void ExtensionService::GrantPermissions(const Extension* extension) { - CHECK(extension); - - // We only maintain the granted permissions prefs for extensions that can't - // silently increase their permissions. - if (extension->CanSilentlyIncreasePermissions()) - return; - - extension_prefs_->AddGrantedPermissions(extension->id(), - extension->GetActivePermissions()); -} - void ExtensionService::GrantPermissionsAndEnableExtension( const Extension* extension) { CHECK(extension); RecordPermissionMessagesHistogram( extension, "Extensions.Permissions_ReEnable"); - GrantPermissions(extension); + extensions::PermissionsUpdater perms_updater(profile()); + perms_updater.GrantActivePermissions(extension); extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); EnableExtension(extension->id()); } -void ExtensionService::UpdateActivePermissions( - const Extension* extension, - const ExtensionPermissionSet* permissions) { - extension_prefs()->SetActivePermissions(extension->id(), permissions); - extension->SetActivePermissions(permissions); -} - // static void ExtensionService::RecordPermissionMessagesHistogram( const Extension* e, const char* histogram) { @@ -2054,7 +2036,8 @@ void ExtensionService::InitializePermissions(const Extension* extension) { adjusted_active = ExtensionPermissionSet::CreateUnion( extension->required_permission_set(), adjusted_active.get()); - UpdateActivePermissions(extension, adjusted_active); + extensions::PermissionsUpdater perms_updater(profile()); + perms_updater.UpdateActivePermissions(extension, adjusted_active); } // We keep track of all permissions the user has granted each extension. diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 3ce1a99..9922976 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -25,7 +25,6 @@ #include "chrome/browser/extensions/apps_promo.h" #include "chrome/browser/extensions/extension_icon_manager.h" #include "chrome/browser/extensions/extension_menu_manager.h" -#include "chrome/browser/extensions/extension_permissions_api.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_sync_data.h" @@ -349,18 +348,10 @@ class ExtensionService virtual void DisableExtension(const std::string& extension_id); // Updates the |extension|'s granted permissions lists to include all - // permissions in the |extension|'s manifest. - void GrantPermissions(const Extension* extension); - - // Updates the |extension|'s granted permissions lists to include all // permissions in the |extension|'s manifest and re-enables the // extension. void GrantPermissionsAndEnableExtension(const Extension* extension); - // Sets the |extension|'s active permissions to |permissions|. - void UpdateActivePermissions(const Extension* extension, - const ExtensionPermissionSet* permissions); - // Check for updates (or potentially new extensions from external providers) void CheckForExternalUpdates(); @@ -476,10 +467,6 @@ class ExtensionService return app_notification_manager_.get(); } - ExtensionPermissionsManager* permissions_manager() { - return &permissions_manager_; - } - ExtensionBrowserEventRouter* browser_event_router() { return browser_event_router_.get(); } @@ -796,9 +783,6 @@ class ExtensionService // Keeps track of app notifications. scoped_refptr<AppNotificationManager> app_notification_manager_; - // Keeps track of extension permissions. - ExtensionPermissionsManager permissions_manager_; - // Keeps track of favicon-sized omnibox icons for extensions. ExtensionIconManager omnibox_icon_manager_; ExtensionIconManager omnibox_popup_icon_manager_; diff --git a/chrome/browser/extensions/extension_tab_helper.cc b/chrome/browser/extensions/extension_tab_helper.cc index ea0785d..76533e0 100644 --- a/chrome/browser/extensions/extension_tab_helper.cc +++ b/chrome/browser/extensions/extension_tab_helper.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -22,6 +22,7 @@ #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" using content::WebContents; diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc index d391683..efdb1f3 100644 --- a/chrome/browser/extensions/extension_webrequest_api.cc +++ b/chrome/browser/extensions/extension_webrequest_api.cc @@ -38,6 +38,7 @@ #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" #include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "net/base/auth.h" diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index df48df0..4df3996 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -11,6 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/omnibox/location_bar.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/test/base/ui_test_utils.h" diff --git a/chrome/browser/extensions/permissions_apitest.cc b/chrome/browser/extensions/permissions_apitest.cc index e0bd632..c000bf19 100644 --- a/chrome/browser/extensions/permissions_apitest.cc +++ b/chrome/browser/extensions/permissions_apitest.cc @@ -1,8 +1,9 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_permissions_api.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc new file mode 100644 index 0000000..eb79b70 --- /dev/null +++ b/chrome/browser/extensions/permissions_updater.cc @@ -0,0 +1,155 @@ +// Copyright (c) 2012 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/browser/extensions/permissions_updater.h" + +#include "base/json/json_writer.h" +#include "base/memory/ref_counted.h" +#include "base/values.h" +#include "chrome/browser/extensions/extension_event_router.h" +#include "chrome/browser/extensions/extension_permissions_api_helpers.h" +#include "chrome/browser/extensions/extension_prefs.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_messages.h" +#include "chrome/common/extensions/extension_permission_set.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/render_process_host.h" + +using content::RenderProcessHost; +using extensions::permissions_api::PackPermissionsToValue; + +namespace extensions { + +namespace { + +const char kOnAdded[] = "permissions.onAdded"; +const char kOnRemoved[] = "permissions.onRemoved"; + +} + +PermissionsUpdater::PermissionsUpdater(Profile* profile) + : profile_(profile) {} + +PermissionsUpdater::~PermissionsUpdater() {} + +void PermissionsUpdater::AddPermissions( + const Extension* extension, const ExtensionPermissionSet* permissions) { + scoped_refptr<const ExtensionPermissionSet> existing( + extension->GetActivePermissions()); + scoped_refptr<ExtensionPermissionSet> total( + ExtensionPermissionSet::CreateUnion(existing, permissions)); + scoped_refptr<ExtensionPermissionSet> added( + ExtensionPermissionSet::CreateDifference(total.get(), existing)); + + UpdateActivePermissions(extension, total.get()); + + // Update the granted permissions so we don't auto-disable the extension. + GrantActivePermissions(extension); + + NotifyPermissionsUpdated(ADDED, extension, added.get()); +} + +void PermissionsUpdater::RemovePermissions( + const Extension* extension, const ExtensionPermissionSet* permissions) { + scoped_refptr<const ExtensionPermissionSet> existing( + extension->GetActivePermissions()); + scoped_refptr<ExtensionPermissionSet> total( + ExtensionPermissionSet::CreateDifference(existing, permissions)); + scoped_refptr<ExtensionPermissionSet> removed( + ExtensionPermissionSet::CreateDifference(existing, total.get())); + + // We update the active permissions, and not the granted permissions, because + // the extension, not the user, removed the permissions. This allows the + // extension to add them again without prompting the user. + UpdateActivePermissions(extension, total.get()); + + NotifyPermissionsUpdated(REMOVED, extension, removed.get()); +} + +void PermissionsUpdater::GrantActivePermissions(const Extension* extension) { + CHECK(extension); + + // We only maintain the granted permissions prefs for extensions that can't + // silently increase their permissions. + if (extension->CanSilentlyIncreasePermissions()) + return; + + GetExtensionPrefs()->AddGrantedPermissions( + extension->id(), extension->GetActivePermissions()); +} + +void PermissionsUpdater::UpdateActivePermissions( + const Extension* extension, const ExtensionPermissionSet* permissions) { + GetExtensionPrefs()->SetActivePermissions(extension->id(), permissions); + extension->SetActivePermissions(permissions); +} + +void PermissionsUpdater::DispatchEvent( + const std::string& extension_id, + const char* event_name, + const ExtensionPermissionSet* changed_permissions) { + if (!profile_ || !profile_->GetExtensionEventRouter()) + return; + + ListValue value; + value.Append(PackPermissionsToValue(changed_permissions)); + std::string json_value; + base::JSONWriter::Write(&value, false, &json_value); + profile_->GetExtensionEventRouter()->DispatchEventToExtension( + extension_id, event_name, json_value, profile_, GURL()); +} + +void PermissionsUpdater::NotifyPermissionsUpdated( + EventType event_type, + const Extension* extension, + const ExtensionPermissionSet* changed) { + if (!changed || changed->IsEmpty()) + return; + + UpdatedExtensionPermissionsInfo::Reason reason; + const char* event_name = NULL; + + if (event_type == REMOVED) { + reason = UpdatedExtensionPermissionsInfo::REMOVED; + event_name = kOnRemoved; + } else { + CHECK_EQ(ADDED, event_type); + reason = UpdatedExtensionPermissionsInfo::ADDED; + event_name = kOnAdded; + } + + // Notify other APIs or interested parties. + UpdatedExtensionPermissionsInfo info = UpdatedExtensionPermissionsInfo( + extension, changed, reason); + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, + content::Source<Profile>(profile_), + content::Details<UpdatedExtensionPermissionsInfo>(&info)); + + // Send the new permissions to the renderers. + for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); + !i.IsAtEnd(); i.Advance()) { + RenderProcessHost* host = i.GetCurrentValue(); + Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); + if (profile_->IsSameProfile(profile)) + host->Send(new ExtensionMsg_UpdatePermissions( + static_cast<int>(reason), + extension->id(), + changed->apis(), + changed->explicit_hosts(), + changed->scriptable_hosts())); + } + + // Trigger the onAdded and onRemoved events in the extension. + DispatchEvent(extension->id(), event_name, changed); +} + +ExtensionPrefs* PermissionsUpdater::GetExtensionPrefs() { + return profile_->GetExtensionService()->extension_prefs(); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/permissions_updater.h b/chrome/browser/extensions/permissions_updater.h new file mode 100644 index 0000000..0640f2d --- /dev/null +++ b/chrome/browser/extensions/permissions_updater.h @@ -0,0 +1,77 @@ +// Copyright (c) 2012 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_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__ +#define CHROME_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__ +#pragma once + +#include <string> + +#include "base/memory/ref_counted.h" + +namespace base { +class DictionaryValue; +} +class Extension; +class ExtensionPermissionSet; +class ExtensionPrefs; +class Profile; + +namespace extensions { + +// Updates an Extension's active and granted permissions in persistent storage +// and notifies interested parties of the changes. +class PermissionsUpdater { + public: + explicit PermissionsUpdater(Profile* profile); + ~PermissionsUpdater(); + + // Adds the set of |permissions| to the |extension|'s active permission set + // and sends the relevant messages and notifications. This method assumes the + // user has already been prompted, if necessary, for the extra permissions. + void AddPermissions(const Extension* extension, + const ExtensionPermissionSet* permissions); + + // Removes the set of |permissions| from the |extension|'s active permission + // set and sends the relevant messages and notifications. + void RemovePermissions(const Extension* extension, + const ExtensionPermissionSet* permissions); + + // Adds all permissions in the |extension|'s active permissions to its + // granted permission set. + void GrantActivePermissions(const Extension* extension); + + // Sets the |extension|'s active permissions to |permissions|. + void UpdateActivePermissions(const Extension* extension, + const ExtensionPermissionSet* permissions); + + private: + enum EventType { + ADDED, + REMOVED, + }; + + // Dispatches specified event to the extension. + void DispatchEvent(const std::string& extension_id, + const char* event_name, + const ExtensionPermissionSet* changed_permissions); + + // Issues the relevant events, messages and notifications when the + // |extension|'s permissions have |changed| (|changed| is the delta). + // Specifically, this sends the EXTENSION_PERMISSIONS_UPDATED notification, + // the ExtensionMsg_UpdatePermissions IPC message, and fires the + // onAdded/onRemoved events in the extension. + void NotifyPermissionsUpdated(EventType event_type, + const Extension* extension, + const ExtensionPermissionSet* changed); + + // Gets the ExtensionPrefs for the associated profile. + ExtensionPrefs* GetExtensionPrefs(); + + Profile* profile_; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_PERMISSIONS_UPDATER_H__ diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc new file mode 100644 index 0000000..30e38de --- /dev/null +++ b/chrome/browser/extensions/permissions_updater_unittest.cc @@ -0,0 +1,210 @@ +// Copyright (c) 2012 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/file_path.h" +#include "base/json/json_value_serializer.h" +#include "base/memory/ref_counted.h" +#include "base/path_service.h" +#include "base/values.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_service_unittest.h" +#include "chrome/browser/extensions/permissions_updater.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_permission_set.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" +#include "content/public/browser/notification_service.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { + +namespace { + +// A helper class that listens for NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED. +class PermissionsUpdaterListener : public content::NotificationObserver { + public: + PermissionsUpdaterListener() + : received_notification_(false), waiting_(false) { + registrar_.Add(this, + chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, + content::NotificationService::AllSources()); + } + + void Reset() { + received_notification_ = false; + waiting_ = false; + extension_ = NULL; + permissions_ = NULL; + } + + void Wait() { + if (received_notification_) + return; + + waiting_ = true; + ui_test_utils::RunMessageLoop(); + } + + bool received_notification() const { return received_notification_; } + const Extension* extension() const { return extension_; } + const ExtensionPermissionSet* permissions() const { return permissions_; } + UpdatedExtensionPermissionsInfo::Reason reason() const { + return reason_; + } + + private: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE { + received_notification_ = true; + UpdatedExtensionPermissionsInfo* info = + content::Details<UpdatedExtensionPermissionsInfo>(details).ptr(); + + extension_ = info->extension; + permissions_ = info->permissions; + reason_ = info->reason; + + if (waiting_) { + waiting_ = false; + MessageLoopForUI::current()->Quit(); + } + } + + bool received_notification_; + bool waiting_; + content::NotificationRegistrar registrar_; + scoped_refptr<const Extension> extension_; + scoped_refptr<const ExtensionPermissionSet> permissions_; + UpdatedExtensionPermissionsInfo::Reason reason_; +}; + +class PermissionsUpdaterTest : public ExtensionServiceTestBase { +}; + +scoped_refptr<Extension> LoadManifest(std::string* error) { + FilePath path; + PathService::Get(chrome::DIR_TEST_DATA, &path); + path = path.AppendASCII("extensions") + .AppendASCII("api_test") + .AppendASCII("permissions") + .AppendASCII("optional") + .AppendASCII("manifest.json"); + + JSONFileValueSerializer serializer(path); + scoped_ptr<Value> result(serializer.Deserialize(NULL, error)); + if (!result.get()) + return NULL; + + scoped_refptr<Extension> extension = Extension::Create( + path.DirName(), Extension::INTERNAL, + *static_cast<DictionaryValue*>(result.get()), Extension::NO_FLAGS, error); + return extension; +} + +void AddPattern(URLPatternSet* extent, const std::string& pattern) { + int schemes = URLPattern::SCHEME_ALL; + extent->AddPattern(URLPattern(schemes, pattern)); +} + +} // namespace + +// Test that the PermissionUpdater can correctly add and remove active +// permissions. This tests all of PermissionsUpdater's public methods because +// GrantActivePermissions and UpdateActivePermissions are used by +// AddPermissions. +TEST_F(PermissionsUpdaterTest, AddAndRemovePermissions) { + InitializeEmptyExtensionService(); + + // Load the test extension. + std::string error; + scoped_refptr<Extension> extension = LoadManifest(&error); + ASSERT_TRUE(error.empty()) << error; + + ExtensionAPIPermissionSet default_apis; + default_apis.insert(ExtensionAPIPermission::kManagement); + URLPatternSet default_hosts; + AddPattern(&default_hosts, "http://a.com/*"); + scoped_refptr<ExtensionPermissionSet> default_permissions = + new ExtensionPermissionSet(default_apis, default_hosts, URLPatternSet()); + + // Make sure it loaded properly. + scoped_refptr<const ExtensionPermissionSet> permissions = + extension->GetActivePermissions(); + ASSERT_EQ(*default_permissions, *extension->GetActivePermissions()); + + // Add a few permissions. + ExtensionAPIPermissionSet apis; + apis.insert(ExtensionAPIPermission::kTab); + apis.insert(ExtensionAPIPermission::kNotification); + URLPatternSet hosts; + AddPattern(&hosts, "http://*.c.com/*"); + + scoped_refptr<ExtensionPermissionSet> delta = + new ExtensionPermissionSet(apis, hosts, URLPatternSet()); + + PermissionsUpdaterListener listener; + PermissionsUpdater updater(profile_.get()); + updater.AddPermissions(extension.get(), delta.get()); + + listener.Wait(); + + // Verify that the permission notification was sent correctly. + ASSERT_TRUE(listener.received_notification()); + ASSERT_EQ(extension, listener.extension()); + ASSERT_EQ(UpdatedExtensionPermissionsInfo::ADDED, listener.reason()); + ASSERT_EQ(*delta, *listener.permissions()); + + // Make sure the extension's active permissions reflect the change. + scoped_refptr<ExtensionPermissionSet> active_permissions = + ExtensionPermissionSet::CreateUnion(default_permissions, delta); + ASSERT_EQ(*active_permissions, *extension->GetActivePermissions()); + + // Verify that the new granted and active permissions were also stored + // in the extension preferences. In this case, the granted permissions should + // be equal to the active permissions. + ExtensionPrefs* prefs = service_->extension_prefs(); + scoped_refptr<ExtensionPermissionSet> granted_permissions = + active_permissions; + + scoped_refptr<ExtensionPermissionSet> from_prefs = + prefs->GetActivePermissions(extension->id()); + ASSERT_EQ(*active_permissions, *from_prefs); + + from_prefs = prefs->GetGrantedPermissions(extension->id()); + ASSERT_EQ(*active_permissions, *from_prefs); + + // In the second part of the test, we'll remove the permissions that we + // just added except for 'notification'. + apis.erase(ExtensionAPIPermission::kNotification); + delta = new ExtensionPermissionSet(apis, hosts, URLPatternSet()); + + listener.Reset(); + updater.RemovePermissions(extension, delta); + listener.Wait(); + + // Verify that the notification was correct. + ASSERT_TRUE(listener.received_notification()); + ASSERT_EQ(extension, listener.extension()); + ASSERT_EQ(UpdatedExtensionPermissionsInfo::REMOVED, listener.reason()); + ASSERT_EQ(*delta, *listener.permissions()); + + // Make sure the extension's active permissions reflect the change. + active_permissions = + ExtensionPermissionSet::CreateDifference(active_permissions, delta); + ASSERT_EQ(*active_permissions, *extension->GetActivePermissions()); + + // Verify that the extension prefs hold the new active permissions and the + // same granted permissions. + from_prefs = prefs->GetActivePermissions(extension->id()); + ASSERT_EQ(*active_permissions, *from_prefs); + + from_prefs = prefs->GetGrantedPermissions(extension->id()); + ASSERT_EQ(*granted_permissions, *from_prefs); +} + +} // namespace extensions diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc index 852e6c7..b4301a3 100644 --- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc +++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc @@ -14,6 +14,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/background_contents.h" #include "chrome/browser/tab_contents/retargeting_details.h" +#include "chrome/common/chrome_notification_types.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index cb1e72a..1fee671 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -26,6 +26,7 @@ #include "chrome/browser/ui/status_bubble.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/web_applications/web_app.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc index 017b972..bd0cbc8 100644 --- a/chrome/browser/ui/intents/web_intent_picker_controller.cc +++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -19,6 +19,7 @@ #include "chrome/browser/ui/intents/web_intent_picker_factory.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/webdata/web_data_service.h" +#include "chrome/common/chrome_notification_types.h" #include "content/browser/intents/intent_injector.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" diff --git a/chrome/browser/ui/panels/base_panel_browser_test.cc b/chrome/browser/ui/panels/base_panel_browser_test.cc index 8f3b6fb..5abb51a 100644 --- a/chrome/browser/ui/panels/base_panel_browser_test.cc +++ b/chrome/browser/ui/panels/base_panel_browser_test.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -19,6 +19,7 @@ #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_mouse_watcher.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/string_ordinal.h" diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index ad43f58..ddc22f4 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -15,6 +15,7 @@ #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/window_sizer.h" #include "chrome/browser/web_applications/web_app.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/public/browser/notification_service.h" diff --git a/chrome/browser/ui/panels/panel_app_browsertest.cc b/chrome/browser/ui/panels/panel_app_browsertest.cc index c426e71..d658d72 100644 --- a/chrome/browser/ui/panels/panel_app_browsertest.cc +++ b/chrome/browser/ui/panels/panel_app_browsertest.cc @@ -1,5 +1,4 @@ - -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -13,6 +12,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/panels/panel_manager.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" diff --git a/chrome/browser/ui/panels/panel_browser_view_browsertest.cc b/chrome/browser/ui/panels/panel_browser_view_browsertest.cc index b259fe1..b22c6a3 100644 --- a/chrome/browser/ui/panels/panel_browser_view_browsertest.cc +++ b/chrome/browser/ui/panels/panel_browser_view_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -14,6 +14,7 @@ #include "chrome/browser/ui/panels/panel_browser_view.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/web_applications/web_app.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/test/base/ui_test_utils.h" diff --git a/chrome/browser/ui/webui/options/extension_settings_handler.cc b/chrome/browser/ui/webui/options/extension_settings_handler.cc index 89545cc3..5ae0e6d 100644 --- a/chrome/browser/ui/webui/options/extension_settings_handler.cc +++ b/chrome/browser/ui/webui/options/extension_settings_handler.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -25,6 +25,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/background_contents.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_view_type.h" #include "chrome/common/extensions/extension.h" diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 9627beb..8c9ba15 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1119,6 +1119,8 @@ 'browser/extensions/extension_page_capture_api.h', 'browser/extensions/extension_permissions_api.cc', 'browser/extensions/extension_permissions_api.h', + 'browser/extensions/extension_permissions_api_helpers.cc', + 'browser/extensions/extension_permissions_api_helpers.h', 'browser/extensions/extension_pref_store.cc', 'browser/extensions/extension_pref_store.h', 'browser/extensions/extension_pref_value_map.cc', @@ -1243,6 +1245,8 @@ 'browser/extensions/pending_extension_info.h', 'browser/extensions/pending_extension_manager.cc', 'browser/extensions/pending_extension_manager.h', + 'browser/extensions/permissions_updater.cc', + 'browser/extensions/permissions_updater.h', 'browser/extensions/process_map.cc', 'browser/extensions/process_map.h', 'browser/extensions/sandboxed_extension_unpacker.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 12a2f90..ccf8f52 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1415,6 +1415,7 @@ 'browser/extensions/extension_info_map_unittest.cc', 'browser/extensions/extension_menu_manager_unittest.cc', 'browser/extensions/extension_omnibox_unittest.cc', + 'browser/extensions/extension_permissions_api_helpers_unittest.cc', 'browser/extensions/extension_pref_value_map_unittest.cc', 'browser/extensions/extension_prefs_unittest.cc', 'browser/extensions/extension_process_manager_unittest.cc', @@ -1432,6 +1433,7 @@ 'browser/extensions/extension_webrequest_time_tracker_unittest.cc', 'browser/extensions/extensions_quota_service_unittest.cc', 'browser/extensions/external_policy_extension_loader_unittest.cc', + 'browser/extensions/permissions_updater_unittest.cc', 'browser/extensions/file_reader_unittest.cc', 'browser/extensions/image_loading_tracker_unittest.cc', 'browser/extensions/key_identifier_conversion_views_unittest.cc', |