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"
8 #include "base/command_line.h"
9 #include "chrome/browser/infobars/infobar_service.h"
10 #include "chrome/browser/permissions/permission_queue_controller.h"
11 #include "chrome/browser/permissions/permission_request_id.h"
12 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
13 #include "chrome/common/chrome_switches.h"
14 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "components/content_settings/core/browser/host_content_settings_map.h"
17 #include "components/content_settings/core/common/content_settings.h"
18 #include "components/content_settings/core/common/content_settings_types.h"
19 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/test/mock_render_process_host.h"
22 #include "content/public/test/web_contents_tester.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 class TestPermissionContext
: public PermissionContextBase
{
27 TestPermissionContext(Profile
* profile
,
28 const ContentSettingsType permission_type
)
29 : PermissionContextBase(profile
, permission_type
),
30 permission_set_(false),
31 permission_granted_(false),
32 tab_context_updated_(false) {}
34 ~TestPermissionContext() override
{}
36 PermissionQueueController
* GetInfoBarController() {
37 return GetQueueController();
40 bool permission_granted() {
41 return permission_granted_
;
44 bool permission_set() {
45 return permission_set_
;
48 bool tab_context_updated() {
49 return tab_context_updated_
;
52 void TrackPermissionDecision(ContentSetting content_setting
) {
53 permission_set_
= true;
54 permission_granted_
= content_setting
== CONTENT_SETTING_ALLOW
;
58 void UpdateTabContext(const PermissionRequestID
& id
,
59 const GURL
& requesting_origin
,
60 bool allowed
) override
{
61 tab_context_updated_
= true;
64 bool IsRestrictedToSecureOrigins() const override
{
70 bool permission_granted_
;
71 bool tab_context_updated_
;
74 class PermissionContextBaseTests
: public ChromeRenderViewHostTestHarness
{
76 PermissionContextBaseTests() {}
78 // Accept or dismiss the permission bubble or infobar.
79 void RespondToPermission(TestPermissionContext
* context
,
80 const PermissionRequestID
& id
,
83 if (!PermissionBubbleManager::Enabled()) {
84 context
->GetInfoBarController()->OnPermissionSet(
85 id
, url
, url
, accept
, accept
);
89 PermissionBubbleManager
* manager
=
90 PermissionBubbleManager::FromWebContents(web_contents());
97 void TestAskAndGrant_TestContent() {
98 TestPermissionContext
permission_context(
99 profile(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
100 GURL
url("http://www.google.com");
101 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
103 const PermissionRequestID
id(
104 web_contents()->GetRenderProcessHost()->GetID(),
105 web_contents()->GetMainFrame()->GetRoutingID(),
107 permission_context
.RequestPermission(
110 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
111 base::Unretained(&permission_context
)));
113 RespondToPermission(&permission_context
, id
, url
, true);
114 EXPECT_TRUE(permission_context
.permission_set());
115 EXPECT_TRUE(permission_context
.permission_granted());
116 EXPECT_TRUE(permission_context
.tab_context_updated());
118 ContentSetting setting
=
119 profile()->GetHostContentSettingsMap()->GetContentSetting(
120 url
.GetOrigin(), url
.GetOrigin(),
121 CONTENT_SETTINGS_TYPE_NOTIFICATIONS
, std::string());
122 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
125 void TestAskAndDismiss_TestContent() {
126 TestPermissionContext
permission_context(
127 profile(), CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
128 GURL
url("http://www.google.es");
129 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
131 const PermissionRequestID
id(
132 web_contents()->GetRenderProcessHost()->GetID(),
133 web_contents()->GetMainFrame()->GetRoutingID(),
135 permission_context
.RequestPermission(
138 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
139 base::Unretained(&permission_context
)));
141 RespondToPermission(&permission_context
, id
, url
, false);
142 EXPECT_TRUE(permission_context
.permission_set());
143 EXPECT_FALSE(permission_context
.permission_granted());
144 EXPECT_TRUE(permission_context
.tab_context_updated());
146 ContentSetting setting
=
147 profile()->GetHostContentSettingsMap()->GetContentSetting(
148 url
.GetOrigin(), url
.GetOrigin(),
149 CONTENT_SETTINGS_TYPE_MIDI_SYSEX
, std::string());
150 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
153 void TestRequestPermissionInvalidUrl(ContentSettingsType type
) {
154 TestPermissionContext
permission_context(profile(), type
);
156 ASSERT_FALSE(url
.is_valid());
157 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
159 const PermissionRequestID
id(
160 web_contents()->GetRenderProcessHost()->GetID(),
161 web_contents()->GetMainFrame()->GetRoutingID(),
163 permission_context
.RequestPermission(
166 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
167 base::Unretained(&permission_context
)));
169 EXPECT_TRUE(permission_context
.permission_set());
170 EXPECT_FALSE(permission_context
.permission_granted());
171 EXPECT_TRUE(permission_context
.tab_context_updated());
173 ContentSetting setting
=
174 profile()->GetHostContentSettingsMap()->GetContentSetting(
175 url
.GetOrigin(), url
.GetOrigin(), type
, std::string());
176 EXPECT_EQ(CONTENT_SETTING_ASK
, setting
);
179 void TestGrantAndRevoke_TestContent(ContentSettingsType type
,
180 ContentSetting expected_default
) {
181 TestPermissionContext
permission_context(profile(), type
);
182 GURL
url("https://www.google.com");
183 content::WebContentsTester::For(web_contents())->NavigateAndCommit(url
);
185 const PermissionRequestID
id(
186 web_contents()->GetRenderProcessHost()->GetID(),
187 web_contents()->GetMainFrame()->GetRoutingID(),
189 permission_context
.RequestPermission(
192 base::Bind(&TestPermissionContext::TrackPermissionDecision
,
193 base::Unretained(&permission_context
)));
195 RespondToPermission(&permission_context
, id
, url
, true);
196 EXPECT_TRUE(permission_context
.permission_set());
197 EXPECT_TRUE(permission_context
.permission_granted());
198 EXPECT_TRUE(permission_context
.tab_context_updated());
200 ContentSetting setting
=
201 profile()->GetHostContentSettingsMap()->GetContentSetting(
202 url
.GetOrigin(), url
.GetOrigin(),
203 type
, std::string());
204 EXPECT_EQ(CONTENT_SETTING_ALLOW
, setting
);
206 // Try to reset permission.
207 permission_context
.ResetPermission(url
.GetOrigin(), url
.GetOrigin());
208 ContentSetting setting_after_reset
=
209 profile()->GetHostContentSettingsMap()->GetContentSetting(
210 url
.GetOrigin(), url
.GetOrigin(),
211 type
, std::string());
212 ContentSetting default_setting
=
213 profile()->GetHostContentSettingsMap()->GetDefaultContentSetting(
215 EXPECT_EQ(default_setting
, setting_after_reset
);
219 // ChromeRenderViewHostTestHarness:
220 void SetUp() override
{
221 ChromeRenderViewHostTestHarness::SetUp();
222 InfoBarService::CreateForWebContents(web_contents());
223 PermissionBubbleManager::CreateForWebContents(web_contents());
226 DISALLOW_COPY_AND_ASSIGN(PermissionContextBaseTests
);
229 // Simulates clicking Accept. The permission should be granted and
230 // saved for future use.
231 TEST_F(PermissionContextBaseTests
, TestAskAndGrant
) {
232 TestAskAndGrant_TestContent();
235 // Simulates clicking Dismiss (X) in the infobar/bubble.
236 // The permission should be denied but not saved for future use.
237 TEST_F(PermissionContextBaseTests
, TestAskAndDismiss
) {
238 TestAskAndDismiss_TestContent();
241 // Simulates non-valid requesting URL.
242 // The permission should be denied but not saved for future use.
243 TEST_F(PermissionContextBaseTests
, TestNonValidRequestingUrl
) {
244 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_GEOLOCATION
);
245 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);
246 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
);
247 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
);
248 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
249 TestRequestPermissionInvalidUrl(
250 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
);
254 #if defined(OS_ANDROID)
255 // This test is specific to Android because other platforms use bubbles.
256 TEST_F(PermissionContextBaseTests
, TestGrantAndRevokeWithInfobars
) {
257 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
258 CONTENT_SETTING_ASK
);
259 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
260 CONTENT_SETTING_ASK
);
261 TestGrantAndRevoke_TestContent(
262 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
, CONTENT_SETTING_ASK
);
263 // TODO(timvolodine): currently no test for
264 // CONTENT_SETTINGS_TYPE_NOTIFICATIONS because notification permissions work
265 // differently with infobars as compared to bubbles (crbug.com/453784).
266 // TODO(timvolodine): currently no test for
267 // CONTENT_SETTINGS_TYPE_PUSH_MESSAGING because infobars do not implement push
268 // messaging permissions (crbug.com/453788).
272 #if !defined(OS_ANDROID) && !defined(OS_IOS)
273 // Simulates granting and revoking of permissions using permission bubbles.
274 // This test shouldn't run on mobile because mobile platforms use infobars.
275 TEST_F(PermissionContextBaseTests
, TestGrantAndRevokeWithBubbles
) {
276 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION
,
277 CONTENT_SETTING_ASK
);
278 #if defined(ENABLE_NOTIFICATIONS)
279 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS
,
280 CONTENT_SETTING_ASK
);
282 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX
,
283 CONTENT_SETTING_ASK
);
284 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
,
285 CONTENT_SETTING_ASK
);