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/content_settings/permission_context_base.h"
8 #include "base/command_line.h"
9 #include "chrome/browser/content_settings/permission_queue_controller.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "components/content_settings/core/browser/host_content_settings_map.h"
16 #include "components/content_settings/core/common/content_settings.h"
17 #include "components/content_settings/core/common/content_settings_types.h"
18 #include "components/content_settings/core/common/permission_request_id.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/mock_render_process_host.h"
21 #include "content/public/test/web_contents_tester.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 class TestPermissionContext
: public PermissionContextBase
{
26 TestPermissionContext(Profile
* profile
,
27 const ContentSettingsType permission_type
)
28 : PermissionContextBase(profile
, permission_type
),
29 permission_set_(false),
30 permission_granted_(false),
31 tab_context_updated_(false) {}
33 ~TestPermissionContext() override
{}
35 PermissionQueueController
* GetInfoBarController() {
36 return GetQueueController();
39 bool permission_granted() {
40 return permission_granted_
;
43 bool permission_set() {
44 return permission_set_
;
47 bool tab_context_updated() {
48 return tab_context_updated_
;
51 void TrackPermissionDecision(ContentSetting content_setting
) {
52 permission_set_
= true;
53 permission_granted_
= content_setting
== CONTENT_SETTING_ALLOW
;
57 void UpdateTabContext(const PermissionRequestID
& id
,
58 const GURL
& requesting_origin
,
59 bool allowed
) override
{
60 tab_context_updated_
= true;
65 bool permission_granted_
;
66 bool tab_context_updated_
;
69 class PermissionContextBaseTests
: public ChromeRenderViewHostTestHarness
{
71 PermissionContextBaseTests() {}
73 // Accept or dismiss the permission bubble or infobar.
74 void RespondToPermission(TestPermissionContext
* context
,
75 const PermissionRequestID
& id
,
78 if (!PermissionBubbleManager::Enabled()) {
79 context
->GetInfoBarController()->OnPermissionSet(
80 id
, url
, url
, accept
, accept
);
84 PermissionBubbleManager
* manager
=
85 PermissionBubbleManager::FromWebContents(web_contents());
92 // Use either the bubble or the infobar.
93 void StartUsingPermissionBubble() {
94 base::CommandLine::ForCurrentProcess()->AppendSwitch(
95 switches::kEnablePermissionsBubbles
);
96 EXPECT_TRUE(PermissionBubbleManager::Enabled());
99 void TestAskAndGrant_TestContent() {
100 TestPermissionContext
permission_context(
101 profile(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
102 GURL
url("http://www.google.com");
103 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
105 const PermissionRequestID
id(
106 web_contents()->GetRenderProcessHost()->GetID(),
107 web_contents()->GetRenderViewHost()->GetRoutingID(),
109 permission_context
.RequestPermission(
112 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
113 base::Unretained(&permission_context
)));
115 RespondToPermission(&permission_context
, id
, url
, true);
116 EXPECT_TRUE(permission_context
.permission_set());
117 EXPECT_TRUE(permission_context
.permission_granted());
118 EXPECT_TRUE(permission_context
.tab_context_updated());
120 ContentSetting setting
=
121 profile()->GetHostContentSettingsMap()->GetContentSetting(
122 url
.GetOrigin(), url
.GetOrigin(),
123 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
, std::string());
124 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
127 void TestAskAndDismiss_TestContent() {
128 TestPermissionContext
permission_context(
129 profile(), CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
130 GURL
url("http://www.google.es");
131 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
133 const PermissionRequestID
id(
134 web_contents()->GetRenderProcessHost()->GetID(),
135 web_contents()->GetRenderViewHost()->GetRoutingID(),
137 permission_context
.RequestPermission(
140 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
141 base::Unretained(&permission_context
)));
143 RespondToPermission(&permission_context
, id
, url
, false);
144 EXPECT_TRUE(permission_context
.permission_set());
145 EXPECT_FALSE(permission_context
.permission_granted());
146 EXPECT_TRUE(permission_context
.tab_context_updated());
148 ContentSetting setting
=
149 profile()->GetHostContentSettingsMap()->GetContentSetting(
150 url
.GetOrigin(), url
.GetOrigin(),
151 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, std::string());
152 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
155 void TestRequestPermissionInvalidUrl(ContentSettingsType type
) {
156 TestPermissionContext
permission_context(profile(), type
);
158 ASSERT_FALSE(url
.is_valid());
159 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
161 const PermissionRequestID
id(
162 web_contents()->GetRenderProcessHost()->GetID(),
163 web_contents()->GetRenderViewHost()->GetRoutingID(),
165 permission_context
.RequestPermission(
168 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
169 base::Unretained(&permission_context
)));
171 EXPECT_TRUE(permission_context
.permission_set());
172 EXPECT_FALSE(permission_context
.permission_granted());
173 EXPECT_TRUE(permission_context
.tab_context_updated());
175 ContentSetting setting
=
176 profile()->GetHostContentSettingsMap()->GetContentSetting(
177 url
.GetOrigin(), url
.GetOrigin(), type
, std::string());
178 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
181 void TestRequestPermissionNonSecureUrl(ContentSettingsType type
) {
182 TestPermissionContext
permission_context(profile(), type
);
183 GURL
url("http://www.google.com");
184 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
186 const PermissionRequestID
id(
187 web_contents()->GetRenderProcessHost()->GetID(),
188 web_contents()->GetRenderViewHost()->GetRoutingID(),
190 permission_context
.RequestPermission(
193 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
194 base::Unretained(&permission_context
)));
196 EXPECT_TRUE(permission_context
.permission_set());
197 EXPECT_FALSE(permission_context
.permission_granted());
198 EXPECT_TRUE(permission_context
.tab_context_updated());
200 ContentSetting setting
=
201 profile()->GetHostContentSettingsMap()->GetContentSetting(
202 url
.GetOrigin(), url
.GetOrigin(), type
, std::string());
203 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
206 void TestGrantAndRevoke_TestContent(ContentSettingsType type
,
207 ContentSetting expected_default
) {
208 TestPermissionContext
permission_context(profile(), type
);
209 GURL
url("https://www.google.com");
210 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
212 const PermissionRequestID
id(
213 web_contents()->GetRenderProcessHost()->GetID(),
214 web_contents()->GetRenderViewHost()->GetRoutingID(),
216 permission_context
.RequestPermission(
219 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
220 base::Unretained(&permission_context
)));
222 RespondToPermission(&permission_context
, id
, url
, true);
223 EXPECT_TRUE(permission_context
.permission_set());
224 EXPECT_TRUE(permission_context
.permission_granted());
225 EXPECT_TRUE(permission_context
.tab_context_updated());
227 ContentSetting setting
=
228 profile()->GetHostContentSettingsMap()->GetContentSetting(
229 url
.GetOrigin(), url
.GetOrigin(),
230 type
, std::string());
231 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
233 // Try to reset permission.
234 permission_context
.ResetPermission(url
.GetOrigin(), url
.GetOrigin());
235 ContentSetting setting_after_reset
=
236 profile()->GetHostContentSettingsMap()->GetContentSetting(
237 url
.GetOrigin(), url
.GetOrigin(),
238 type
, std::string());
239 ContentSetting default_setting
=
240 profile()->GetHostContentSettingsMap()->GetDefaultContentSetting(
242 EXPECT_EQ(default_setting
, setting_after_reset
);
246 // ChromeRenderViewHostTestHarness:
247 void SetUp() override
{
248 ChromeRenderViewHostTestHarness::SetUp();
249 InfoBarService::CreateForWebContents(web_contents());
250 PermissionBubbleManager::CreateForWebContents(web_contents());
253 DISALLOW_COPY_AND_ASSIGN(PermissionContextBaseTests
);
256 // Simulates clicking Accept. The permission should be granted and
257 // saved for future use.
258 TEST_F(PermissionContextBaseTests
, TestAskAndGrant
) {
259 TestAskAndGrant_TestContent();
260 StartUsingPermissionBubble();
261 TestAskAndGrant_TestContent();
264 // Simulates clicking Dismiss (X) in the infobar/bubble.
265 // The permission should be denied but not saved for future use.
266 TEST_F(PermissionContextBaseTests
, TestAskAndDismiss
) {
267 TestAskAndDismiss_TestContent();
268 StartUsingPermissionBubble();
269 TestAskAndDismiss_TestContent();
272 // Simulates non-valid requesting URL.
273 // The permission should be denied but not saved for future use.
274 TEST_F(PermissionContextBaseTests
, TestNonValidRequestingUrl
) {
275 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
276 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
277 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
278 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
);
279 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
280 TestRequestPermissionInvalidUrl(
281 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
285 // Simulates non-secure requesting URL.
286 // Web MIDI permission should be denied for non-secure origin.
287 // Simulates granting and revoking of permissions.
288 TEST_F(PermissionContextBaseTests
, TestNonSecureRequestingUrl
) {
289 TestRequestPermissionNonSecureUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
292 TEST_F(PermissionContextBaseTests
, TestGrantAndRevoke
) {
293 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
294 CONTENT_SETTING_ASK
);
295 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
296 CONTENT_SETTING_ASK
);
297 #if defined(OS_ANDROID)
298 TestGrantAndRevoke_TestContent(
299 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, CONTENT_SETTING_ASK
);
301 // TODO(timvolodine): currently no test for
302 // CONTENT_SETTINGS_TYPE_NOTIFICATIONS because notification permissions work
303 // differently with infobars as compared to bubbles (crbug.com/453784).
304 // TODO(timvolodine): currently no test for
305 // CONTENT_SETTINGS_TYPE_PUSH_MESSAGING because infobars do not implement push
306 // messaging permissions (crbug.com/453788).
309 // Simulates granting and revoking of permissions using permission bubbles.
310 TEST_F(PermissionContextBaseTests
, TestGrantAndRevokeWithBubbles
) {
311 StartUsingPermissionBubble();
312 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
313 CONTENT_SETTING_ASK
);
314 #if defined(ENABLE_NOTIFICATIONS)
315 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
316 CONTENT_SETTING_ASK
);
318 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
319 CONTENT_SETTING_ASK
);
320 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
,
321 CONTENT_SETTING_ASK
);
322 #if defined(OS_ANDROID)
323 TestGrantAndRevoke_TestContent(
324 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, CONTENT_SETTING_ASK
);