[Extensions] Un-refcount PermissionSet

PermissionSet represents a set of permissions, and for some reason,
it's been refcounted. There's really no reason to have it, and it
makes everything more costly and difficult to reason about. Remove the
refcounting.

Note: This is part 1 of a 2-part series. This removes the ref-counting.
In a followup, I'll go through and update many of the places that
use const PermissionSet* and convert to const &.

BUG=455414
[email protected] (misc chrome files with ptr conversion)
[email protected] (extension messages - not actually changing any IPC messages)

Review URL: https://codereview.chromium.org/1349613003

Cr-Commit-Position: refs/heads/master@{#350684}
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc
index a8f111b6..ef4aefa 100644
--- a/chrome/browser/background/background_application_list_model.cc
+++ b/chrome/browser/background/background_application_list_model.cc
@@ -363,8 +363,8 @@
 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated(
     const Extension* extension,
     UpdatedExtensionPermissionsInfo::Reason reason,
-    const PermissionSet* permissions) {
-  if (permissions->HasAPIPermission(APIPermission::kBackground)) {
+    const PermissionSet& permissions) {
+  if (permissions.HasAPIPermission(APIPermission::kBackground)) {
     switch (reason) {
       case UpdatedExtensionPermissionsInfo::ADDED:
         DCHECK(IsBackgroundApp(*extension, profile_));
diff --git a/chrome/browser/background/background_application_list_model.h b/chrome/browser/background/background_application_list_model.h
index 0f19cb0b..b145e5ef 100644
--- a/chrome/browser/background/background_application_list_model.h
+++ b/chrome/browser/background/background_application_list_model.h
@@ -139,7 +139,7 @@
   void OnExtensionPermissionsUpdated(
       const extensions::Extension* extension,
       extensions::UpdatedExtensionPermissionsInfo::Reason reason,
-      const extensions::PermissionSet* permissions);
+      const extensions::PermissionSet& permissions);
 
   // Refresh the list of background applications and generate notifications.
   void Update();
diff --git a/chrome/browser/background/background_application_list_model_unittest.cc b/chrome/browser/background/background_application_list_model_unittest.cc
index fe92927d..1c41c0a4 100644
--- a/chrome/browser/background/background_application_list_model_unittest.cc
+++ b/chrome/browser/background/background_application_list_model_unittest.cc
@@ -117,10 +117,10 @@
 
   scoped_refptr<Extension> temporary =
       CreateExtension(GenerateUniqueExtensionName(), true);
-  scoped_refptr<const extensions::PermissionSet> permissions =
+  const extensions::PermissionSet* permissions =
       temporary->permissions_data()->active_permissions();
-  extensions::PermissionsUpdater(service->profile()).AddPermissions(
-      extension, permissions.get());
+  extensions::PermissionsUpdater(service->profile())
+      .AddPermissions(extension, permissions);
 }
 
 void RemoveBackgroundPermission(ExtensionService* service,
@@ -131,7 +131,7 @@
   }
   extensions::PermissionsUpdater(service->profile())
       .RemovePermissionsUnsafe(
-          extension, extension->permissions_data()->active_permissions().get());
+          extension, extension->permissions_data()->active_permissions());
 }
 
 void AddEphemeralApp(const Extension* extension, ExtensionService* service) {
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc
index 64bb507..5bd2c6c5 100644
--- a/chrome/browser/background/background_mode_manager.cc
+++ b/chrome/browser/background/background_mode_manager.cc
@@ -67,7 +67,6 @@
 
 using base::UserMetricsAction;
 using extensions::Extension;
-using extensions::UpdatedExtensionPermissionsInfo;
 
 namespace {
 
diff --git a/chrome/browser/extensions/active_script_controller.cc b/chrome/browser/extensions/active_script_controller.cc
index f4ef4de..e5c3f03 100644
--- a/chrome/browser/extensions/active_script_controller.cc
+++ b/chrome/browser/extensions/active_script_controller.cc
@@ -89,7 +89,7 @@
   URLPatternSet new_explicit_hosts;
   URLPatternSet new_scriptable_hosts;
 
-  scoped_refptr<const PermissionSet> withheld_permissions =
+  const PermissionSet* withheld_permissions =
       extension->permissions_data()->withheld_permissions();
   if (withheld_permissions->explicit_hosts().MatchesURL(url)) {
     new_explicit_hosts.AddOrigin(UserScript::ValidUserScriptSchemes(),
@@ -100,18 +100,15 @@
                                    url.GetOrigin());
   }
 
-  scoped_refptr<PermissionSet> new_permissions =
-      new PermissionSet(APIPermissionSet(),
-                        ManifestPermissionSet(),
-                        new_explicit_hosts,
-                        new_scriptable_hosts);
+  PermissionSet new_permissions(APIPermissionSet(), ManifestPermissionSet(),
+                                new_explicit_hosts, new_scriptable_hosts);
 
   // Update permissions for the session. This adds |new_permissions| to active
   // permissions and granted permissions.
   // TODO(devlin): Make sure that the permission is removed from
   // withheld_permissions if appropriate.
-  PermissionsUpdater(browser_context_).AddPermissions(extension,
-                                                      new_permissions.get());
+  PermissionsUpdater(browser_context_)
+      .AddPermissions(extension, &new_permissions);
 
   // Allow current tab to run injection.
   OnClicked(extension);
@@ -231,8 +228,7 @@
   // permitted extensions (for metrics), and return immediately.
   if (request_id == -1) {
     if (PermissionsData::ScriptsMayRequireActionForExtension(
-            extension,
-            extension->permissions_data()->active_permissions().get())) {
+            extension, extension->permissions_data()->active_permissions())) {
       permitted_extensions_.insert(extension->id());
     }
     return;
diff --git a/chrome/browser/extensions/active_tab_permission_granter.cc b/chrome/browser/extensions/active_tab_permission_granter.cc
index cce3f3f..64b79c2 100644
--- a/chrome/browser/extensions/active_tab_permission_granter.cc
+++ b/chrome/browser/extensions/active_tab_permission_granter.cc
@@ -104,9 +104,8 @@
 
   if (!new_apis.empty() || !new_hosts.is_empty()) {
     granted_extensions_.Insert(extension);
-    scoped_refptr<const PermissionSet> new_permissions =
-        new PermissionSet(new_apis, ManifestPermissionSet(),
-                          new_hosts, URLPatternSet());
+    PermissionSet new_permissions(new_apis, ManifestPermissionSet(), new_hosts,
+                                  URLPatternSet());
     permissions_data->UpdateTabSpecificPermissions(tab_id_, new_permissions);
     const content::NavigationEntry* navigation_entry =
         web_contents()->GetController().GetVisibleEntry();
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
index 85d58c8..a7efa10 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
@@ -501,8 +501,7 @@
   info->run_on_all_urls.is_enabled =
       (FeatureSwitch::scripts_require_action()->IsEnabled() &&
        PermissionsData::ScriptsMayRequireActionForExtension(
-           &extension,
-           extension.permissions_data()->active_permissions().get())) ||
+           &extension, extension.permissions_data()->active_permissions())) ||
       extension.permissions_data()->HasWithheldImpliedAllHosts() ||
       util::HasSetAllowedScriptingOnAllUrls(extension.id(), browser_context_);
   info->run_on_all_urls.is_active =
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.cc b/chrome/browser/extensions/api/permissions/permissions_api.cc
index e27912a9..da393353 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api.cc
@@ -56,7 +56,7 @@
   scoped_ptr<Contains::Params> params(Contains::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  scoped_refptr<const PermissionSet> permissions = helpers::UnpackPermissionSet(
+  scoped_ptr<const PermissionSet> permissions = helpers::UnpackPermissionSet(
       params->permissions,
       ExtensionPrefs::Get(GetProfile())->AllowFileAccess(extension_->id()),
       &error_);
@@ -65,13 +65,13 @@
 
   results_ = Contains::Results::Create(
       extension()->permissions_data()->active_permissions()->Contains(
-          *permissions.get()));
+          *permissions));
   return true;
 }
 
 bool PermissionsGetAllFunction::RunSync() {
   scoped_ptr<Permissions> permissions = helpers::PackPermissionSet(
-      extension()->permissions_data()->active_permissions().get());
+      extension()->permissions_data()->active_permissions());
   results_ = GetAll::Results::Create(*permissions);
   return true;
 }
