permission_context_base.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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 3// found in the LICENSE file. 4 5#include "chrome/browser/content_settings/permission_context_base.h" 6 7#include "base/logging.h" 8#include "base/prefs/pref_service.h" 9#include "chrome/browser/content_settings/host_content_settings_map.h" 10#include "chrome/browser/content_settings/permission_bubble_request_impl.h" 11#include "chrome/browser/content_settings/permission_context_uma_util.h" 12#include "chrome/browser/content_settings/permission_queue_controller.h" 13#include "chrome/browser/content_settings/permission_request_id.h" 14#include "chrome/browser/content_settings/tab_specific_content_settings.h" 15#include "chrome/browser/profiles/profile.h" 16#include "chrome/browser/ui/website_settings/permission_bubble_manager.h" 17#include "chrome/common/pref_names.h" 18#include "content/public/browser/browser_thread.h" 19#include "content/public/browser/web_contents.h" 20 21PermissionContextBase::PermissionContextBase( 22 Profile* profile, 23 const ContentSettingsType permission_type) 24 : profile_(profile), 25 permission_type_(permission_type), 26 weak_factory_(this) { 27 permission_queue_controller_.reset( 28 new PermissionQueueController(profile_, permission_type_)); 29} 30 31PermissionContextBase::~PermissionContextBase() { 32 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 33} 34 35void PermissionContextBase::RequestPermission( 36 content::WebContents* web_contents, 37 const PermissionRequestID& id, 38 const GURL& requesting_frame, 39 bool user_gesture, 40 const BrowserPermissionCallback& callback) { 41 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 42 43 DecidePermission(web_contents, 44 id, 45 requesting_frame.GetOrigin(), 46 web_contents->GetLastCommittedURL().GetOrigin(), 47 user_gesture, 48 callback); 49} 50 51void PermissionContextBase::DecidePermission( 52 content::WebContents* web_contents, 53 const PermissionRequestID& id, 54 const GURL& requesting_origin, 55 const GURL& embedder_origin, 56 bool user_gesture, 57 const BrowserPermissionCallback& callback) { 58 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 59 60 ContentSetting content_setting = 61 profile_->GetHostContentSettingsMap()->GetContentSetting( 62 requesting_origin, embedder_origin, permission_type_, std::string()); 63 switch (content_setting) { 64 case CONTENT_SETTING_BLOCK: 65 NotifyPermissionSet(id, requesting_origin, embedder_origin, 66 callback, false /* persist */, false /* granted */); 67 return; 68 case CONTENT_SETTING_ALLOW: 69 NotifyPermissionSet(id, requesting_origin, embedder_origin, 70 callback, false /* persist */, true /* granted */); 71 return; 72 default: 73 break; 74 } 75 76 PermissionContextUmaUtil::PermissionRequested(permission_type_); 77 78 if (PermissionBubbleManager::Enabled()) { 79 PermissionBubbleManager* bubble_manager = 80 PermissionBubbleManager::FromWebContents(web_contents); 81 DCHECK(bubble_manager); 82 scoped_ptr<PermissionBubbleRequest> request_ptr( 83 new PermissionBubbleRequestImpl( 84 requesting_origin, 85 user_gesture, 86 permission_type_, 87 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), 88 base::Bind(&PermissionContextBase::PermissionDecided, 89 weak_factory_.GetWeakPtr(), 90 id, 91 requesting_origin, 92 embedder_origin, 93 callback), 94 base::Bind(&PermissionContextBase::CleanUpBubble, 95 weak_factory_.GetWeakPtr(), id))); 96 PermissionBubbleRequest* request = request_ptr.get(); 97 98 bool inserted = pending_bubbles_.add( 99 id.ToString(), request_ptr.Pass()).second; 100 DCHECK(inserted) << "Duplicate id " << id.ToString(); 101 bubble_manager->AddRequest(request); 102 return; 103 } 104 105 // TODO(gbillock): Delete this and the infobar delegate when 106 // we're using only bubbles. crbug.com/337458 107 GetQueueController()->CreateInfoBarRequest( 108 id, 109 requesting_origin, 110 embedder_origin, 111 base::Bind(&PermissionContextBase::PermissionDecided, 112 weak_factory_.GetWeakPtr(), 113 id, 114 requesting_origin, 115 embedder_origin, 116 callback, 117 // the queue controller takes care of persisting the 118 // permission 119 false)); 120} 121 122void PermissionContextBase::PermissionDecided( 123 const PermissionRequestID& id, 124 const GURL& requesting_origin, 125 const GURL& embedder_origin, 126 const BrowserPermissionCallback& callback, 127 bool persist, 128 bool allowed) { 129 130 // Infobar persistance and its related UMA is tracked on the infobar 131 // controller directly. 132 if (PermissionBubbleManager::Enabled()) { 133 if (persist) { 134 if (allowed) 135 PermissionContextUmaUtil::PermissionGranted(permission_type_); 136 else 137 PermissionContextUmaUtil::PermissionDenied(permission_type_); 138 } else { 139 PermissionContextUmaUtil::PermissionDismissed(permission_type_); 140 } 141 } 142 143 NotifyPermissionSet( 144 id, requesting_origin, embedder_origin, callback, persist, allowed); 145} 146 147PermissionQueueController* PermissionContextBase::GetQueueController() { 148 return permission_queue_controller_.get(); 149} 150 151void PermissionContextBase::NotifyPermissionSet( 152 const PermissionRequestID& id, 153 const GURL& requesting_origin, 154 const GURL& embedder_origin, 155 const BrowserPermissionCallback& callback, 156 bool persist, 157 bool allowed) { 158 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 159 if (persist) 160 UpdateContentSetting(requesting_origin, embedder_origin, allowed); 161 162 UpdateTabContext(id, requesting_origin, allowed); 163 callback.Run(allowed); 164} 165 166void PermissionContextBase::CleanUpBubble(const PermissionRequestID& id) { 167 size_t success = pending_bubbles_.erase(id.ToString()); 168 DCHECK(success == 1) << "Missing request " << id.ToString(); 169} 170 171void PermissionContextBase::UpdateContentSetting( 172 const GURL& requesting_origin, 173 const GURL& embedder_origin, 174 bool allowed) { 175 DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin()); 176 DCHECK_EQ(embedder_origin, embedder_origin.GetOrigin()); 177 ContentSetting content_setting = 178 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 179 profile_->GetHostContentSettingsMap()->SetContentSetting( 180 ContentSettingsPattern::FromURLNoWildcard(requesting_origin), 181 ContentSettingsPattern::FromURLNoWildcard(embedder_origin), 182 permission_type_, 183 std::string(), 184 content_setting); 185} 186