Chromium Code Reviews| Index: chrome/common/extensions/extension.cc |
| diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc |
| index 54e056617ede1fb55352371f612050bdb4ffb5de..d1b88a6f1a6dd746883589b7a5af8f9888d2e272 100644 |
| --- a/chrome/common/extensions/extension.cc |
| +++ b/chrome/common/extensions/extension.cc |
| @@ -3320,6 +3320,7 @@ bool Extension::HasMultipleUISurfaces() const { |
| } |
| bool Extension::CanExecuteScriptOnPage(const GURL& page_url, |
| + int tab_id, |
| const UserScript* script, |
| std::string* error) const { |
| base::AutoLock auto_lock(runtime_data_lock_); |
| @@ -3342,6 +3343,14 @@ bool Extension::CanExecuteScriptOnPage(const GURL& page_url, |
| !CanExecuteScriptEverywhere()) |
| return false; |
| + // If a tab ID is specified, try the tab-specific permissions. |
| + if (tab_id >= 0) { |
| + const URLPatternSet* tab = |
|
Aaron Boodman
2012/06/06 01:03:13
nit: tab_permissions?
not at google - send to devlin
2012/06/06 07:38:40
But then it won't fit on 1 line!
|
| + runtime_data_.GetTabSpecificHostPermissions(tab_id); |
| + if (tab && tab->MatchesSecurityOrigin(page_url)) |
| + return true; |
| + } |
| + |
| // If a script is specified, use its matches. |
| if (script) |
| return script->MatchesURL(page_url); |
| @@ -3404,7 +3413,14 @@ bool Extension::CanExecuteScriptEverywhere() const { |
| } |
| bool Extension::CanCaptureVisiblePage(const GURL& page_url, |
| + int tab_id, |
| std::string *error) const { |
| + if (tab_id >= 0) { |
| + const URLPatternSet* tab = GetTabSpecificHostPermissions(tab_id); |
| + if (tab && tab->MatchesSecurityOrigin(page_url)) |
| + return true; |
| + } |
| + |
| if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) |
| return true; |
| @@ -3580,6 +3596,41 @@ ExtensionAction* Extension::GetScriptBadge() const { |
| return script_badge_.get(); |
| } |
| +const URLPatternSet* Extension::GetTabSpecificHostPermissions( |
| + int tab_id) const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + return runtime_data_.GetTabSpecificHostPermissions(tab_id); |
| +} |
| + |
| +void Extension::SetTabSpecificHostPermissions( |
| + int tab_id, |
| + const URLPatternSet& permissions) const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + runtime_data_.SetTabSpecificHostPermissions(tab_id, permissions); |
| +} |
| + |
| +void Extension::ClearTabSpecificHostPermissions(int tab_id) const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + runtime_data_.ClearTabSpecificHostPermissions(tab_id); |
| +} |
| + |
| +const URLPatternSet* Extension::GetActiveHostPermissionsForAllTabs() const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + return runtime_data_.GetActiveHostPermissionsForAllTabs(); |
| +} |
| + |
| +void Extension::GetAllTabSpecificHostPermissions( |
| + std::map<int, URLPatternSet>* out) const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + runtime_data_.GetAllTabSpecificHostPermissions(out); |
| +} |
| + |
| +void Extension::SetAllTabSpecificHostPermissions( |
| + const std::map<int, URLPatternSet>& origins) const { |
| + base::AutoLock auto_lock(runtime_data_lock_); |
| + runtime_data_.SetAllTabSpecificHostPermissions(origins); |
| +} |
| + |
| bool Extension::CheckPlatformAppFeatures(std::string* utf8_error) { |
| if (!is_platform_app()) |
| return true; |
| @@ -3623,6 +3674,93 @@ scoped_refptr<const ExtensionPermissionSet> |
| void Extension::RuntimeData::SetActivePermissions( |
| const ExtensionPermissionSet* active) { |
| active_permissions_ = active; |
| + active_host_permissions_for_all_tabs_.reset(); |
| +} |
| + |
| +const URLPatternSet* |
| + Extension::RuntimeData::GetTabSpecificHostPermissions(int tab_id) const { |
| + CHECK_GE(tab_id, 0); |
| + TabHostPermissionsMap::const_iterator it = |
| + tab_specific_host_permissions_.find(tab_id); |
| + return (it != tab_specific_host_permissions_.end()) ? it->second.get() : NULL; |
| +} |
| + |
| +void Extension::RuntimeData::SetTabSpecificHostPermissions( |
| + int tab_id, |
| + const URLPatternSet& hosts) { |
| + CHECK_GE(tab_id, 0); |
| + tab_specific_host_permissions_[tab_id] = |
| + make_linked_ptr(new URLPatternSet(hosts)); |
| + |
| + // If we're tracking the active host permissions for all tabs, update it. |
| + if (active_host_permissions_for_all_tabs_.get()) { |
| + scoped_ptr<URLPatternSet> updated(new URLPatternSet()); |
| + URLPatternSet::CreateUnion(*active_host_permissions_for_all_tabs_, |
| + hosts, |
| + updated.get()); |
| + active_host_permissions_for_all_tabs_ = updated.Pass(); |
| + } |
| +} |
| + |
| +void Extension::RuntimeData::ClearTabSpecificHostPermissions(int tab_id) { |
| + CHECK_GE(tab_id, 0); |
| + tab_specific_host_permissions_.erase(tab_id); |
| + active_host_permissions_for_all_tabs_.reset(); |
| +} |
| + |
| +const URLPatternSet* |
| + Extension::RuntimeData::GetActiveHostPermissionsForAllTabs() const { |
| + if (active_host_permissions_for_all_tabs_.get()) |
| + return active_host_permissions_for_all_tabs_.get(); |
| + |
| + if (tab_specific_host_permissions_.empty()) |
| + return &active_permissions_->explicit_hosts(); |
| + |
| + // Compute and cache the union of all tab specific permissions. The union |
| + // operation for ExtensionPermissionSet is O(n), so the naive union |
| + // implementation would be O(n^2). Try to be smarter and do it in O(nlog(n)). |
| + std::vector<linked_ptr<const URLPatternSet> > all; |
| + for (TabHostPermissionsMap::const_iterator it = |
| + tab_specific_host_permissions_.begin(); |
| + it != tab_specific_host_permissions_.end(); ++it) { |
| + all.push_back(it->second); |
| + } |
| + |
| + for (size_t skip = 1; skip < all.size(); skip *= 2) { |
| + for (size_t i = 0; i < all.size() - skip; i += skip) { |
| + URLPatternSet* u = new URLPatternSet(); |
| + URLPatternSet::CreateUnion(*all[i], *all[i + skip], u); |
| + all[i] = make_linked_ptr(u); |
| + } |
| + } |
| + |
| + active_host_permissions_for_all_tabs_.reset(new URLPatternSet()); |
| + URLPatternSet::CreateUnion( |
| + *all[0], |
| + active_permissions_->explicit_hosts(), |
| + active_host_permissions_for_all_tabs_.get()); |
| + return active_host_permissions_for_all_tabs_.get(); |
| +} |
| + |
| +void Extension::RuntimeData::GetAllTabSpecificHostPermissions( |
| + std::map<int, URLPatternSet>* out) const { |
| + for (TabHostPermissionsMap::const_iterator it = |
| + tab_specific_host_permissions_.begin(); |
| + it != tab_specific_host_permissions_.end(); ++it) { |
| + (*out)[it->first] = *it->second; |
| + } |
| +} |
| + |
| +void Extension::RuntimeData::SetAllTabSpecificHostPermissions( |
| + const std::map<int, URLPatternSet>& in) { |
| + tab_specific_host_permissions_.clear(); |
| + active_host_permissions_for_all_tabs_.reset(); |
| + |
| + for (std::map<int, URLPatternSet>::const_iterator it = in.begin(); |
| + it != in.end(); ++it) { |
| + tab_specific_host_permissions_[it->first].reset( |
| + new URLPatternSet(it->second)); |
| + } |
| } |
| UnloadedExtensionInfo::UnloadedExtensionInfo( |