@@ -80,7 +80,7 @@
   scoped_ptr<Remove::Params> params(Remove::Params::Create(*args_));
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  scoped_refptr<const PermissionSet> permissions = helpers::UnpackPermissionSet(
+  scoped_ptr<const PermissionSet> permissions = helpers::UnpackPermissionSet(
       params->permissions,
       ExtensionPrefs::Get(GetProfile())->AllowFileAccess(extension_->id()),
       &error_);
@@ -103,12 +103,12 @@
   // optional and required (and should assume its required), so we need both of
   // these checks.
   // TODO(devlin): *Why* do we support that? Should be a load error.
-  scoped_refptr<const PermissionSet> optional =
+  const PermissionSet* optional =
       PermissionsParser::GetOptionalPermissions(extension());
-  scoped_refptr<const PermissionSet> required =
+  const PermissionSet* required =
       PermissionsParser::GetRequiredPermissions(extension());
   if (!optional->Contains(*permissions) ||
-      !scoped_refptr<const PermissionSet>(
+      !scoped_ptr<const PermissionSet>(
            PermissionSet::CreateIntersection(*permissions, *required))
            ->IsEmpty()) {
     error_ = kCantRemoveRequiredPermissionsError;
@@ -192,7 +192,7 @@
 
   // The requested permissions must be defined as optional in the manifest.
   if (!PermissionsParser::GetOptionalPermissions(extension())
-           ->Contains(*requested_permissions_.get())) {
+           ->Contains(*requested_permissions_)) {
     error_ = kNotInOptionalPermissionsError;
     return false;
   }
@@ -200,17 +200,17 @@
   // Automatically declines api permissions requests, which are blocked by
   // enterprise policy.
   if (!ExtensionManagementFactory::GetForBrowserContext(GetProfile())
-           ->IsPermissionSetAllowed(extension(), requested_permissions_)) {
+           ->IsPermissionSetAllowed(extension(), *requested_permissions_)) {
     error_ = kBlockedByEnterprisePolicy;
     return false;
   }
 
   // We don't need to prompt the user if the requested permissions are a subset
   // of the granted permissions set.
-  scoped_refptr<const PermissionSet> granted =
+  scoped_ptr<const PermissionSet> granted =
       ExtensionPrefs::Get(GetProfile())
           ->GetGrantedPermissions(extension()->id());
-  if (granted.get() && granted->Contains(*requested_permissions_.get())) {
+  if (granted.get() && granted->Contains(*requested_permissions_)) {
     PermissionsUpdater perms_updater(GetProfile());
     perms_updater.AddPermissions(extension(), requested_permissions_.get());
     results_ = Request::Results::Create(true);
@@ -224,7 +224,7 @@
 
   // Filter out the active permissions.
   requested_permissions_ = PermissionSet::CreateDifference(
-      *requested_permissions_.get(),
+      *requested_permissions_,
       *extension()->permissions_data()->active_permissions());
 
   AddRef();  // Balanced in InstallUIProceed() / InstallUIAbort().
@@ -248,8 +248,8 @@
   } else {
     CHECK_EQ(DO_NOT_SKIP, auto_confirm_for_tests);
     install_ui_.reset(new ExtensionInstallPrompt(GetAssociatedWebContents()));
-    install_ui_->ConfirmPermissions(
-        this, extension(), requested_permissions_.get());
+    install_ui_->ConfirmPermissions(this, extension(),
+                                    requested_permissions_->Clone());
   }
 
   return true;
diff --git a/chrome/browser/extensions/api/permissions/permissions_api.h b/chrome/browser/extensions/api/permissions/permissions_api.h
index 9c58c579..cff53326 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api.h
+++ b/chrome/browser/extensions/api/permissions/permissions_api.h
@@ -74,7 +74,7 @@
 
  private:
   scoped_ptr<ExtensionInstallPrompt> install_ui_;
-  scoped_refptr<const PermissionSet> requested_permissions_;
+  scoped_ptr<const PermissionSet> requested_permissions_;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc b/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc
index 71fb3ea..298ece3f 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc
@@ -15,10 +15,6 @@
 #include "extensions/common/permissions/usb_device_permission.h"
 #include "extensions/common/url_pattern_set.h"
 
-using extensions::APIPermission;
-using extensions::PermissionSet;
-using extensions::PermissionsInfo;
-
 namespace extensions {
 
 using api::permissions::Permissions;
@@ -67,7 +63,7 @@
   return scoped_ptr<Permissions>(permissions);
 }
 
-scoped_refptr<const PermissionSet> UnpackPermissionSet(
+scoped_ptr<const PermissionSet> UnpackPermissionSet(
     const Permissions& permissions,
     bool allow_file_access,
     std::string* error) {
@@ -149,7 +145,7 @@
     }
   }
 
-  return make_scoped_refptr(
+  return make_scoped_ptr(
       new PermissionSet(apis, manifest_permissions, origins, URLPatternSet()));
 }
 
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers.h b/chrome/browser/extensions/api/permissions/permissions_api_helpers.h
index becc490..5284c44 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api_helpers.h
+++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers.h
@@ -31,7 +31,7 @@
 
 // Creates a permission set from |permissions|. Returns NULL if the permissions
 // cannot be converted to a permission set, in which case |error| will be set.
-scoped_refptr<const PermissionSet> UnpackPermissionSet(
+scoped_ptr<const PermissionSet> UnpackPermissionSet(
     const api::permissions::Permissions& permissions,
     bool allow_file_access,
     std::string* error);
diff --git a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
index 6ac34270..0cd5c85 100644
--- a/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc
@@ -36,11 +36,11 @@
   AddPattern(&hosts, "http://a.com/*");
   AddPattern(&hosts, "http://b.com/*");
 
-  scoped_refptr<const PermissionSet> permission_set =
-      new PermissionSet(apis, ManifestPermissionSet(), hosts, URLPatternSet());
+  PermissionSet permission_set(apis, ManifestPermissionSet(), hosts,
+                               URLPatternSet());
 
   // Pack the permission set to value and verify its contents.
-  scoped_ptr<Permissions> permissions(PackPermissionSet(permission_set.get()));
+  scoped_ptr<Permissions> permissions(PackPermissionSet(&permission_set));
   scoped_ptr<base::DictionaryValue> value(permissions->ToValue());
   base::ListValue* api_list = NULL;
   base::ListValue* origin_list = NULL;
@@ -65,14 +65,14 @@
 
   // Unpack the value back to a permission set and make sure its equal to the
   // original one.
-  scoped_refptr<const PermissionSet> from_value;
   std::string error;
   Permissions permissions_object;
   EXPECT_TRUE(Permissions::Populate(*value, &permissions_object));
-  from_value = UnpackPermissionSet(permissions_object, true, &error);
+  scoped_ptr<const PermissionSet> from_value =
+      UnpackPermissionSet(permissions_object, true, &error);
   EXPECT_TRUE(error.empty());
 
-  EXPECT_EQ(*permission_set.get(), *from_value.get());
+  EXPECT_EQ(permission_set, *from_value);
 }
 
 // Tests various error conditions and edge cases when unpacking values
@@ -84,7 +84,7 @@
   origins->Append(new base::StringValue("http://a.com/*"));
 
   scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  scoped_refptr<const PermissionSet> permissions;
+  scoped_ptr<const PermissionSet> permissions;
   std::string error;
 
   // Origins shouldn't have to be present.
diff --git a/chrome/browser/extensions/api/permissions/permissions_apitest.cc b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
index ed55325..37f82c84 100644
--- a/chrome/browser/extensions/api/permissions/permissions_apitest.cc
+++ b/chrome/browser/extensions/api/permissions/permissions_apitest.cc
@@ -92,12 +92,12 @@
   ManifestPermissionSet manifest_permissions;
   URLPatternSet explicit_hosts;
   AddPattern(&explicit_hosts, "http://*.c.com/*");
-  scoped_refptr<const PermissionSet> granted_permissions = new PermissionSet(
-      apis, manifest_permissions, explicit_hosts, URLPatternSet());
+  PermissionSet granted_permissions(apis, manifest_permissions, explicit_hosts,
+                                    URLPatternSet());
 
   ExtensionPrefs* prefs = ExtensionPrefs::Get(browser()->profile());
   prefs->AddGrantedPermissions("kjmkgkdkpedkejedfhmfcenooemhbpbo",
-                               granted_permissions.get());
+                               &granted_permissions);
 
   PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
   host_resolver()->AddRule("*.com", "127.0.0.1");
diff --git a/chrome/browser/extensions/bundle_installer.cc b/chrome/browser/extensions/bundle_installer.cc
index 98b60ee0..c8f6b7b 100644
--- a/chrome/browser/extensions/bundle_installer.cc
+++ b/chrome/browser/extensions/bundle_installer.cc
@@ -261,11 +261,13 @@
     return;
   }
 
-  scoped_refptr<const PermissionSet> permissions =
-      dummy_extensions_[0]->permissions_data()->active_permissions();
-  for (size_t i = 1; i < dummy_extensions_.size(); ++i) {
+  scoped_ptr<const PermissionSet> permissions;
+  PermissionSet empty;
+  for (size_t i = 0; i < dummy_extensions_.size(); ++i) {
+    // Using "permissions ? *permissions : PermissionSet()" tries to do a copy,
+    // and doesn't compile. Use a more verbose, but compilable, workaround.
     permissions = PermissionSet::CreateUnion(
-        *permissions,
+        permissions ? *permissions : empty,
         *dummy_extensions_[i]->permissions_data()->active_permissions());
   }
 
@@ -285,10 +287,10 @@
       web_contents = browser->tab_strip_model()->GetActiveWebContents();
     install_ui_.reset(new ExtensionInstallPrompt(web_contents));
     if (delegated_username_.empty()) {
-      install_ui_->ConfirmBundleInstall(this, &icon_, permissions.get());
+      install_ui_->ConfirmBundleInstall(this, &icon_, permissions.Pass());
     } else {
       install_ui_->ConfirmPermissionsForDelegatedBundleInstall(
-          this, delegated_username_, &icon_, permissions.get());
+          this, delegated_username_, &icon_, permissions.Pass());
     }
   }
 }
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index c8cee2bda..f0c319c3 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -297,11 +297,11 @@
                               extension->id(),
                               &error);
         if (error.empty()) {
-          scoped_refptr<const PermissionSet> expected_permissions =
+          const PermissionSet* expected_permissions =
               dummy_extension->permissions_data()->active_permissions();
           valid = !(PermissionMessageProvider::Get()->IsPrivilegeIncrease(
-              expected_permissions.get(),
-              extension->permissions_data()->active_permissions().get(),
+              expected_permissions,
+              extension->permissions_data()->active_permissions(),
               extension->GetType()));
         }
       }
@@ -798,6 +798,8 @@
   if (!service_weak_.get() || service_weak_->browser_terminating())
     return;
 
+  extension()->permissions_data()->BindToCurrentThread();
+
   if (!update_from_settings_page_) {
     // If there is a client, tell the client about installation.
     if (client_)
diff --git a/chrome/browser/extensions/crx_installer_browsertest.cc b/chrome/browser/extensions/crx_installer_browsertest.cc
index c6aea61..f01c8f8 100644
--- a/chrome/browser/extensions/crx_installer_browsertest.cc
+++ b/chrome/browser/extensions/crx_installer_browsertest.cc
@@ -249,7 +249,7 @@
     mock_prompt->set_record_oauth2_grant(record_oauth2_grant);
     InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt);
 
