Chromium Code Reviews| Index: extensions/common/permissions/permissions_data.h |
| diff --git a/extensions/common/permissions/permissions_data.h b/extensions/common/permissions/permissions_data.h |
| index 43be869029d784ff470ae8db08d9ae3ce46fcd1c..585145da276c1011626c8b70257e593769df38e4 100644 |
| --- a/extensions/common/permissions/permissions_data.h |
| +++ b/extensions/common/permissions/permissions_data.h |
| @@ -9,6 +9,7 @@ |
| #include <string> |
| #include <vector> |
| +#include "base/containers/scoped_ptr_map.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/strings/string16.h" |
| #include "base/synchronization/lock.h" |
| @@ -19,12 +20,22 @@ |
| class GURL; |
| +namespace base { |
| +class ThreadChecker; |
| +} |
| + |
| namespace extensions { |
| class Extension; |
| class URLPatternSet; |
| // A container for the permissions state of an extension, including active, |
| // withheld, and tab-specific permissions. |
| +// Thread-Safety: Since this is an object on the Extension object, *some* thread |
| +// safety is provided. All utility functions for checking if a permission is |
| +// present or an operation is allowed are thread-safe. However, permissions can |
| +// only be set (or updated) on the thread on which this object was created. |
|
not at google - send to devlin
2015/09/22 21:51:26
Why is this? Just for sanity checking? Because you
Devlin
2015/09/22 22:08:45
So this is (one of the) fun parts. We lock, but w
not at google - send to devlin
2015/09/22 22:32:58
I see.
So to say it in a more general way, to mak
|
| +// Permissions may be accessed synchronously on that same thread. |
| +// Accessing on an improper thread will CHECK(). |
|
not at google - send to devlin
2015/09/22 21:51:26
Brave!
Honestly I'd make this (all instances) a D
Devlin
2015/09/23 17:09:00
Done.
|
| class PermissionsData { |
| public: |
| // The possible types of access for a given frame. |
| @@ -35,7 +46,8 @@ class PermissionsData { |
| // the given page. |
| }; |
| - using TabPermissionsMap = std::map<int, scoped_refptr<const PermissionSet>>; |
| + using TabPermissionsMap = |
| + base::ScopedPtrMap<int, scoped_ptr<const PermissionSet>>; |
| // Delegate class to allow different contexts (e.g. browser vs renderer) to |
| // have control over policy decisions. |
| @@ -80,16 +92,22 @@ class PermissionsData { |
| const Extension* extension, |
| std::string* error); |
| + // Locks the permissions data to the current thread. We don't do this on |
| + // construction, since extensions are initialized across multiple threads. |
| + void LockToThread() const; |
|
not at google - send to devlin
2015/09/22 21:51:27
"Lock" is an unfortunate term to be using, since i
Devlin
2015/09/23 17:09:00
Done.
|
| + |
| // Sets the runtime permissions of the given |extension| to |active| and |
| // |withheld|. |
| - void SetPermissions(const scoped_refptr<const PermissionSet>& active, |
| - const scoped_refptr<const PermissionSet>& withheld) const; |
| + void SetPermissions(scoped_ptr<const PermissionSet> active, |
| + scoped_ptr<const PermissionSet> withheld) const; |
| + |
| + // Sets the active permissions, leaving withheld the same. |
| + void SetActivePermissions(scoped_ptr<const PermissionSet> active) const; |
| // Updates the tab-specific permissions of |tab_id| to include those from |
| // |permissions|. |
| - void UpdateTabSpecificPermissions( |
| - int tab_id, |
| - scoped_refptr<const PermissionSet> permissions) const; |
| + void UpdateTabSpecificPermissions(int tab_id, |
| + const PermissionSet& permissions) const; |
| // Clears the tab-specific permissions of |tab_id|. |
| void ClearTabSpecificPermissions(int tab_id) const; |
| @@ -182,33 +200,35 @@ class PermissionsData { |
| // page itself. |
| bool CanCaptureVisiblePage(int tab_id, std::string* error) const; |
| - // Returns the tab permissions map. |
| - TabPermissionsMap CopyTabSpecificPermissionsMap() const; |
| + const TabPermissionsMap& tab_specific_permissions() const { |
| + CHECK(CalledOnValidThread()); |
| + return tab_specific_permissions_; |
| + } |
| - scoped_refptr<const PermissionSet> active_permissions() const { |
| - // We lock so that we can't also be setting the permissions while returning. |
| - base::AutoLock auto_lock(runtime_lock_); |
| - return active_permissions_unsafe_; |
| + const PermissionSet* active_permissions() const { |
|
not at google - send to devlin
2015/09/22 21:51:27
(noting place which should be a reference)
|
| + CHECK(CalledOnValidThread()); |
| + return active_permissions_unsafe_.get(); |
| } |
| - scoped_refptr<const PermissionSet> withheld_permissions() const { |
| - // We lock so that we can't also be setting the permissions while returning. |
| - base::AutoLock auto_lock(runtime_lock_); |
| - return withheld_permissions_unsafe_; |
| + const PermissionSet* withheld_permissions() const { |
| + CHECK(CalledOnValidThread()); |
| + return withheld_permissions_unsafe_.get(); |
| } |
| #if defined(UNIT_TEST) |
| - scoped_refptr<const PermissionSet> GetTabSpecificPermissionsForTesting( |
| - int tab_id) const { |
| + const PermissionSet* GetTabSpecificPermissionsForTesting(int tab_id) const { |
| + base::AutoLock auto_lock(runtime_lock_); |
| return GetTabSpecificPermissions(tab_id); |
| } |
| #endif |
| private: |
| + // Returns true if this is called on a valid thread. |
| + bool CalledOnValidThread() const; |
| + |
| // Gets the tab-specific host permissions of |tab_id|, or NULL if there |
| // aren't any. |
|
not at google - send to devlin
2015/09/22 21:51:27
Mention "must be called with |runtime_lock_| acqui
Devlin
2015/09/23 17:09:00
Done.
|
| - scoped_refptr<const PermissionSet> GetTabSpecificPermissions( |
| - int tab_id) const; |
| + const PermissionSet* GetTabSpecificPermissions(int tab_id) const; |
| // Returns true if the |extension| has tab-specific permission to operate on |
| // the tab specified by |tab_id| with the given |url|. |
| @@ -241,17 +261,19 @@ class PermissionsData { |
| // Unsafe indicates that we must lock anytime this is directly accessed. |
| // Unless you need to change |active_permissions_unsafe_|, use the (safe) |
| // active_permissions() accessor. |
| - mutable scoped_refptr<const PermissionSet> active_permissions_unsafe_; |
| + mutable scoped_ptr<const PermissionSet> active_permissions_unsafe_; |
| // The permissions the extension requested, but was not granted due because |
| // they are too powerful. This includes things like all_hosts. |
| // Unsafe indicates that we must lock anytime this is directly accessed. |
| // Unless you need to change |withheld_permissions_unsafe_|, use the (safe) |
| // withheld_permissions() accessor. |
| - mutable scoped_refptr<const PermissionSet> withheld_permissions_unsafe_; |
| + mutable scoped_ptr<const PermissionSet> withheld_permissions_unsafe_; |
| mutable TabPermissionsMap tab_specific_permissions_; |
| + mutable scoped_ptr<base::ThreadChecker> thread_checker_; |
| + |
| DISALLOW_COPY_AND_ASSIGN(PermissionsData); |
| }; |