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