-    scoped_refptr<const PermissionSet> permissions =
+    scoped_ptr<const PermissionSet> permissions =
         ExtensionPrefs::Get(browser()->profile())
             ->GetGrantedPermissions(mock_prompt->extension_id());
     ASSERT_TRUE(permissions.get());
diff --git a/chrome/browser/extensions/extension_install_prompt.cc b/chrome/browser/extensions/extension_install_prompt.cc
index 7526a7d..9f0ad7d 100644
--- a/chrome/browser/extensions/extension_install_prompt.cc
+++ b/chrome/browser/extensions/extension_install_prompt.cc
@@ -623,10 +623,10 @@
 void ExtensionInstallPrompt::ConfirmBundleInstall(
     extensions::BundleInstaller* bundle,
     const SkBitmap* icon,
-    const PermissionSet* permissions) {
+    scoped_ptr<const PermissionSet> permissions) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   bundle_ = bundle;
-  custom_permissions_ = permissions;
+  custom_permissions_ = permissions.Pass();
   delegate_ = bundle;
   prompt_ = new Prompt(BUNDLE_INSTALL_PROMPT);
 
@@ -638,11 +638,11 @@
     extensions::BundleInstaller* bundle,
     const std::string& delegated_username,
     const SkBitmap* icon,
-    const extensions::PermissionSet* permissions) {
+    scoped_ptr<const extensions::PermissionSet> permissions) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   bundle_ = bundle;
   delegated_username_ = delegated_username;
-  custom_permissions_ = permissions;
+  custom_permissions_ = permissions.Pass();
   delegate_ = bundle;
   prompt_ = new Prompt(DELEGATED_BUNDLE_PERMISSIONS_PROMPT);
 
@@ -759,10 +759,10 @@
 void ExtensionInstallPrompt::ConfirmPermissions(
     Delegate* delegate,
     const Extension* extension,
-    const PermissionSet* permissions) {
+    scoped_ptr<const PermissionSet> permissions) {
   DCHECK(ui_loop_ == base::MessageLoop::current());
   extension_ = extension;
-  custom_permissions_ = permissions;
+  custom_permissions_ = permissions.Pass();
   delegate_ = delegate;
   prompt_ = new Prompt(PERMISSIONS_PROMPT);
 
@@ -845,9 +845,10 @@
 }
 
 void ExtensionInstallPrompt::ShowConfirmation() {
-  scoped_refptr<const PermissionSet> permissions_to_display;
+  scoped_ptr<const PermissionSet> permissions_wrapper;
+  const PermissionSet* permissions_to_display = nullptr;
   if (custom_permissions_.get()) {
-    permissions_to_display = custom_permissions_;
+    permissions_to_display = custom_permissions_.get();
   } else if (extension_) {
     // Initialize permissions if they have not already been set so that
     // withheld permissions are displayed properly in the install prompt.
@@ -860,14 +861,15 @@
     // person who triggers the install, so add them to the list.
     if (prompt_->type() == DELEGATED_PERMISSIONS_PROMPT ||
         prompt_->type() == DELEGATED_BUNDLE_PERMISSIONS_PROMPT) {
-      scoped_refptr<const PermissionSet> optional_permissions =
+      const PermissionSet* optional_permissions =
           extensions::PermissionsParser::GetOptionalPermissions(extension_);
-      permissions_to_display = PermissionSet::CreateUnion(
-          *permissions_to_display, *optional_permissions);
+      permissions_wrapper = PermissionSet::CreateUnion(*permissions_to_display,
+                                                       *optional_permissions);
+      permissions_to_display = permissions_wrapper.get();
     }
   }
 
-  if (permissions_to_display.get() &&
+  if (permissions_to_display &&
       (!extension_ ||
        !extensions::PermissionsData::ShouldSkipPermissionWarnings(
            extension_->id()))) {
@@ -878,16 +880,16 @@
 
     prompt_->SetPermissions(message_provider->GetPermissionMessages(
                                 message_provider->GetAllPermissionIDs(
-                                    permissions_to_display.get(), type)),
+                                    permissions_to_display, type)),
                             REGULAR_PERMISSIONS);
 
-    scoped_refptr<const extensions::PermissionSet> withheld =
+    const PermissionSet* withheld =
         extension_ ? extension_->permissions_data()->withheld_permissions()
                    : nullptr;
     if (withheld && !withheld->IsEmpty()) {
       prompt_->SetPermissions(
           message_provider->GetPermissionMessages(
-              message_provider->GetAllPermissionIDs(withheld.get(), type)),
+              message_provider->GetAllPermissionIDs(withheld, type)),
           WITHHELD_PERMISSIONS);
     }
   }
diff --git a/chrome/browser/extensions/extension_install_prompt.h b/chrome/browser/extensions/extension_install_prompt.h
index 81edbec..f558877 100644
--- a/chrome/browser/extensions/extension_install_prompt.h
+++ b/chrome/browser/extensions/extension_install_prompt.h
@@ -309,7 +309,7 @@
   virtual void ConfirmBundleInstall(
       extensions::BundleInstaller* bundle,
       const SkBitmap* icon,
-      const extensions::PermissionSet* permissions);
+      scoped_ptr<const extensions::PermissionSet> permissions);
 
   // This is called by the bundle installer to verify the permissions for a
   // delegated bundle install.
@@ -319,7 +319,7 @@
       extensions::BundleInstaller* bundle,
       const std::string& delegated_username,
       const SkBitmap* icon,
-      const extensions::PermissionSet* permissions);
+      scoped_ptr<const extensions::PermissionSet> permissions);
 
   // This is called by the standalone installer to verify whether the install
   // from the webstore should proceed.
@@ -381,9 +381,10 @@
   // extension may be granted additional permissions.
   //
   // We *MUST* eventually call either Proceed() or Abort() on |delegate|.
-  virtual void ConfirmPermissions(Delegate* delegate,
-                                  const extensions::Extension* extension,
-                                  const extensions::PermissionSet* permissions);
+  virtual void ConfirmPermissions(
+      Delegate* delegate,
+      const extensions::Extension* extension,
+      scoped_ptr<const extensions::PermissionSet> permissions);
 
   // This is called by the app handler launcher to review what permissions the
   // extension or app currently has.
@@ -452,7 +453,7 @@
 
   // A custom set of permissions to show in the install prompt instead of the
   // extension's active permissions.
-  scoped_refptr<const extensions::PermissionSet> custom_permissions_;
+  scoped_ptr<const extensions::PermissionSet> custom_permissions_;
 
   // The object responsible for doing the UI specific actions.
   scoped_ptr<extensions::ExtensionInstallUI> install_ui_;
diff --git a/chrome/browser/extensions/extension_install_prompt_unittest.cc b/chrome/browser/extensions/extension_install_prompt_unittest.cc
index 31f7c86..8102a1f 100644
--- a/chrome/browser/extensions/extension_install_prompt_unittest.cc
+++ b/chrome/browser/extensions/extension_install_prompt_unittest.cc
@@ -42,9 +42,9 @@
   content::TestBrowserThreadBundle thread_bundle;
   APIPermissionSet api_permissions;
   api_permissions.insert(APIPermission::kTab);
-  scoped_refptr<const PermissionSet> permission_set =
+  scoped_ptr<const PermissionSet> permission_set(
       new PermissionSet(api_permissions, ManifestPermissionSet(),
-                        URLPatternSet(), URLPatternSet());
+                        URLPatternSet(), URLPatternSet()));
   scoped_refptr<const Extension> extension =
       ExtensionBuilder().SetManifest(
           DictionaryBuilder().Set("name", "foo")
@@ -59,8 +59,7 @@
                  1u,  // |regular_permissions_count|.
                  0u));  // |withheld_permissions_count|.
   prompt.ConfirmPermissions(nullptr,  // no delegate
-                            extension.get(),
-                            permission_set.get());
+                            extension.get(), permission_set.Pass());
   run_loop.Run();
 }
 
diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc
index 8e801ca..202a1bd 100644
--- a/chrome/browser/extensions/extension_management.cc
+++ b/chrome/browser/extensions/extension_management.cc
@@ -204,19 +204,19 @@
   return default_settings_->blocked_permissions;
 }
 
