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); |
}; |