| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/permissions/permission_context_base.h" | 5 #include "chrome/browser/permissions/permission_context_base.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #endif | 53 #endif |
| 54 } | 54 } |
| 55 | 55 |
| 56 PermissionContextBase::~PermissionContextBase() { | 56 PermissionContextBase::~PermissionContextBase() { |
| 57 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 57 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 58 } | 58 } |
| 59 | 59 |
| 60 void PermissionContextBase::RequestPermission( | 60 void PermissionContextBase::RequestPermission( |
| 61 content::WebContents* web_contents, | 61 content::WebContents* web_contents, |
| 62 const PermissionRequestID& id, | 62 const PermissionRequestID& id, |
| 63 const GURL& requesting_frame, | 63 const url::Origin& requesting_origin, |
| 64 const BrowserPermissionCallback& callback) { | 64 const BrowserPermissionCallback& callback) { |
| 65 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 65 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 66 | 66 |
| 67 // First check if this permission has been disabled. | 67 // First check if this permission has been disabled. |
| 68 if (IsPermissionKillSwitchOn()) { | 68 if (IsPermissionKillSwitchOn()) { |
| 69 // Log to the developer console. | 69 // Log to the developer console. |
| 70 web_contents->GetMainFrame()->AddMessageToConsole( | 70 web_contents->GetMainFrame()->AddMessageToConsole( |
| 71 content::CONSOLE_MESSAGE_LEVEL_LOG, | 71 content::CONSOLE_MESSAGE_LEVEL_LOG, |
| 72 base::StringPrintf( | 72 base::StringPrintf( |
| 73 "%s permission has been blocked.", | 73 "%s permission has been blocked.", |
| 74 PermissionUtil::GetPermissionString(permission_type_).c_str())); | 74 PermissionUtil::GetPermissionString(permission_type_).c_str())); |
| 75 // The kill switch is enabled for this permission; Block all requests. | 75 // The kill switch is enabled for this permission; Block all requests. |
| 76 callback.Run(CONTENT_SETTING_BLOCK); | 76 callback.Run(CONTENT_SETTING_BLOCK); |
| 77 return; | 77 return; |
| 78 } | 78 } |
| 79 | 79 |
| 80 GURL requesting_origin = requesting_frame.GetOrigin(); | 80 const GURL& embedding_url = web_contents->GetLastCommittedURL(); |
| 81 GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); | 81 const url::Origin embedding_origin(embedding_url); |
| 82 const GURL requesting_url(requesting_origin.Serialize()); |
| 82 | 83 |
| 83 if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) { | 84 if (!requesting_origin.empty() || !embedding_origin.empty()) { |
| 84 std::string type_name = | 85 std::string type_name = |
| 85 content_settings::WebsiteSettingsRegistry::GetInstance() | 86 content_settings::WebsiteSettingsRegistry::GetInstance() |
| 86 ->Get(content_settings_type_) | 87 ->Get(content_settings_type_) |
| 87 ->name(); | 88 ->name(); |
| 88 | 89 |
| 89 DVLOG(1) << "Attempt to use " << type_name | 90 DVLOG(1) << "Attempt to use " << type_name |
| 90 << " from an invalid URL: " << requesting_origin << "," | 91 << " from an invalid origin: " << requesting_origin << "," |
| 91 << embedding_origin << " (" << type_name | 92 << embedding_origin << " (" << type_name |
| 92 << " is not supported in popups)"; | 93 << " is not supported in popups)"; |
| 93 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | 94 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
| 94 false /* persist */, CONTENT_SETTING_BLOCK); | 95 false /* persist */, CONTENT_SETTING_BLOCK); |
| 95 return; | 96 return; |
| 96 } | 97 } |
| 97 | 98 |
| 98 ContentSetting content_setting = | 99 ContentSetting content_setting = |
| 99 GetPermissionStatus(requesting_origin, embedding_origin); | 100 GetPermissionStatus(requesting_origin, embedding_origin); |
| 100 if (content_setting == CONTENT_SETTING_ALLOW) { | 101 if (content_setting == CONTENT_SETTING_ALLOW) { |
| 101 HostContentSettingsMapFactory::GetForProfile(profile_)->UpdateLastUsage( | 102 HostContentSettingsMapFactory::GetForProfile(profile_)->UpdateLastUsage( |
| 102 requesting_origin, embedding_origin, content_settings_type_); | 103 requesting_url, embedding_url, content_settings_type_); |
| 103 } | 104 } |
| 104 if (content_setting == CONTENT_SETTING_ALLOW || | 105 if (content_setting == CONTENT_SETTING_ALLOW || |
| 105 content_setting == CONTENT_SETTING_BLOCK) { | 106 content_setting == CONTENT_SETTING_BLOCK) { |
| 106 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | 107 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
| 107 false /* persist */, content_setting); | 108 false /* persist */, content_setting); |
| 108 return; | 109 return; |
| 109 } | 110 } |
| 110 | 111 |
| 111 PermissionUmaUtil::PermissionRequested(permission_type_, requesting_origin, | 112 PermissionUmaUtil::PermissionRequested(permission_type_, requesting_url, |
| 112 embedding_origin, profile_); | 113 embedding_url, profile_); |
| 113 | 114 |
| 114 DecidePermission(web_contents, id, requesting_origin, embedding_origin, | 115 DecidePermission(web_contents, id, requesting_origin, embedding_origin, |
| 115 callback); | 116 callback); |
| 116 } | 117 } |
| 117 | 118 |
| 118 ContentSetting PermissionContextBase::GetPermissionStatus( | 119 ContentSetting PermissionContextBase::GetPermissionStatus( |
| 119 const GURL& requesting_origin, | 120 const url::Origin& requesting_origin, |
| 120 const GURL& embedding_origin) const { | 121 const url::Origin& embedding_origin) const { |
| 121 | |
| 122 // If the permission has been disabled through Finch, block all requests. | 122 // If the permission has been disabled through Finch, block all requests. |
| 123 if (IsPermissionKillSwitchOn()) | 123 if (IsPermissionKillSwitchOn()) |
| 124 return CONTENT_SETTING_BLOCK; | 124 return CONTENT_SETTING_BLOCK; |
| 125 | 125 |
| 126 const GURL requesting_url(requesting_origin.Serialize()); |
| 127 |
| 126 if (IsRestrictedToSecureOrigins() && | 128 if (IsRestrictedToSecureOrigins() && |
| 127 !content::IsOriginSecure(requesting_origin)) { | 129 !content::IsOriginSecure(requesting_url)) { |
| 128 return CONTENT_SETTING_BLOCK; | 130 return CONTENT_SETTING_BLOCK; |
| 129 } | 131 } |
| 130 | 132 |
| 131 return HostContentSettingsMapFactory::GetForProfile(profile_) | 133 return HostContentSettingsMapFactory::GetForProfile(profile_) |
| 132 ->GetContentSetting(requesting_origin, embedding_origin, | 134 ->GetContentSetting(requesting_url, GURL(embedding_origin.Serialize()), |
| 133 content_settings_type_, std::string()); | 135 content_settings_type_, std::string()); |
| 134 } | 136 } |
| 135 | 137 |
| 136 void PermissionContextBase::ResetPermission( | 138 void PermissionContextBase::ResetPermission( |
| 137 const GURL& requesting_origin, | 139 const url::Origin& requesting_origin, |
| 138 const GURL& embedding_origin) { | 140 const url::Origin& embedding_origin) { |
| 139 HostContentSettingsMapFactory::GetForProfile(profile_) | 141 HostContentSettingsMapFactory::GetForProfile(profile_) |
| 140 ->SetContentSettingDefaultScope(requesting_origin, embedding_origin, | 142 ->SetContentSettingDefaultScope(GURL(requesting_origin.Serialize()), |
| 143 GURL(embedding_origin.Serialize()), |
| 141 content_settings_type_, std::string(), | 144 content_settings_type_, std::string(), |
| 142 CONTENT_SETTING_DEFAULT); | 145 CONTENT_SETTING_DEFAULT); |
| 143 } | 146 } |
| 144 | 147 |
| 145 void PermissionContextBase::CancelPermissionRequest( | 148 void PermissionContextBase::CancelPermissionRequest( |
| 146 content::WebContents* web_contents, | 149 content::WebContents* web_contents, |
| 147 const PermissionRequestID& id) { | 150 const PermissionRequestID& id) { |
| 148 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 151 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 149 | 152 |
| 150 #if defined(OS_ANDROID) | 153 #if defined(OS_ANDROID) |
| 151 GetQueueController()->CancelInfoBarRequest(id); | 154 GetQueueController()->CancelInfoBarRequest(id); |
| 152 #else | 155 #else |
| 153 PermissionBubbleRequest* cancelling = pending_bubbles_.get(id.ToString()); | 156 PermissionBubbleRequest* cancelling = pending_bubbles_.get(id.ToString()); |
| 154 if (cancelling != NULL && web_contents != NULL && | 157 if (cancelling != NULL && web_contents != NULL && |
| 155 PermissionBubbleManager::FromWebContents(web_contents) != NULL) { | 158 PermissionBubbleManager::FromWebContents(web_contents) != NULL) { |
| 156 PermissionBubbleManager::FromWebContents(web_contents) | 159 PermissionBubbleManager::FromWebContents(web_contents) |
| 157 ->CancelRequest(cancelling); | 160 ->CancelRequest(cancelling); |
| 158 } | 161 } |
| 159 #endif | 162 #endif |
| 160 } | 163 } |
| 161 | 164 |
| 162 void PermissionContextBase::DecidePermission( | 165 void PermissionContextBase::DecidePermission( |
| 163 content::WebContents* web_contents, | 166 content::WebContents* web_contents, |
| 164 const PermissionRequestID& id, | 167 const PermissionRequestID& id, |
| 165 const GURL& requesting_origin, | 168 const url::Origin& requesting_origin, |
| 166 const GURL& embedding_origin, | 169 const url::Origin& embedding_origin, |
| 167 const BrowserPermissionCallback& callback) { | 170 const BrowserPermissionCallback& callback) { |
| 168 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 171 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 169 | 172 |
| 173 const GURL requesting_url(requesting_origin.Serialize()); |
| 174 const GURL embedding_url(embedding_origin.Serialize()); |
| 175 |
| 170 #if !defined(OS_ANDROID) | 176 #if !defined(OS_ANDROID) |
| 171 PermissionBubbleManager* bubble_manager = | 177 PermissionBubbleManager* bubble_manager = |
| 172 PermissionBubbleManager::FromWebContents(web_contents); | 178 PermissionBubbleManager::FromWebContents(web_contents); |
| 173 // TODO(felt): sometimes |bubble_manager| is null. This check is meant to | 179 // TODO(felt): sometimes |bubble_manager| is null. This check is meant to |
| 174 // prevent crashes. See crbug.com/457091. | 180 // prevent crashes. See crbug.com/457091. |
| 175 if (!bubble_manager) | 181 if (!bubble_manager) |
| 176 return; | 182 return; |
| 183 |
| 177 scoped_ptr<PermissionBubbleRequest> request_ptr( | 184 scoped_ptr<PermissionBubbleRequest> request_ptr( |
| 178 new PermissionBubbleRequestImpl( | 185 new PermissionBubbleRequestImpl( |
| 179 requesting_origin, permission_type_, | 186 requesting_url, permission_type_, |
| 180 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), | 187 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), |
| 181 base::Bind(&PermissionContextBase::PermissionDecided, | 188 base::Bind(&PermissionContextBase::PermissionDecided, |
| 182 weak_factory_.GetWeakPtr(), id, requesting_origin, | 189 weak_factory_.GetWeakPtr(), id, requesting_origin, |
| 183 embedding_origin, callback), | 190 embedding_origin, callback), |
| 184 base::Bind(&PermissionContextBase::CleanUpBubble, | 191 base::Bind(&PermissionContextBase::CleanUpBubble, |
| 185 weak_factory_.GetWeakPtr(), id))); | 192 weak_factory_.GetWeakPtr(), id))); |
| 186 PermissionBubbleRequest* request = request_ptr.get(); | 193 PermissionBubbleRequest* request = request_ptr.get(); |
| 187 | 194 |
| 188 bool inserted = | 195 bool inserted = |
| 189 pending_bubbles_.add(id.ToString(), std::move(request_ptr)).second; | 196 pending_bubbles_.add(id.ToString(), std::move(request_ptr)).second; |
| 190 DCHECK(inserted) << "Duplicate id " << id.ToString(); | 197 DCHECK(inserted) << "Duplicate id " << id.ToString(); |
| 191 bubble_manager->AddRequest(request); | 198 bubble_manager->AddRequest(request); |
| 192 #else | 199 #else |
| 193 GetQueueController()->CreateInfoBarRequest( | 200 GetQueueController()->CreateInfoBarRequest( |
| 194 id, requesting_origin, embedding_origin, | 201 id, requesting_url, embedding_url, |
| 195 base::Bind(&PermissionContextBase::PermissionDecided, | 202 base::Bind(&PermissionContextBase::PermissionDecided, |
| 196 weak_factory_.GetWeakPtr(), id, requesting_origin, | 203 weak_factory_.GetWeakPtr(), id, requesting_origin, |
| 197 embedding_origin, callback, | 204 embedding_origin, callback, |
| 198 // the queue controller takes care of persisting the | 205 // the queue controller takes care of persisting the |
| 199 // permission | 206 // permission |
| 200 false)); | 207 false)); |
| 201 #endif | 208 #endif |
| 202 } | 209 } |
| 203 | 210 |
| 204 void PermissionContextBase::PermissionDecided( | 211 void PermissionContextBase::PermissionDecided( |
| 205 const PermissionRequestID& id, | 212 const PermissionRequestID& id, |
| 206 const GURL& requesting_origin, | 213 const url::Origin& requesting_origin, |
| 207 const GURL& embedding_origin, | 214 const url::Origin& embedding_origin, |
| 208 const BrowserPermissionCallback& callback, | 215 const BrowserPermissionCallback& callback, |
| 209 bool persist, | 216 bool persist, |
| 210 ContentSetting content_setting) { | 217 ContentSetting content_setting) { |
| 211 #if !defined(OS_ANDROID) | 218 #if !defined(OS_ANDROID) |
| 212 // Infobar persistence and its related UMA is tracked on the infobar | 219 // Infobar persistence and its related UMA is tracked on the infobar |
| 213 // controller directly. | 220 // controller directly. |
| 221 const GURL requesting_url(requesting_origin.Serialize()); |
| 214 if (persist) { | 222 if (persist) { |
| 215 DCHECK(content_setting == CONTENT_SETTING_ALLOW || | 223 DCHECK(content_setting == CONTENT_SETTING_ALLOW || |
| 216 content_setting == CONTENT_SETTING_BLOCK); | 224 content_setting == CONTENT_SETTING_BLOCK); |
| 217 if (content_setting == CONTENT_SETTING_ALLOW) | 225 if (content_setting == CONTENT_SETTING_ALLOW) |
| 218 PermissionUmaUtil::PermissionGranted(permission_type_, requesting_origin); | 226 PermissionUmaUtil::PermissionGranted(permission_type_, requesting_url); |
| 219 else | 227 else |
| 220 PermissionUmaUtil::PermissionDenied(permission_type_, requesting_origin); | 228 PermissionUmaUtil::PermissionDenied(permission_type_, requesting_url); |
| 221 } else { | 229 } else { |
| 222 DCHECK_EQ(content_setting, CONTENT_SETTING_DEFAULT); | 230 DCHECK_EQ(content_setting, CONTENT_SETTING_DEFAULT); |
| 223 PermissionUmaUtil::PermissionDismissed(permission_type_, requesting_origin); | 231 PermissionUmaUtil::PermissionDismissed(permission_type_, requesting_url); |
| 224 } | 232 } |
| 225 #endif | 233 #endif |
| 226 | 234 |
| 227 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, | 235 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback, |
| 228 persist, content_setting); | 236 persist, content_setting); |
| 229 } | 237 } |
| 230 | 238 |
| 231 #if defined(OS_ANDROID) | 239 #if defined(OS_ANDROID) |
| 232 PermissionQueueController* PermissionContextBase::GetQueueController() { | 240 PermissionQueueController* PermissionContextBase::GetQueueController() { |
| 233 return permission_queue_controller_.get(); | 241 return permission_queue_controller_.get(); |
| 234 } | 242 } |
| 235 #endif | 243 #endif |
| 236 | 244 |
| 237 Profile* PermissionContextBase::profile() const { | 245 Profile* PermissionContextBase::profile() const { |
| 238 return profile_; | 246 return profile_; |
| 239 } | 247 } |
| 240 | 248 |
| 241 void PermissionContextBase::NotifyPermissionSet( | 249 void PermissionContextBase::NotifyPermissionSet( |
| 242 const PermissionRequestID& id, | 250 const PermissionRequestID& id, |
| 243 const GURL& requesting_origin, | 251 const url::Origin& requesting_origin, |
| 244 const GURL& embedding_origin, | 252 const url::Origin& embedding_origin, |
| 245 const BrowserPermissionCallback& callback, | 253 const BrowserPermissionCallback& callback, |
| 246 bool persist, | 254 bool persist, |
| 247 ContentSetting content_setting) { | 255 ContentSetting content_setting) { |
| 248 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 256 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 249 | 257 |
| 250 if (persist) | 258 if (persist) |
| 251 UpdateContentSetting(requesting_origin, embedding_origin, content_setting); | 259 UpdateContentSetting(requesting_origin, embedding_origin, content_setting); |
| 252 | 260 |
| 253 UpdateTabContext(id, requesting_origin, | 261 UpdateTabContext(id, requesting_origin, |
| 254 content_setting == CONTENT_SETTING_ALLOW); | 262 content_setting == CONTENT_SETTING_ALLOW); |
| 255 | 263 |
| 256 if (content_setting == CONTENT_SETTING_DEFAULT) { | 264 if (content_setting == CONTENT_SETTING_DEFAULT) { |
| 257 content_setting = | 265 content_setting = |
| 258 HostContentSettingsMapFactory::GetForProfile(profile_) | 266 HostContentSettingsMapFactory::GetForProfile(profile_) |
| 259 ->GetDefaultContentSetting(content_settings_type_, nullptr); | 267 ->GetDefaultContentSetting(content_settings_type_, nullptr); |
| 260 } | 268 } |
| 261 | 269 |
| 262 DCHECK_NE(content_setting, CONTENT_SETTING_DEFAULT); | 270 DCHECK_NE(content_setting, CONTENT_SETTING_DEFAULT); |
| 263 callback.Run(content_setting); | 271 callback.Run(content_setting); |
| 264 } | 272 } |
| 265 | 273 |
| 266 void PermissionContextBase::CleanUpBubble(const PermissionRequestID& id) { | 274 void PermissionContextBase::CleanUpBubble(const PermissionRequestID& id) { |
| 267 size_t success = pending_bubbles_.erase(id.ToString()); | 275 size_t success = pending_bubbles_.erase(id.ToString()); |
| 268 DCHECK(success == 1) << "Missing request " << id.ToString(); | 276 DCHECK(success == 1) << "Missing request " << id.ToString(); |
| 269 } | 277 } |
| 270 | 278 |
| 271 void PermissionContextBase::UpdateContentSetting( | 279 void PermissionContextBase::UpdateContentSetting( |
| 272 const GURL& requesting_origin, | 280 const url::Origin& requesting_origin, |
| 273 const GURL& embedding_origin, | 281 const url::Origin& embedding_origin, |
| 274 ContentSetting content_setting) { | 282 ContentSetting content_setting) { |
| 275 DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin()); | 283 const GURL requesting_url(requesting_origin.Serialize()); |
| 276 DCHECK_EQ(embedding_origin, embedding_origin.GetOrigin()); | 284 const GURL embedding_url(embedding_origin.Serialize()); |
| 285 DCHECK_EQ(requesting_origin, url::Origin(requesting_url)); |
| 286 DCHECK_EQ(embedding_origin, url::Origin(embedding_url)); |
| 277 DCHECK(content_setting == CONTENT_SETTING_ALLOW || | 287 DCHECK(content_setting == CONTENT_SETTING_ALLOW || |
| 278 content_setting == CONTENT_SETTING_BLOCK); | 288 content_setting == CONTENT_SETTING_BLOCK); |
| 279 | 289 |
| 280 HostContentSettingsMapFactory::GetForProfile(profile_) | 290 HostContentSettingsMapFactory::GetForProfile(profile_) |
| 281 ->SetContentSettingDefaultScope(requesting_origin, embedding_origin, | 291 ->SetContentSettingDefaultScope(requesting_url, embedding_url, |
| 282 content_settings_type_, std::string(), | 292 content_settings_type_, std::string(), |
| 283 content_setting); | 293 content_setting); |
| 284 } | 294 } |
| 285 | 295 |
| 286 bool PermissionContextBase::IsPermissionKillSwitchOn() const { | 296 bool PermissionContextBase::IsPermissionKillSwitchOn() const { |
| 287 const std::string param = variations::GetVariationParamValue( | 297 const std::string param = variations::GetVariationParamValue( |
| 288 kPermissionsKillSwitchFieldStudy, | 298 kPermissionsKillSwitchFieldStudy, |
| 289 PermissionUtil::GetPermissionString(permission_type_)); | 299 PermissionUtil::GetPermissionString(permission_type_)); |
| 290 | 300 |
| 291 return param == kPermissionsKillSwitchBlockedValue; | 301 return param == kPermissionsKillSwitchBlockedValue; |
| 292 } | 302 } |
| OLD | NEW |