-scoped_refptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions(
+scoped_ptr<const PermissionSet> ExtensionManagement::GetBlockedPermissions(
     const Extension* extension) const {
   // Only api permissions are supported currently.
-  return scoped_refptr<const PermissionSet>(new PermissionSet(
+  return scoped_ptr<const PermissionSet>(new PermissionSet(
       GetBlockedAPIPermissions(extension), ManifestPermissionSet(),
       URLPatternSet(), URLPatternSet()));
 }
 
 bool ExtensionManagement::IsPermissionSetAllowed(
     const Extension* extension,
-    scoped_refptr<const PermissionSet> perms) const {
+    const PermissionSet& perms) const {
   for (const auto& blocked_api : GetBlockedAPIPermissions(extension)) {
-    if (perms->HasAPIPermission(blocked_api->id()))
+    if (perms.HasAPIPermission(blocked_api->id()))
       return false;
   }
   return true;
diff --git a/chrome/browser/extensions/extension_management.h b/chrome/browser/extensions/extension_management.h
index d3ebb94..291dcbc 100644
--- a/chrome/browser/extensions/extension_management.h
+++ b/chrome/browser/extensions/extension_management.h
@@ -114,12 +114,12 @@
   APIPermissionSet GetBlockedAPIPermissions(const Extension* extension) const;
 
   // Returns blocked permission set for |extension|.
-  scoped_refptr<const PermissionSet> GetBlockedPermissions(
+  scoped_ptr<const PermissionSet> GetBlockedPermissions(
       const Extension* extension) const;
 
   // Returns true if every permission in |perms| is allowed for |extension|.
   bool IsPermissionSetAllowed(const Extension* extension,
-                              scoped_refptr<const PermissionSet> perms) const;
+                              const PermissionSet& perms) const;
 
   // Returns true if |extension| meets the minimum required version set for it.
   // If there is no such requirement set for it, returns true as well.
diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc
index 2fb467fb..66e9c7a 100644
--- a/chrome/browser/extensions/extension_prefs_unittest.cc
+++ b/chrome/browser/extensions/extension_prefs_unittest.cc
@@ -208,32 +208,32 @@
     APIPermissionSet empty_set;
     ManifestPermissionSet empty_manifest_permissions;
     URLPatternSet empty_extent;
-    scoped_refptr<const PermissionSet> permissions;
-    scoped_refptr<const PermissionSet> granted_permissions;
 
     // Make sure both granted api and host permissions start empty.
-    granted_permissions =
-        prefs()->GetGrantedPermissions(extension_id_);
-    EXPECT_TRUE(granted_permissions->IsEmpty());
+    EXPECT_TRUE(prefs()->GetGrantedPermissions(extension_id_)->IsEmpty());
 
-    permissions = new PermissionSet(
-        api_perm_set1_, empty_manifest_permissions, empty_extent, empty_extent);
+    {
+      PermissionSet permissions(api_perm_set1_, empty_manifest_permissions,
+                                empty_extent, empty_extent);
 
     // Add part of the api permissions.
-    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
-    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
+    prefs()->AddGrantedPermissions(extension_id_, &permissions);
+    scoped_ptr<const PermissionSet> granted_permissions =
+        prefs()->GetGrantedPermissions(extension_id_);
     EXPECT_TRUE(granted_permissions.get());
     EXPECT_FALSE(granted_permissions->IsEmpty());
     EXPECT_EQ(expected_apis, granted_permissions->apis());
     EXPECT_TRUE(granted_permissions->effective_hosts().is_empty());
     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
-    granted_permissions = NULL;
+    }
 
+    {
     // Add part of the explicit host permissions.
-    permissions = new PermissionSet(
-        empty_set, empty_manifest_permissions, ehost_perm_set1_, empty_extent);
-    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
-    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
+    PermissionSet permissions(empty_set, empty_manifest_permissions,
+                              ehost_perm_set1_, empty_extent);
+    prefs()->AddGrantedPermissions(extension_id_, &permissions);
+    scoped_ptr<const PermissionSet> granted_permissions =
+        prefs()->GetGrantedPermissions(extension_id_);
     EXPECT_FALSE(granted_permissions->IsEmpty());
     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
     EXPECT_EQ(expected_apis, granted_permissions->apis());
@@ -241,12 +241,15 @@
               granted_permissions->explicit_hosts());
     EXPECT_EQ(ehost_perm_set1_,
               granted_permissions->effective_hosts());
+    }
 
+    {
     // Add part of the scriptable host permissions.
-    permissions = new PermissionSet(
-        empty_set, empty_manifest_permissions, empty_extent, shost_perm_set1_);
-    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
-    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
+    PermissionSet permissions(empty_set, empty_manifest_permissions,
+                              empty_extent, shost_perm_set1_);
+    prefs()->AddGrantedPermissions(extension_id_, &permissions);
+    scoped_ptr<const PermissionSet> granted_permissions =
+        prefs()->GetGrantedPermissions(extension_id_);
     EXPECT_FALSE(granted_permissions->IsEmpty());
     EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
     EXPECT_EQ(expected_apis, granted_permissions->apis());
@@ -258,16 +261,18 @@
     effective_permissions_ =
         URLPatternSet::CreateUnion(ehost_perm_set1_, shost_perm_set1_);
     EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
+    }
 
+    {
     // Add the rest of the permissions.
-    permissions = new PermissionSet(
-        api_perm_set2_, empty_manifest_permissions,
-        ehost_perm_set2_, shost_perm_set2_);
+    PermissionSet permissions(api_perm_set2_, empty_manifest_permissions,
+                              ehost_perm_set2_, shost_perm_set2_);
 
     APIPermissionSet::Union(expected_apis, api_perm_set2_, &api_permissions_);
 
-    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
-    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
+    prefs()->AddGrantedPermissions(extension_id_, &permissions);
+    scoped_ptr<const PermissionSet> granted_permissions =
+        prefs()->GetGrantedPermissions(extension_id_);
     EXPECT_TRUE(granted_permissions.get());
     EXPECT_FALSE(granted_permissions->IsEmpty());
     EXPECT_EQ(api_permissions_, granted_permissions->apis());
@@ -278,11 +283,12 @@
     effective_permissions_ =
         URLPatternSet::CreateUnion(ehost_permissions_, shost_permissions_);
     EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
+    }
   }
 
   void Verify() override {
-    scoped_refptr<const PermissionSet> permissions(
-        prefs()->GetGrantedPermissions(extension_id_));
+    scoped_ptr<const PermissionSet> permissions =
+        prefs()->GetGrantedPermissions(extension_id_);
     EXPECT_TRUE(permissions.get());
     EXPECT_FALSE(permissions->HasEffectiveFullAccess());
     EXPECT_EQ(api_permissions_, permissions->apis());
@@ -330,12 +336,12 @@
     AddPattern(&shosts, "https://*.google.com/*");
     AddPattern(&shosts, "http://reddit.com/r/test/*");
 
-    active_perms_ = new PermissionSet(
-        api_perms, empty_manifest_permissions, ehosts, shosts);
+    active_perms_.reset(new PermissionSet(api_perms, empty_manifest_permissions,
+                                          ehosts, shosts));
 
     // Make sure the active permissions start empty.
-    scoped_refptr<const PermissionSet> active(
-        prefs()->GetActivePermissions(extension_id_));
+    scoped_ptr<const PermissionSet> active =
+        prefs()->GetActivePermissions(extension_id_);
     EXPECT_TRUE(active->IsEmpty());
 
     // Set the active permissions.
@@ -348,14 +354,14 @@
   }
 
   void Verify() override {
-    scoped_refptr<const PermissionSet> permissions(
-        prefs()->GetActivePermissions(extension_id_));
+    scoped_ptr<const PermissionSet> permissions =
+        prefs()->GetActivePermissions(extension_id_);
     EXPECT_EQ(*active_perms_.get(), *permissions.get());
   }
 
  private:
   std::string extension_id_;
-  scoped_refptr<const PermissionSet> active_perms_;
+  scoped_ptr<const PermissionSet> active_perms_;
 };
 TEST_F(ExtensionPrefsActivePermissions, SetAndGetActivePermissions) {}
 
@@ -952,8 +958,8 @@
     URLPatternSet ehosts, shosts;
     AddPattern(&shosts, "chrome://print/*");
 
-    active_perms_ = new PermissionSet(api_perms, empty_manifest_permissions,
-                                      ehosts, shosts);
+    active_perms_.reset(new PermissionSet(api_perms, empty_manifest_permissions,
+                                          ehosts, shosts));
     // Set the active permissions.
     prefs()->SetActivePermissions(component_extension_->id(),
                                   active_perms_.get());
@@ -963,13 +969,13 @@
 
   void Verify() override {
     // Component extension can access chrome://print/*.
-    scoped_refptr<const PermissionSet> component_permissions(
-        prefs()->GetActivePermissions(component_extension_->id()));
+    scoped_ptr<const PermissionSet> component_permissions =
+        prefs()->GetActivePermissions(component_extension_->id());
     EXPECT_EQ(1u, component_permissions->scriptable_hosts().size());
 
     // Non Component extension can not access chrome://print/*.
-    scoped_refptr<const PermissionSet> no_component_permissions(
-        prefs()->GetActivePermissions(no_component_extension_->id()));
+    scoped_ptr<const PermissionSet> no_component_permissions =
+        prefs()->GetActivePermissions(no_component_extension_->id());
     EXPECT_EQ(0u, no_component_permissions->scriptable_hosts().size());
 
     // |URLPattern::SCHEME_CHROMEUI| scheme will be added in valid_schemes for
@@ -988,7 +994,7 @@
   }
 
  private:
-  scoped_refptr<const PermissionSet> active_perms_;
+  scoped_ptr<const PermissionSet> active_perms_;
   scoped_refptr<Extension> component_extension_;
   scoped_refptr<Extension> no_component_extension_;
 };
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 0f976b8..45ab9b6 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -1001,7 +1001,7 @@
 
   PermissionIDSet permissions =
       extensions::PermissionMessageProvider::Get()->GetAllPermissionIDs(
-          extension->permissions_data()->active_permissions().get(),
+          extension->permissions_data()->active_permissions(),
           extension->GetType());
   counter_has_any->AddBoolean(!permissions.empty());
   for (const PermissionID& id : permissions)
@@ -1602,7 +1602,7 @@
   if (extension->location() == Manifest::INTERNAL && !auto_grant_permission) {
     // Add all the recognized permissions if the granted permissions list
     // hasn't been initialized yet.
-    scoped_refptr<const PermissionSet> granted_permissions =
+    scoped_ptr<const PermissionSet> granted_permissions =
         extension_prefs_->GetGrantedPermissions(extension->id());
     CHECK(granted_permissions.get());
 
@@ -1613,7 +1613,7 @@
     is_privilege_increase =
         extensions::PermissionMessageProvider::Get()->IsPrivilegeIncrease(
             granted_permissions.get(),
-            extension->permissions_data()->active_permissions().get(),
+            extension->permissions_data()->active_permissions(),
             extension->GetType());
   }
 
