Index: extensions/common/permissions/permissions_data.cc |
diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc |
index 7fdbd2c36a79eea46b681b1f3ef464be2be27b15..3b944f4a17371660b190d183266d405bd6ce5cba 100644 |
--- a/extensions/common/permissions/permissions_data.cc |
+++ b/extensions/common/permissions/permissions_data.cc |
@@ -5,6 +5,7 @@ |
#include "extensions/common/permissions/permissions_data.h" |
#include "base/command_line.h" |
+#include "base/threading/thread_checker.h" |
#include "content/public/common/url_constants.h" |
#include "extensions/common/constants.h" |
#include "extensions/common/error_utils.h" |
@@ -30,14 +31,14 @@ PermissionsData::PolicyDelegate* g_policy_delegate = NULL; |
PermissionsData::PermissionsData(const Extension* extension) |
: extension_id_(extension->id()), manifest_type_(extension->GetType()) { |
base::AutoLock auto_lock(runtime_lock_); |
not at google - send to devlin
2015/09/22 21:51:26
I know the code is like this already, but it seems
Devlin
2015/09/23 17:09:00
heh, true. Removed.
|
- scoped_refptr<const PermissionSet> required_permissions = |
+ const PermissionSet* required_permissions = |
PermissionsParser::GetRequiredPermissions(extension); |
- active_permissions_unsafe_ = |
+ active_permissions_unsafe_.reset( |
new PermissionSet(required_permissions->apis(), |
required_permissions->manifest_permissions(), |
required_permissions->explicit_hosts(), |
- required_permissions->scriptable_hosts()); |
- withheld_permissions_unsafe_ = new PermissionSet(); |
+ required_permissions->scriptable_hosts())); |
+ withheld_permissions_unsafe_.reset(new PermissionSet()); |
} |
PermissionsData::~PermissionsData() { |
@@ -121,39 +122,57 @@ bool PermissionsData::IsRestrictedUrl(const GURL& document_url, |
return false; |
} |
+void PermissionsData::LockToThread() const { |
+ DCHECK(!thread_checker_); |
+ thread_checker_.reset(new base::ThreadChecker()); |
+} |
+ |
void PermissionsData::SetPermissions( |
- const scoped_refptr<const PermissionSet>& active, |
- const scoped_refptr<const PermissionSet>& withheld) const { |
+ scoped_ptr<const PermissionSet> active, |
+ scoped_ptr<const PermissionSet> withheld) const { |
+ CHECK(CalledOnValidThread()); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ active_permissions_unsafe_ = active.Pass(); |
+ withheld_permissions_unsafe_ = withheld.Pass(); |
+} |
+ |
+void PermissionsData::SetActivePermissions( |
+ scoped_ptr<const PermissionSet> active) const { |
+ CHECK(CalledOnValidThread()); |
base::AutoLock auto_lock(runtime_lock_); |
- active_permissions_unsafe_ = active; |
- withheld_permissions_unsafe_ = withheld; |
+ active_permissions_unsafe_ = active.Pass(); |
} |
void PermissionsData::UpdateTabSpecificPermissions( |
int tab_id, |
- scoped_refptr<const PermissionSet> permissions) const { |
+ const PermissionSet& permissions) const { |
+ CHECK(CalledOnValidThread()); |
base::AutoLock auto_lock(runtime_lock_); |
CHECK_GE(tab_id, 0); |
- TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id); |
- if (iter == tab_specific_permissions_.end()) |
- tab_specific_permissions_[tab_id] = permissions; |
- else |
- iter->second = PermissionSet::CreateUnion(*(iter->second), *permissions); |
+ TabPermissionsMap::const_iterator iter = |
+ tab_specific_permissions_.find(tab_id); |
+ scoped_ptr<const PermissionSet> new_permissions = PermissionSet::CreateUnion( |
+ iter == tab_specific_permissions_.end() ? PermissionSet() : *iter->second, |
+ permissions); |
+ tab_specific_permissions_.set(tab_id, new_permissions.Pass()); |
} |
void PermissionsData::ClearTabSpecificPermissions(int tab_id) const { |
+ CHECK(CalledOnValidThread()); |
base::AutoLock auto_lock(runtime_lock_); |
not at google - send to devlin
2015/09/22 21:51:26
Thought: you could tighten this up a bit with a cl
Devlin
2015/09/23 17:08:59
Done.
|
CHECK_GE(tab_id, 0); |
tab_specific_permissions_.erase(tab_id); |
} |
bool PermissionsData::HasAPIPermission(APIPermission::ID permission) const { |
- return active_permissions()->HasAPIPermission(permission); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return active_permissions_unsafe_->HasAPIPermission(permission); |
} |
bool PermissionsData::HasAPIPermission( |
const std::string& permission_name) const { |
- return active_permissions()->HasAPIPermission(permission_name); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return active_permissions_unsafe_->HasAPIPermission(permission_name); |
} |
bool PermissionsData::HasAPIPermissionForTab( |
@@ -162,19 +181,19 @@ bool PermissionsData::HasAPIPermissionForTab( |
if (HasAPIPermission(permission)) |
return true; |
- scoped_refptr<const PermissionSet> tab_permissions = |
- GetTabSpecificPermissions(tab_id); |
- |
- // Place autolock below the HasAPIPermission() and |
- // GetTabSpecificPermissions(), since each already acquires the lock. |
+ // Place autolock below the HasAPIPermission() since it already acquires the |
+ // lock. |
not at google - send to devlin
2015/09/22 21:51:26
I'd be more comfortable if locks were held for the
Devlin
2015/09/23 17:08:59
Done.
|
base::AutoLock auto_lock(runtime_lock_); |
- return tab_permissions.get() && tab_permissions->HasAPIPermission(permission); |
+ const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); |
+ return tab_permissions && tab_permissions->HasAPIPermission(permission); |
} |
bool PermissionsData::CheckAPIPermissionWithParam( |
APIPermission::ID permission, |
const APIPermission::CheckParam* param) const { |
- return active_permissions()->CheckAPIPermissionWithParam(permission, param); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return active_permissions_unsafe_->CheckAPIPermissionWithParam(permission, |
+ param); |
} |
URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { |
@@ -186,24 +205,28 @@ URLPatternSet PermissionsData::GetEffectiveHostPermissions() const { |
} |
bool PermissionsData::HasHostPermission(const GURL& url) const { |
- return active_permissions()->HasExplicitAccessToOrigin(url); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return active_permissions_unsafe_->HasExplicitAccessToOrigin(url); |
} |
bool PermissionsData::HasEffectiveAccessToAllHosts() const { |
- return active_permissions()->HasEffectiveAccessToAllHosts(); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return active_permissions_unsafe_->HasEffectiveAccessToAllHosts(); |
} |
PermissionMessages PermissionsData::GetPermissionMessages() const { |
+ base::AutoLock auto_lock(runtime_lock_); |
return PermissionMessageProvider::Get()->GetPermissionMessages( |
PermissionMessageProvider::Get()->GetAllPermissionIDs( |
- active_permissions().get(), manifest_type_)); |
+ active_permissions_unsafe_.get(), manifest_type_)); |
} |
bool PermissionsData::HasWithheldImpliedAllHosts() const { |
+ base::AutoLock auto_lock(runtime_lock_); |
// Since we currently only withhold all_hosts, it's sufficient to check |
// that either set is not empty. |
- return !withheld_permissions()->explicit_hosts().is_empty() || |
- !withheld_permissions()->scriptable_hosts().is_empty(); |
+ return !withheld_permissions_unsafe_->explicit_hosts().is_empty() || |
+ !withheld_permissions_unsafe_->scriptable_hosts().is_empty(); |
} |
bool PermissionsData::CanAccessPage(const Extension* extension, |
@@ -211,13 +234,11 @@ bool PermissionsData::CanAccessPage(const Extension* extension, |
int tab_id, |
int process_id, |
std::string* error) const { |
- AccessType result = CanRunOnPage(extension, |
- document_url, |
- tab_id, |
- process_id, |
- active_permissions()->explicit_hosts(), |
- withheld_permissions()->explicit_hosts(), |
- error); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ AccessType result = |
+ CanRunOnPage(extension, document_url, tab_id, process_id, |
+ active_permissions_unsafe_->explicit_hosts(), |
+ withheld_permissions_unsafe_->explicit_hosts(), error); |
// TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
} |
@@ -228,13 +249,10 @@ PermissionsData::AccessType PermissionsData::GetPageAccess( |
int tab_id, |
int process_id, |
std::string* error) const { |
- return CanRunOnPage(extension, |
- document_url, |
- tab_id, |
- process_id, |
- active_permissions()->explicit_hosts(), |
- withheld_permissions()->explicit_hosts(), |
- error); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return CanRunOnPage(extension, document_url, tab_id, process_id, |
+ active_permissions_unsafe_->explicit_hosts(), |
+ withheld_permissions_unsafe_->explicit_hosts(), error); |
} |
bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, |
@@ -242,13 +260,11 @@ bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, |
int tab_id, |
int process_id, |
std::string* error) const { |
- AccessType result = CanRunOnPage(extension, |
- document_url, |
- tab_id, |
- process_id, |
- active_permissions()->scriptable_hosts(), |
- withheld_permissions()->scriptable_hosts(), |
- error); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ AccessType result = |
+ CanRunOnPage(extension, document_url, tab_id, process_id, |
+ active_permissions_unsafe_->scriptable_hosts(), |
+ withheld_permissions_unsafe_->scriptable_hosts(), error); |
// TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
} |
@@ -259,13 +275,10 @@ PermissionsData::AccessType PermissionsData::GetContentScriptAccess( |
int tab_id, |
int process_id, |
std::string* error) const { |
- return CanRunOnPage(extension, |
- document_url, |
- tab_id, |
- process_id, |
- active_permissions()->scriptable_hosts(), |
- withheld_permissions()->scriptable_hosts(), |
- error); |
+ base::AutoLock auto_lock(runtime_lock_); |
+ return CanRunOnPage(extension, document_url, tab_id, process_id, |
+ active_permissions_unsafe_->scriptable_hosts(), |
+ withheld_permissions_unsafe_->scriptable_hosts(), error); |
} |
bool PermissionsData::CanCaptureVisiblePage(int tab_id, |
@@ -273,13 +286,13 @@ bool PermissionsData::CanCaptureVisiblePage(int tab_id, |
const URLPattern all_urls(URLPattern::SCHEME_ALL, |
URLPattern::kAllUrlsPattern); |
- if (active_permissions()->explicit_hosts().ContainsPattern(all_urls)) |
+ base::AutoLock auto_lock(runtime_lock_); |
+ if (active_permissions_unsafe_->explicit_hosts().ContainsPattern(all_urls)) |
return true; |
if (tab_id >= 0) { |
- scoped_refptr<const PermissionSet> tab_permissions = |
- GetTabSpecificPermissions(tab_id); |
- if (tab_permissions.get() && |
+ const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); |
+ if (tab_permissions && |
tab_permissions->HasAPIPermission(APIPermission::kTab)) { |
return true; |
} |
@@ -293,28 +306,26 @@ bool PermissionsData::CanCaptureVisiblePage(int tab_id, |
return false; |
} |
-PermissionsData::TabPermissionsMap |
-PermissionsData::CopyTabSpecificPermissionsMap() const { |
- base::AutoLock auto_lock(runtime_lock_); |
- return tab_specific_permissions_; |
+bool PermissionsData::CalledOnValidThread() const { |
+ return !thread_checker_ || thread_checker_->CalledOnValidThread(); |
not at google - send to devlin
2015/09/22 21:51:26
I'd find "return thread_checker_ && thread_checker
Devlin
2015/09/22 22:08:45
It's not bound to a thread during construction, be
|
} |
-scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions( |
+const PermissionSet* PermissionsData::GetTabSpecificPermissions( |
int tab_id) const { |
- base::AutoLock auto_lock(runtime_lock_); |
CHECK_GE(tab_id, 0); |
+ runtime_lock_.AssertAcquired(); |
TabPermissionsMap::const_iterator iter = |
tab_specific_permissions_.find(tab_id); |
- return (iter != tab_specific_permissions_.end()) ? iter->second : NULL; |
+ return (iter != tab_specific_permissions_.end()) ? iter->second : nullptr; |
} |
bool PermissionsData::HasTabSpecificPermissionToExecuteScript( |
int tab_id, |
const GURL& url) const { |
+ runtime_lock_.AssertAcquired(); |
if (tab_id >= 0) { |
- scoped_refptr<const PermissionSet> tab_permissions = |
- GetTabSpecificPermissions(tab_id); |
- if (tab_permissions.get() && |
+ const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id); |
+ if (tab_permissions && |
tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { |
return true; |
} |
@@ -330,6 +341,7 @@ PermissionsData::AccessType PermissionsData::CanRunOnPage( |
const URLPatternSet& permitted_url_patterns, |
const URLPatternSet& withheld_url_patterns, |
std::string* error) const { |
+ runtime_lock_.AssertAcquired(); |
if (g_policy_delegate && |
!g_policy_delegate->CanExecuteScriptOnPage( |
extension, document_url, tab_id, process_id, error)) { |