Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / permissions / permission_context_base.cc
blob09747e13bd128d2df5072d8715a747d7e10eb8de
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.
5 #include "chrome/browser/permissions/permission_context_base.h"
7 #include "base/logging.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/permissions/permission_bubble_request_impl.h"
10 #include "chrome/browser/permissions/permission_context_uma_util.h"
11 #include "chrome/browser/permissions/permission_queue_controller.h"
12 #include "chrome/browser/permissions/permission_request_id.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/content_settings/core/browser/host_content_settings_map.h"
17 #include "components/content_settings/core/browser/website_settings_registry.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/origin_util.h"
22 PermissionContextBase::PermissionContextBase(
23 Profile* profile,
24 const ContentSettingsType permission_type)
25 : profile_(profile),
26 permission_type_(permission_type),
27 weak_factory_(this) {
28 permission_queue_controller_.reset(
29 new PermissionQueueController(profile_, permission_type_));
32 PermissionContextBase::~PermissionContextBase() {
33 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
36 void PermissionContextBase::RequestPermission(
37 content::WebContents* web_contents,
38 const PermissionRequestID& id,
39 const GURL& requesting_frame,
40 bool user_gesture,
41 const BrowserPermissionCallback& callback) {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
44 DecidePermission(web_contents,
45 id,
46 requesting_frame.GetOrigin(),
47 web_contents->GetLastCommittedURL().GetOrigin(),
48 user_gesture,
49 callback);
52 ContentSetting PermissionContextBase::GetPermissionStatus(
53 const GURL& requesting_origin,
54 const GURL& embedding_origin) const {
55 if (IsRestrictedToSecureOrigins() &&
56 !content::IsOriginSecure(requesting_origin)) {
57 return CONTENT_SETTING_BLOCK;
60 return profile_->GetHostContentSettingsMap()->GetContentSetting(
61 requesting_origin, embedding_origin, permission_type_, std::string());
64 void PermissionContextBase::ResetPermission(
65 const GURL& requesting_origin,
66 const GURL& embedding_origin) {
67 profile_->GetHostContentSettingsMap()->SetContentSetting(
68 ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
69 ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
70 permission_type_, std::string(), CONTENT_SETTING_DEFAULT);
73 void PermissionContextBase::CancelPermissionRequest(
74 content::WebContents* web_contents,
75 const PermissionRequestID& id) {
76 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
78 if (PermissionBubbleManager::Enabled()) {
79 PermissionBubbleRequest* cancelling =
80 pending_bubbles_.get(id.ToString());
81 if (cancelling != NULL && web_contents != NULL &&
82 PermissionBubbleManager::FromWebContents(web_contents) != NULL) {
83 PermissionBubbleManager::FromWebContents(web_contents)->
84 CancelRequest(cancelling);
86 return;
89 GetQueueController()->CancelInfoBarRequest(id);
92 void PermissionContextBase::DecidePermission(
93 content::WebContents* web_contents,
94 const PermissionRequestID& id,
95 const GURL& requesting_origin,
96 const GURL& embedding_origin,
97 bool user_gesture,
98 const BrowserPermissionCallback& callback) {
99 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
101 if (!requesting_origin.is_valid() || !embedding_origin.is_valid()) {
102 std::string type_name =
103 content_settings::WebsiteSettingsRegistry::GetInstance()
104 ->Get(permission_type_)
105 ->name();
107 DVLOG(1) << "Attempt to use " << type_name
108 << " from an invalid URL: " << requesting_origin << ","
109 << embedding_origin << " (" << type_name
110 << " is not supported in popups)";
111 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
112 false /* persist */, CONTENT_SETTING_BLOCK);
113 return;
116 if (IsRestrictedToSecureOrigins() &&
117 !content::IsOriginSecure(requesting_origin)) {
118 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
119 false /* persist */, CONTENT_SETTING_BLOCK);
120 return;
123 ContentSetting content_setting =
124 profile_->GetHostContentSettingsMap()
125 ->GetContentSettingAndMaybeUpdateLastUsage(
126 requesting_origin, embedding_origin, permission_type_,
127 std::string());
129 if (content_setting == CONTENT_SETTING_ALLOW ||
130 content_setting == CONTENT_SETTING_BLOCK) {
131 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
132 false /* persist */, content_setting);
133 return;
136 PermissionContextUmaUtil::PermissionRequested(
137 permission_type_, requesting_origin, embedding_origin, profile_);
139 if (PermissionBubbleManager::Enabled()) {
140 PermissionBubbleManager* bubble_manager =
141 PermissionBubbleManager::FromWebContents(web_contents);
142 DCHECK(bubble_manager);
143 scoped_ptr<PermissionBubbleRequest> request_ptr(
144 new PermissionBubbleRequestImpl(
145 requesting_origin, user_gesture, permission_type_,
146 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
147 base::Bind(&PermissionContextBase::PermissionDecided,
148 weak_factory_.GetWeakPtr(), id, requesting_origin,
149 embedding_origin, callback),
150 base::Bind(&PermissionContextBase::CleanUpBubble,
151 weak_factory_.GetWeakPtr(), id)));
152 PermissionBubbleRequest* request = request_ptr.get();
154 bool inserted = pending_bubbles_.add(
155 id.ToString(), request_ptr.Pass()).second;
156 DCHECK(inserted) << "Duplicate id " << id.ToString();
157 bubble_manager->AddRequest(request);
158 return;
161 // TODO(gbillock): Delete this and the infobar delegate when
162 // we're using only bubbles. crbug.com/337458
163 GetQueueController()->CreateInfoBarRequest(
164 id, requesting_origin, embedding_origin,
165 base::Bind(&PermissionContextBase::PermissionDecided,
166 weak_factory_.GetWeakPtr(), id, requesting_origin,
167 embedding_origin, callback,
168 // the queue controller takes care of persisting the
169 // permission
170 false));
173 void PermissionContextBase::PermissionDecided(
174 const PermissionRequestID& id,
175 const GURL& requesting_origin,
176 const GURL& embedding_origin,
177 const BrowserPermissionCallback& callback,
178 bool persist,
179 ContentSetting content_setting) {
180 // Infobar persistance and its related UMA is tracked on the infobar
181 // controller directly.
182 if (PermissionBubbleManager::Enabled()) {
183 if (persist) {
184 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
185 content_setting == CONTENT_SETTING_BLOCK);
186 if (content_setting == CONTENT_SETTING_ALLOW)
187 PermissionContextUmaUtil::PermissionGranted(permission_type_,
188 requesting_origin);
189 else
190 PermissionContextUmaUtil::PermissionDenied(permission_type_,
191 requesting_origin);
192 } else {
193 DCHECK_EQ(content_setting, CONTENT_SETTING_DEFAULT);
194 PermissionContextUmaUtil::PermissionDismissed(permission_type_,
195 requesting_origin);
199 NotifyPermissionSet(id, requesting_origin, embedding_origin, callback,
200 persist, content_setting);
203 PermissionQueueController* PermissionContextBase::GetQueueController() {
204 return permission_queue_controller_.get();
207 Profile* PermissionContextBase::profile() const {
208 return profile_;
211 void PermissionContextBase::NotifyPermissionSet(
212 const PermissionRequestID& id,
213 const GURL& requesting_origin,
214 const GURL& embedding_origin,
215 const BrowserPermissionCallback& callback,
216 bool persist,
217 ContentSetting content_setting) {
218 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
220 if (persist)
221 UpdateContentSetting(requesting_origin, embedding_origin, content_setting);
223 UpdateTabContext(id, requesting_origin,
224 content_setting == CONTENT_SETTING_ALLOW);
226 if (content_setting == CONTENT_SETTING_DEFAULT) {
227 content_setting =
228 profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
229 permission_type_, nullptr);
232 DCHECK_NE(content_setting, CONTENT_SETTING_DEFAULT);
233 callback.Run(content_setting);
236 void PermissionContextBase::CleanUpBubble(const PermissionRequestID& id) {
237 size_t success = pending_bubbles_.erase(id.ToString());
238 DCHECK(success == 1) << "Missing request " << id.ToString();
241 void PermissionContextBase::UpdateContentSetting(
242 const GURL& requesting_origin,
243 const GURL& embedding_origin,
244 ContentSetting content_setting) {
245 DCHECK_EQ(requesting_origin, requesting_origin.GetOrigin());
246 DCHECK_EQ(embedding_origin, embedding_origin.GetOrigin());
247 DCHECK(content_setting == CONTENT_SETTING_ALLOW ||
248 content_setting == CONTENT_SETTING_BLOCK);
250 profile_->GetHostContentSettingsMap()->SetContentSetting(
251 ContentSettingsPattern::FromURLNoWildcard(requesting_origin),
252 ContentSettingsPattern::FromURLNoWildcard(embedding_origin),
253 permission_type_, std::string(), content_setting);