@@ -1848,7 +1848,7 @@
   for (const auto& extension : *all_extensions.get()) {
     if (!settings->IsPermissionSetAllowed(
             extension.get(),
-            extension->permissions_data()->active_permissions())) {
+            *extension->permissions_data()->active_permissions())) {
       extensions::PermissionsUpdater(profile()).RemovePermissionsUnsafe(
           extension.get(),
           settings->GetBlockedPermissions(extension.get()).get());
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 68f9429..d40ebf1 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -792,10 +792,10 @@
   // set for extension |id|.
   void GrantAllOptionalPermissions(const std::string& id) {
     const Extension* extension = service()->GetInstalledExtension(id);
-    scoped_refptr<const PermissionSet> all_optional_permissions =
+    const PermissionSet* all_optional_permissions =
         extensions::PermissionsParser::GetOptionalPermissions(extension);
     extensions::PermissionsUpdater perms_updater(profile());
-    perms_updater.AddPermissions(extension, all_optional_permissions.get());
+    perms_updater.AddPermissions(extension, all_optional_permissions);
   }
 
   // Helper method to set up a WindowedNotificationObserver to wait for a
@@ -1851,9 +1851,7 @@
 
   // Make sure there aren't any granted permissions before the
   // extension is installed.
-  scoped_refptr<const PermissionSet> known_perms(
-      prefs->GetGrantedPermissions(permissions_crx));
-  EXPECT_FALSE(known_perms.get());
+  EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
 
   const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
 
@@ -1869,7 +1867,8 @@
   AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
   AddPattern(&expected_host_perms, "http://www.example.com/*");
 
-  known_perms = prefs->GetGrantedPermissions(extension->id());
+  scoped_ptr<const PermissionSet> known_perms =
+      prefs->GetGrantedPermissions(extension->id());
   EXPECT_TRUE(known_perms.get());
   EXPECT_FALSE(known_perms->IsEmpty());
   EXPECT_EQ(expected_api_perms, known_perms->apis());
@@ -1898,9 +1897,7 @@
 
   // Make sure there aren't any granted permissions before the
   // extension is installed.
-  scoped_refptr<const PermissionSet> known_perms(
-      prefs->GetGrantedPermissions(permissions_crx));
-  EXPECT_FALSE(known_perms.get());
+  EXPECT_FALSE(prefs->GetGrantedPermissions(permissions_crx).get());
 
   const Extension* extension = PackAndInstallCRX(
       path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
@@ -1912,7 +1909,8 @@
   // Verify that the valid API permissions have been recognized.
   expected_api_perms.insert(APIPermission::kTab);
 
-  known_perms = prefs->GetGrantedPermissions(extension->id());
+  scoped_ptr<const PermissionSet> known_perms =
+      prefs->GetGrantedPermissions(extension->id());
   EXPECT_TRUE(known_perms.get());
   EXPECT_FALSE(known_perms->IsEmpty());
   EXPECT_EQ(expected_api_perms, known_perms->apis());
@@ -1935,8 +1933,8 @@
   EXPECT_EQ(1u, registry()->enabled_extensions().size());
   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
 
-  scoped_refptr<const PermissionSet> permissions(
-      prefs->GetGrantedPermissions(extension->id()));
+  scoped_ptr<const PermissionSet> permissions =
+      prefs->GetGrantedPermissions(extension->id());
   EXPECT_FALSE(permissions->IsEmpty());
   EXPECT_TRUE(permissions->HasEffectiveFullAccess());
   EXPECT_FALSE(permissions->apis().empty());
@@ -1998,8 +1996,8 @@
   ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
   ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
 
-  scoped_refptr<const PermissionSet> current_perms(
-      prefs->GetGrantedPermissions(extension_id));
+  scoped_ptr<const PermissionSet> current_perms =
+      prefs->GetGrantedPermissions(extension_id);
   ASSERT_TRUE(current_perms.get());
   ASSERT_FALSE(current_perms->IsEmpty());
   ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
@@ -2893,8 +2891,8 @@
   EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
 
   // Make sure the granted permissions have been setup.
-  scoped_refptr<const PermissionSet> permissions(
-      ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
+  scoped_ptr<const PermissionSet> permissions =
+      ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1);
   EXPECT_FALSE(permissions->IsEmpty());
   EXPECT_TRUE(permissions->HasEffectiveFullAccess());
   EXPECT_FALSE(permissions->apis().empty());
@@ -4282,8 +4280,8 @@
   GrantAllOptionalPermissions(ext2);
   GrantAllOptionalPermissions(ext2_forced);
 
-  scoped_refptr<const PermissionSet> active_permissions(
-      ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
+  scoped_ptr<const PermissionSet> active_permissions =
+      ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
   EXPECT_TRUE(active_permissions->HasAPIPermission(
       extensions::APIPermission::kDownloads));
 
@@ -6616,8 +6614,8 @@
                                                            : DISABLED);
     EXPECT_EQ(test_case.expect_disable_reasons,
               prefs->GetDisableReasons(good_crx));
-    scoped_refptr<const PermissionSet> permissions(
-        prefs->GetGrantedPermissions(good_crx));
+    scoped_ptr<const PermissionSet> permissions =
+        prefs->GetGrantedPermissions(good_crx);
     EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
     ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
 
@@ -6961,8 +6959,8 @@
     }
     ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
 
-    scoped_refptr<const PermissionSet> granted_permissions_v1(
-        prefs->GetGrantedPermissions(id));
+    scoped_ptr<const PermissionSet> granted_permissions_v1 =
+        prefs->GetGrantedPermissions(id);
 
     // Update to a new version with increased permissions.
     UpdateExtension(id, crx_path_v2, DISABLED);
@@ -6978,8 +6976,8 @@
         id, Extension::DISABLE_PERMISSIONS_INCREASE));
 
     // No new permissions should have been granted.
-    scoped_refptr<const PermissionSet> granted_permissions_v2(
-        prefs->GetGrantedPermissions(id));
+    scoped_ptr<const PermissionSet> granted_permissions_v2 =
+        prefs->GetGrantedPermissions(id);
     ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
 
     // Now a sync update comes in.
@@ -7001,11 +6999,11 @@
 
     // Check expectations.
     EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
-    scoped_refptr<const PermissionSet> granted_permissions(
-        prefs->GetGrantedPermissions(id));
+    scoped_ptr<const PermissionSet> granted_permissions =
+        prefs->GetGrantedPermissions(id);
     if (test_case.expect_permissions_granted) {
-      scoped_refptr<const PermissionSet> active_permissions(
-          prefs->GetActivePermissions(id));
+      scoped_ptr<const PermissionSet> active_permissions =
+          prefs->GetActivePermissions(id);
       EXPECT_EQ(*granted_permissions, *active_permissions);
     } else {
       EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
diff --git a/chrome/browser/extensions/permission_messages_unittest.cc b/chrome/browser/extensions/permission_messages_unittest.cc
index 8f30990..be230e5 100644
--- a/chrome/browser/extensions/permission_messages_unittest.cc
+++ b/chrome/browser/extensions/permission_messages_unittest.cc
@@ -78,42 +78,40 @@
   // Returns the permission messages that would display in the prompt that
   // requests all the optional permissions for the current |app_|.
   std::vector<base::string16> GetOptionalPermissionMessages() {
-    scoped_refptr<const PermissionSet> granted_permissions =
+    scoped_ptr<const PermissionSet> granted_permissions =
         env_.GetExtensionPrefs()->GetGrantedPermissions(app_->id());
-    scoped_refptr<const PermissionSet> optional_permissions =
+    const PermissionSet* optional_permissions =
         PermissionsParser::GetOptionalPermissions(app_.get());
-    scoped_refptr<const PermissionSet> requested_permissions =
+    scoped_ptr<const PermissionSet> requested_permissions =
         PermissionSet::CreateDifference(*optional_permissions,
                                         *granted_permissions);
-    return GetMessages(requested_permissions);
+    return GetMessages(*requested_permissions);
   }
 
   void GrantOptionalPermissions() {
     PermissionsUpdater perms_updater(env_.profile());
     perms_updater.AddPermissions(
-        app_.get(),
-        PermissionsParser::GetOptionalPermissions(app_.get()).get());
+        app_.get(), PermissionsParser::GetOptionalPermissions(app_.get()));
   }
 
   std::vector<base::string16> active_permissions() {
-    return GetMessages(app_->permissions_data()->active_permissions());
+    return GetMessages(*app_->permissions_data()->active_permissions());
   }
 
   std::vector<base::string16> required_permissions() {
-    return GetMessages(PermissionsParser::GetRequiredPermissions(app_.get()));
+    return GetMessages(*PermissionsParser::GetRequiredPermissions(app_.get()));
   }
 
   std::vector<base::string16> optional_permissions() {
-    return GetMessages(PermissionsParser::GetOptionalPermissions(app_.get()));
+    return GetMessages(*PermissionsParser::GetOptionalPermissions(app_.get()));
   }
 
  private:
-  std::vector<base::string16> GetMessages(
-      scoped_refptr<const PermissionSet> permissions) {
+  std::vector<base::string16> GetMessages(const PermissionSet& permissions) {
     std::vector<base::string16> messages;
     for (const PermissionMessage& msg :
          message_provider_->GetPermissionMessages(
-             message_provider_->GetAllPermissionIDs(permissions.get(),
+             message_provider_->GetAllPermissionIDs(&permissions,
                                                     app_->GetType()))) {
       messages.push_back(msg.message());
     }
diff --git a/chrome/browser/extensions/permissions_based_management_policy_provider.cc b/chrome/browser/extensions/permissions_based_management_policy_provider.cc
index 57fa45aa..4b4094e 100644
--- a/chrome/browser/extensions/permissions_based_management_policy_provider.cc
+++ b/chrome/browser/extensions/permissions_based_management_policy_provider.cc
@@ -41,10 +41,10 @@
   if (Manifest::IsComponentLocation(extension->location()))
     return true;
 
-  scoped_refptr<const PermissionSet> required_permissions =
+  const PermissionSet* required_permissions =
       PermissionsParser::GetRequiredPermissions(extension);
 
-  if (!settings_->IsPermissionSetAllowed(extension, required_permissions)) {
+  if (!settings_->IsPermissionSetAllowed(extension, *required_permissions)) {
     if (error) {
       *error =
           l10n_util::GetStringFUTF16(IDS_EXTENSION_CANT_INSTALL_POLICY_BLOCKED,
diff --git a/chrome/browser/extensions/permissions_updater.cc b/chrome/browser/extensions/permissions_updater.cc
index b133cc5..2505836 100644
--- a/chrome/browser/extensions/permissions_updater.cc
+++ b/chrome/browser/extensions/permissions_updater.cc
@@ -59,29 +59,29 @@
 
 // Returns a PermissionSet that has the active permissions of the extension,
 // bounded to its current manifest.
-scoped_refptr<const PermissionSet> GetBoundedActivePermissions(
+scoped_ptr<const PermissionSet> GetBoundedActivePermissions(
     const Extension* extension,
-    const scoped_refptr<const PermissionSet>& active_permissions) {
+    const PermissionSet* active_permissions) {
   // If the extension has used the optional permissions API, it will have a
   // custom set of active permissions defined in the extension prefs. Here,
   // we update the extension's active permissions based on the prefs.
-  if (!active_permissions.get())
-    return extension->permissions_data()->active_permissions();
+  if (!active_permissions)
+    return extension->permissions_data()->active_permissions()->Clone();
 
-  scoped_refptr<const PermissionSet> required_permissions =
+  const PermissionSet* required_permissions =
       PermissionsParser::GetRequiredPermissions(extension);
 
   // We restrict the active permissions to be within the bounds defined in the
   // extension's manifest.
   //  a) active permissions must be a subset of optional + default permissions
   //  b) active permissions must contains all default permissions
-  scoped_refptr<const PermissionSet> total_permissions =
+  scoped_ptr<const PermissionSet> total_permissions =
       PermissionSet::CreateUnion(
           *required_permissions,
           *PermissionsParser::GetOptionalPermissions(extension));
 
   // Make sure the active permissions contain no more than optional + default.
-  scoped_refptr<const PermissionSet> adjusted_active =
+  scoped_ptr<const PermissionSet> adjusted_active =
       PermissionSet::CreateIntersection(*total_permissions,
                                         *active_permissions);
 
@@ -124,19 +124,19 @@
 
 void PermissionsUpdater::AddPermissions(
     const Extension* extension, const PermissionSet* permissions) {
-  scoped_refptr<const PermissionSet> active(
+  const PermissionSet* active(
       extension->permissions_data()->active_permissions());
-  scoped_refptr<const PermissionSet> total(
-      PermissionSet::CreateUnion(*active, *permissions));
-  scoped_refptr<const PermissionSet> added(
-      PermissionSet::CreateDifference(*total, *active));
+  scoped_ptr<const PermissionSet> total =
+      PermissionSet::CreateUnion(*active, *permissions);
+  scoped_ptr<const PermissionSet> added =
+      PermissionSet::CreateDifference(*total, *active);
 
-  SetPermissions(extension, total, nullptr);
+  SetPermissions(extension, total.Pass(), nullptr);
 
   // Update the granted permissions so we don't auto-disable the extension.
   GrantActivePermissions(extension);
 
-  NotifyPermissionsUpdated(ADDED, extension, added.get());
+  NotifyPermissionsUpdated(ADDED, extension, *added);
 }
 
 void PermissionsUpdater::RemovePermissions(const Extension* extension,
@@ -145,23 +145,23 @@
   // We should only be revoking revokable permissions.
   CHECK(GetRevokablePermissions(extension)->Contains(*to_remove));
 
-  scoped_refptr<const PermissionSet> active(
-      extension->permissions_data()->active_permissions());
-  scoped_refptr<const PermissionSet> remaining(
-      PermissionSet::CreateDifference(*active, *to_remove));
+  const PermissionSet* active =
+      extension->permissions_data()->active_permissions();
+  scoped_ptr<const PermissionSet> remaining =
+      PermissionSet::CreateDifference(*active, *to_remove);
 
   // Move any granted permissions that were in the withheld set back to the
   // withheld set so they can be added back later.
   // Any revoked permission that isn't from the optional permissions can only
   // be a withheld permission.
-  scoped_refptr<const PermissionSet> removed_withheld =
+  scoped_ptr<const PermissionSet> removed_withheld =
       PermissionSet::CreateDifference(
           *to_remove, *PermissionsParser::GetOptionalPermissions(extension));
-  scoped_refptr<const PermissionSet> withheld = PermissionSet::CreateUnion(
+  scoped_ptr<const PermissionSet> withheld = PermissionSet::CreateUnion(
       *removed_withheld,
       *extension->permissions_data()->withheld_permissions());
 
-  SetPermissions(extension, remaining, withheld);
+  SetPermissions(extension, remaining.Pass(), withheld.Pass());
 
   // We might not want to revoke the granted permissions because the extension,
   // not the user, removed the permissions. This allows the extension to add
@@ -171,36 +171,37 @@
         ->RemoveGrantedPermissions(extension->id(), to_remove);
   }
 
-  NotifyPermissionsUpdated(REMOVED, extension, to_remove);
+  NotifyPermissionsUpdated(REMOVED, extension, *to_remove);
 }
 
 void PermissionsUpdater::RemovePermissionsUnsafe(
     const Extension* extension,
     const PermissionSet* to_remove) {
-  scoped_refptr<const PermissionSet> active(
-      extension->permissions_data()->active_permissions());
-  scoped_refptr<const PermissionSet> total(
-      PermissionSet::CreateDifference(*active, *to_remove));
+  const PermissionSet* active =
+      extension->permissions_data()->active_permissions();
+  scoped_ptr<const PermissionSet> total =
+      PermissionSet::CreateDifference(*active, *to_remove);
   // |successfully_removed| might not equal |to_remove| if |to_remove| contains
   // permissions the extension didn't have.
-  scoped_refptr<const PermissionSet> successfully_removed(
-      PermissionSet::CreateDifference(*active, *total));
+  scoped_ptr<const PermissionSet> successfully_removed =
+      PermissionSet::CreateDifference(*active, *total);
 
-  SetPermissions(extension, total, nullptr);
-  NotifyPermissionsUpdated(REMOVED, extension, successfully_removed.get());
+  SetPermissions(extension, total.Pass(), nullptr);
+  NotifyPermissionsUpdated(REMOVED, extension, *successfully_removed);
 }
 
-scoped_refptr<const PermissionSet> PermissionsUpdater::GetRevokablePermissions(
+scoped_ptr<const PermissionSet> PermissionsUpdater::GetRevokablePermissions(
     const Extension* extension) const {
   // Optional permissions are revokable.
-  scoped_refptr<const PermissionSet> revokable_permissions =
+  scoped_ptr<const PermissionSet> wrapper;
+  const PermissionSet* revokable_permissions =
       PermissionsParser::GetOptionalPermissions(extension);
-  scoped_refptr<const PermissionSet> active_permissions =
+  const PermissionSet* active_permissions =
       extension->permissions_data()->active_permissions();
   // If click-to-script is enabled, then any hosts that are granted, but not
   // listed explicitly as a required permission, are also revokable.
   if (FeatureSwitch::scripts_require_action()->IsEnabled()) {
-    scoped_refptr<const PermissionSet> required_permissions =
+    const PermissionSet* required_permissions =
         PermissionsParser::GetRequiredPermissions(extension);
     auto find_revokable_hosts = [](const URLPatternSet& active_hosts,
                                    const URLPatternSet& required_hosts) {
@@ -219,42 +220,51 @@
     URLPatternSet revokable_scriptable_hosts =
         find_revokable_hosts(active_permissions->scriptable_hosts(),
                              required_permissions->scriptable_hosts());
-    scoped_refptr<const PermissionSet> revokable_host_permissions =
+    scoped_ptr<const PermissionSet> revokable_host_permissions(
         new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
-                          revokable_explicit_hosts, revokable_scriptable_hosts);
-    revokable_permissions = PermissionSet::CreateUnion(
-        *revokable_permissions, *revokable_host_permissions);
+                          revokable_explicit_hosts,
+                          revokable_scriptable_hosts));
+    wrapper = PermissionSet::CreateUnion(*revokable_permissions,
+                                         *revokable_host_permissions);
+    revokable_permissions = wrapper.get();
   }
-  return scoped_refptr<const PermissionSet>(PermissionSet::CreateIntersection(
-      *active_permissions, *revokable_permissions));
+  return PermissionSet::CreateIntersection(*active_permissions,
+                                           *revokable_permissions);
 }
 
 void PermissionsUpdater::GrantActivePermissions(const Extension* extension) {
   CHECK(extension);
 
-  ExtensionPrefs::Get(browser_context_)->AddGrantedPermissions(
-      extension->id(),
-      extension->permissions_data()->active_permissions().get());
+  ExtensionPrefs::Get(browser_context_)
+      ->AddGrantedPermissions(
+          extension->id(), extension->permissions_data()->active_permissions());
 }
 
 void PermissionsUpdater::InitializePermissions(const Extension* extension) {
-  scoped_refptr<const PermissionSet> active_permissions(NULL);
-  scoped_refptr<const PermissionSet> bounded_active(NULL);
+  scoped_ptr<const PermissionSet> active_wrapper;
+  scoped_ptr<const PermissionSet> bounded_wrapper;
+  const PermissionSet* active_permissions = nullptr;
+  const PermissionSet* bounded_active = nullptr;
   // If |extension| is a transient dummy extension, we do not want to look for
   // it in preferences.
   if (init_flag_ & INIT_FLAG_TRANSIENT) {
-    bounded_active = active_permissions =
+    active_permissions = bounded_active =
         extension->permissions_data()->active_permissions();
   } else {
-    active_permissions = ExtensionPrefs::Get(browser_context_)
-                             ->GetActivePermissions(extension->id());
-    bounded_active = GetBoundedActivePermissions(extension, active_permissions);
+    // As part of initializing permissions, we restrict access to the main
+    // thread.
+    active_wrapper = ExtensionPrefs::Get(browser_context_)
+                         ->GetActivePermissions(extension->id());
+    active_permissions = active_wrapper.get();
+    bounded_wrapper =
+        GetBoundedActivePermissions(extension, active_permissions);
+    bounded_active = bounded_wrapper.get();
   }
 
   // Determine whether or not to withhold host permissions.
   bool should_withhold_permissions = false;
-  if (PermissionsData::ScriptsMayRequireActionForExtension(
-          extension, bounded_active.get())) {
+  if (PermissionsData::ScriptsMayRequireActionForExtension(extension,
+                                                           bounded_active)) {
     should_withhold_permissions =
         init_flag_ & INIT_FLAG_TRANSIENT ?
             !util::DefaultAllowedScriptingOnAllUrls() :
@@ -280,7 +290,7 @@
   // For example, the union of <all_urls> and "example.com" is <all_urls>, so
   // we may lose "example.com". However, "example.com" is important once
   // <all_urls> is stripped during withholding.
-  if (active_permissions.get()) {
+  if (active_permissions) {
     granted_explicit_hosts.AddPatterns(
         FilterSingleOriginPermissions(active_permissions->explicit_hosts(),
                                       bounded_active->explicit_hosts()));
@@ -289,23 +299,20 @@
                                       bounded_active->scriptable_hosts()));
   }
 
-  bounded_active = new PermissionSet(bounded_active->apis(),
-                                     bounded_active->manifest_permissions(),
-                                     granted_explicit_hosts,
-                                     granted_scriptable_hosts);
+  scoped_ptr<const PermissionSet> new_permissions(new PermissionSet(
+      bounded_active->apis(), bounded_active->manifest_permissions(),
+      granted_explicit_hosts, granted_scriptable_hosts));
 
-  scoped_refptr<const PermissionSet> withheld =
-      new PermissionSet(APIPermissionSet(),
-                        ManifestPermissionSet(),
-                        withheld_explicit_hosts,
-                        withheld_scriptable_hosts);
-  SetPermissions(extension, bounded_active, withheld);
+  scoped_ptr<const PermissionSet> withheld(
+      new PermissionSet(APIPermissionSet(), ManifestPermissionSet(),
+                        withheld_explicit_hosts, withheld_scriptable_hosts));
+  SetPermissions(extension, new_permissions.Pass(), withheld.Pass());
 }
 
 void PermissionsUpdater::WithholdImpliedAllHosts(const Extension* extension) {
-  scoped_refptr<const PermissionSet> active =
+  const PermissionSet* active =
       extension->permissions_data()->active_permissions();
-  scoped_refptr<const PermissionSet> withheld =
+  const PermissionSet* withheld =
       extension->permissions_data()->withheld_permissions();
 
   URLPatternSet withheld_scriptable = withheld->scriptable_hosts();
@@ -327,29 +334,24 @@
   URLPatternSet delta_scriptable = URLPatternSet::CreateDifference(
       active->scriptable_hosts(), active_scriptable);
 
-  SetPermissions(extension,
-                 new PermissionSet(active->apis(),
-                                   active->manifest_permissions(),
-                                   active_explicit,
-                                   active_scriptable),
-                 new PermissionSet(withheld->apis(),
-                                   withheld->manifest_permissions(),
-                                   withheld_explicit,
-                                   withheld_scriptable));
+  SetPermissions(extension, make_scoped_ptr(new PermissionSet(
+                                active->apis(), active->manifest_permissions(),
+                                active_explicit, active_scriptable)),
+                 make_scoped_ptr(new PermissionSet(
+                     withheld->apis(), withheld->manifest_permissions(),
+                     withheld_explicit, withheld_scriptable)));
 
-  scoped_refptr<const PermissionSet> delta(new PermissionSet(
-      APIPermissionSet(),
-      ManifestPermissionSet(),
-      delta_explicit,
-      delta_scriptable));
-  NotifyPermissionsUpdated(REMOVED, extension, delta.get());
+  NotifyPermissionsUpdated(
+      REMOVED, extension,
+      PermissionSet(APIPermissionSet(), ManifestPermissionSet(), delta_explicit,
+                    delta_scriptable));
 }
 
 void PermissionsUpdater::GrantWithheldImpliedAllHosts(
     const Extension* extension) {
-  scoped_refptr<const PermissionSet> active =
+  const PermissionSet* active =
       extension->permissions_data()->active_permissions();
-  scoped_refptr<const PermissionSet> withheld =
+  const PermissionSet* withheld =
       extension->permissions_data()->withheld_permissions();
 
   // Move the all-hosts permission from withheld to active.
@@ -368,31 +370,33 @@
 
   // Since we only withhold host permissions (so far), we know that withheld
   // permissions will be empty.
-  SetPermissions(extension,
-                 new PermissionSet(active->apis(),
-                                   active->manifest_permissions(),
-                                   explicit_hosts,
-                                   scriptable_hosts),
-                 new PermissionSet());
+  SetPermissions(extension, make_scoped_ptr(new PermissionSet(
+                                active->apis(), active->manifest_permissions(),
+                                explicit_hosts, scriptable_hosts)),
+                 make_scoped_ptr(new PermissionSet()));
 
-  scoped_refptr<const PermissionSet> delta(new PermissionSet(
-      APIPermissionSet(),
-      ManifestPermissionSet(),
-      delta_explicit,
-      delta_scriptable));
-  NotifyPermissionsUpdated(ADDED, extension, delta.get());
+  NotifyPermissionsUpdated(
+      ADDED, extension,
+      PermissionSet(APIPermissionSet(), ManifestPermissionSet(), delta_explicit,
+                    delta_scriptable));
 }
 
 void PermissionsUpdater::SetPermissions(
     const Extension* extension,
-    const scoped_refptr<const PermissionSet>& active,
-    scoped_refptr<const PermissionSet> withheld) {
-  withheld = withheld.get() ? withheld
-                 : extension->permissions_data()->withheld_permissions();
-  extension->permissions_data()->SetPermissions(active, withheld);
+    scoped_ptr<const PermissionSet> active,
+    scoped_ptr<const PermissionSet> withheld) {
+  DCHECK(active);
+  const PermissionSet* active_weak = active.get();
+  if (withheld) {
+    extension->permissions_data()->SetPermissions(active.Pass(),
+                                                  withheld.Pass());
+  } else {
+    extension->permissions_data()->SetActivePermissions(active.Pass());
+  }
+
   if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) {
     ExtensionPrefs::Get(browser_context_)
-        ->SetActivePermissions(extension->id(), active.get());
+        ->SetActivePermissions(extension->id(), active_weak);
   }
 }
 
@@ -400,14 +404,14 @@
     const std::string& extension_id,
     events::HistogramValue histogram_value,
     const char* event_name,
-    const PermissionSet* changed_permissions) {
+    const PermissionSet& changed_permissions) {
   EventRouter* event_router = EventRouter::Get(browser_context_);
   if (!event_router)
     return;
 
   scoped_ptr<base::ListValue> value(new base::ListValue());
   scoped_ptr<api::permissions::Permissions> permissions =
-      PackPermissionSet(changed_permissions);
+      PackPermissionSet(&changed_permissions);
   value->Append(permissions->ToValue().release());
   scoped_ptr<Event> event(new Event(histogram_value, event_name, value.Pass()));
   event->restrict_to_browser_context = browser_context_;
@@ -417,9 +421,9 @@
 void PermissionsUpdater::NotifyPermissionsUpdated(
     EventType event_type,
     const Extension* extension,
-    const PermissionSet* changed) {
+    const PermissionSet& changed) {
   DCHECK((init_flag_ & INIT_FLAG_TRANSIENT) == 0);
-  if (!changed || changed->IsEmpty())
+  if (changed.IsEmpty())
     return;
 
   UpdatedExtensionPermissionsInfo::Reason reason;
diff --git a/chrome/browser/extensions/permissions_updater.h b/chrome/browser/extensions/permissions_updater.h
index aab225a..c7b1628 100644
--- a/chrome/browser/extensions/permissions_updater.h
+++ b/chrome/browser/extensions/permissions_updater.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
 #include "extensions/browser/extension_event_histogram_value.h"
 
 namespace base {
@@ -69,7 +69,7 @@
                                const PermissionSet* permissions);
 
   // Returns the set of revokable permissions.
-  scoped_refptr<const PermissionSet> GetRevokablePermissions(
+  scoped_ptr<const PermissionSet> GetRevokablePermissions(
       const Extension* extension) const;
 
   // Adds all permissions in the |extension|'s active permissions to its
@@ -98,14 +98,14 @@
   // withheld permissions to |withheld|. Otherwise, |withheld| permissions are
   // not changed.
   void SetPermissions(const Extension* extension,
-                      const scoped_refptr<const PermissionSet>& active,
-                      scoped_refptr<const PermissionSet> withheld);
+                      scoped_ptr<const PermissionSet> active,
+                      scoped_ptr<const PermissionSet> withheld);
 
   // Dispatches specified event to the extension.
   void DispatchEvent(const std::string& extension_id,
                      events::HistogramValue histogram_value,
                      const char* event_name,
-                     const PermissionSet* changed_permissions);
+                     const PermissionSet& changed_permissions);
 
   // Issues the relevant events, messages and notifications when the
   // |extension|'s permissions have |changed| (|changed| is the delta).
@@ -114,7 +114,7 @@
   // onAdded/onRemoved events in the extension.
   void NotifyPermissionsUpdated(EventType event_type,
                                 const Extension* extension,
-                                const PermissionSet* changed);
+                                const PermissionSet& changed);
 
   // The associated BrowserContext.
   content::BrowserContext* browser_context_;
@@ -122,6 +122,8 @@
   // Initialization flag that determines whether prefs is consulted about the
   // extension. Transient extensions should not have entries in prefs.
   InitFlag init_flag_;
+
+  DISALLOW_COPY_AND_ASSIGN(PermissionsUpdater);
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc
index 4621b9ce..26684581 100644
--- a/chrome/browser/extensions/permissions_updater_unittest.cc
+++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -156,7 +156,7 @@
         content::Details<UpdatedExtensionPermissionsInfo>(details).ptr();
 
     extension_ = info->extension;
-    permissions_ = info->permissions;
+    permissions_ = info->permissions.Clone();
     reason_ = info->reason;
 
     if (waiting_) {
@@ -169,7 +169,7 @@
   bool waiting_;
   content::NotificationRegistrar registrar_;
   scoped_refptr<const Extension> extension_;
-  scoped_refptr<const PermissionSet> permissions_;
+  scoped_ptr<const PermissionSet> permissions_;
   UpdatedExtensionPermissionsInfo::Reason reason_;
 };
 
@@ -210,14 +210,16 @@
 
   URLPatternSet default_hosts;
   AddPattern(&default_hosts, "http://a.com/*");
-  scoped_refptr<const PermissionSet> default_permissions = new PermissionSet(
-      default_apis, empty_manifest_permissions, default_hosts, URLPatternSet());
+  PermissionSet default_permissions(default_apis, empty_manifest_permissions,
+                                    default_hosts, URLPatternSet());
 
   // Make sure it loaded properly.
-  scoped_refptr<const PermissionSet> permissions =
-      extension->permissions_data()->active_permissions();
-  ASSERT_EQ(*default_permissions.get(),
-            *extension->permissions_data()->active_permissions().get());
+  ASSERT_EQ(default_permissions,
+            *extension->permissions_data()->active_permissions());
+
+  ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_.get());
+  scoped_ptr<const PermissionSet> active_permissions;
+  scoped_ptr<const PermissionSet> granted_permissions;
 
   // Add a few permissions.
   APIPermissionSet apis;
@@ -225,12 +227,12 @@
   URLPatternSet hosts;
   AddPattern(&hosts, "http://*.c.com/*");
 
-  scoped_refptr<const PermissionSet> delta = new PermissionSet(
-      apis, empty_manifest_permissions, hosts, URLPatternSet());
+  {
+    PermissionSet delta(apis, empty_manifest_permissions, hosts,
+                        URLPatternSet());
 
   PermissionsUpdaterListener listener;
-  PermissionsUpdater updater(profile_.get());
-  updater.AddPermissions(extension.get(), delta.get());
+  PermissionsUpdater(profile_.get()).AddPermissions(extension.get(), &delta);
 
   listener.Wait();
 
@@ -238,57 +240,54 @@
   ASSERT_TRUE(listener.received_notification());
   ASSERT_EQ(extension.get(), listener.extension());
   ASSERT_EQ(UpdatedExtensionPermissionsInfo::ADDED, listener.reason());
-  ASSERT_EQ(*delta.get(), *listener.permissions());
+  ASSERT_EQ(delta, *listener.permissions());
 
   // Make sure the extension's active permissions reflect the change.
-  scoped_refptr<const PermissionSet> active_permissions =
-      PermissionSet::CreateUnion(*default_permissions, *delta);
+  active_permissions = PermissionSet::CreateUnion(default_permissions, delta);
   ASSERT_EQ(*active_permissions.get(),
-            *extension->permissions_data()->active_permissions().get());
+            *extension->permissions_data()->active_permissions());
 
   // 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 = ExtensionPrefs::Get(profile_.get());
-  scoped_refptr<const PermissionSet> granted_permissions = active_permissions;
+  ASSERT_EQ(*active_permissions.get(),
+            *prefs->GetActivePermissions(extension->id()));
+  granted_permissions = active_permissions->Clone();
+  ASSERT_EQ(*granted_permissions,
+            *prefs->GetGrantedPermissions(extension->id()));
+  }
 
-  scoped_refptr<const PermissionSet> from_prefs =
-      prefs->GetActivePermissions(extension->id());
-  ASSERT_EQ(*active_permissions.get(), *from_prefs.get());
-
-  from_prefs = prefs->GetGrantedPermissions(extension->id());
-  ASSERT_EQ(*active_permissions.get(), *from_prefs.get());
-
+  {
   // In the second part of the test, we'll remove the permissions that we
   // just added except for 'notifications'.
   apis.erase(APIPermission::kNotifications);
-  delta = new PermissionSet(apis, empty_manifest_permissions,
-                            hosts, URLPatternSet());
+  PermissionSet delta(apis, empty_manifest_permissions, hosts, URLPatternSet());
 
-  listener.Reset();
-  updater.RemovePermissions(extension.get(), delta.get(),
-                            PermissionsUpdater::REMOVE_SOFT);
+  PermissionsUpdaterListener listener;
+  PermissionsUpdater(profile_.get())
+      .RemovePermissions(extension.get(), &delta,
+                         PermissionsUpdater::REMOVE_SOFT);
   listener.Wait();
 
   // Verify that the notification was correct.
   ASSERT_TRUE(listener.received_notification());
   ASSERT_EQ(extension.get(), listener.extension());
   ASSERT_EQ(UpdatedExtensionPermissionsInfo::REMOVED, listener.reason());
-  ASSERT_EQ(*delta.get(), *listener.permissions());
+  ASSERT_EQ(delta, *listener.permissions());
 
   // Make sure the extension's active permissions reflect the change.
   active_permissions =
-      PermissionSet::CreateDifference(*active_permissions, *delta);
+      PermissionSet::CreateDifference(*active_permissions, delta);
   ASSERT_EQ(*active_permissions.get(),
-            *extension->permissions_data()->active_permissions().get());
+            *extension->permissions_data()->active_permissions());
 
   // 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.get(), *from_prefs.get());
+  ASSERT_EQ(*active_permissions, *prefs->GetActivePermissions(extension->id()));
 
-  from_prefs = prefs->GetGrantedPermissions(extension->id());
-  ASSERT_EQ(*granted_permissions.get(), *from_prefs.get());
+  ASSERT_EQ(*granted_permissions,
+            *prefs->GetGrantedPermissions(extension->id()));
+  }
 }
 
 TEST_F(PermissionsUpdaterTest, WithholdAllHosts) {
@@ -495,15 +494,15 @@
   auto api_permission_set = [](APIPermission::ID id) {
     APIPermissionSet apis;
     apis.insert(id);
-    return make_scoped_refptr(new PermissionSet(
-        apis, ManifestPermissionSet(), URLPatternSet(), URLPatternSet()));
+    return make_scoped_ptr(new PermissionSet(apis, ManifestPermissionSet(),
+                                             URLPatternSet(), URLPatternSet()));
   };
 
   auto url_permission_set = [](const GURL& url) {
     URLPatternSet set;
     URLPattern pattern(URLPattern::SCHEME_ALL, url.spec());
     set.AddPattern(pattern);
-    return make_scoped_refptr(new PermissionSet(
+    return make_scoped_ptr(new PermissionSet(
         APIPermissionSet(), ManifestPermissionSet(), set, URLPatternSet()));
   };
 
@@ -529,7 +528,7 @@
     // its granted permissions (stored in prefs). And, the permission should
     // be revokable.
     EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kCookie));
-    scoped_refptr<const PermissionSet> granted_permissions =
+    scoped_ptr<const PermissionSet> granted_permissions =
         prefs->GetGrantedPermissions(extension->id());
     EXPECT_TRUE(granted_permissions->HasAPIPermission(APIPermission::kCookie));
     EXPECT_TRUE(updater.GetRevokablePermissions(extension.get())
diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc
index 6fd2f9b..b880874 100644
--- a/chrome/browser/extensions/unpacked_installer.cc
+++ b/chrome/browser/extensions/unpacked_installer.cc
@@ -29,6 +29,7 @@
 #include "extensions/common/file_util.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/manifest_handlers/shared_module_info.h"
+#include "extensions/common/permissions/permissions_data.h"
 #include "sync/api/string_ordinal.h"
 
 using content::BrowserThread;
@@ -168,6 +169,7 @@
     return false;
   }
 
+  extension()->permissions_data()->BindToCurrentThread();
   PermissionsUpdater(
       service_weak_->profile(), PermissionsUpdater::INIT_FLAG_TRANSIENT)
       .InitializePermissions(extension());
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc
index 67629be..cf0bdfa8 100644
--- a/chrome/browser/themes/theme_syncable_service_unittest.cc
+++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -189,11 +189,10 @@
     extensions::APIPermissionSet empty_set;
     extensions::ManifestPermissionSet empty_manifest_permissions;
     extensions::URLPatternSet empty_extent;
-    scoped_refptr<extensions::PermissionSet> permissions =
-        new extensions::PermissionSet(empty_set, empty_manifest_permissions,
-                                      empty_extent, empty_extent);
+    extensions::PermissionSet permissions(empty_set, empty_manifest_permissions,
+                                          empty_extent, empty_extent);
     extensions::ExtensionPrefs::Get(profile_.get())
-        ->AddGrantedPermissions(theme_extension_->id(), permissions.get());
+        ->AddGrantedPermissions(theme_extension_->id(), &permissions);
     service->AddExtension(theme_extension_.get());
     extensions::ExtensionRegistry* registry =
         extensions::ExtensionRegistry::Get(profile_.get());
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
index 52516c3..5e7f279 100644
--- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
+++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -212,16 +212,17 @@
       CreateExtension("web store",
                       extensions::kWebStoreAppId,
                       extensions::Manifest::COMPONENT);
-  extensions::ExtensionPrefs::Get(profile_.get())->AddGrantedPermissions(
-      webstore->id(), make_scoped_refptr(new extensions::PermissionSet).get());
+  extensions::PermissionSet empty_permissions;
+  extensions::ExtensionPrefs::Get(profile_.get())
+      ->AddGrantedPermissions(webstore->id(), &empty_permissions);
   extensions->AddExtension(webstore.get());
   EXPECT_FALSE(GetCallbackResult(
       base::Bind(&ui::CheckShouldPromptForNewProfile, profile_.get())));
 
   scoped_refptr<extensions::Extension> extension =
       CreateExtension("foo", std::string(), extensions::Manifest::INTERNAL);
-  extensions::ExtensionPrefs::Get(profile_.get())->AddGrantedPermissions(
-      extension->id(), make_scoped_refptr(new extensions::PermissionSet).get());
+  extensions::ExtensionPrefs::Get(profile_.get())
+      ->AddGrantedPermissions(extension->id(), &empty_permissions);
   extensions->AddExtension(extension.get());
   EXPECT_TRUE(GetCallbackResult(
       base::Bind(&ui::CheckShouldPromptForNewProfile, profile_.get())));