blob: 655dcf2ac6418558da9a9c1d59050400125b3ff4 [file] [log] [blame]
[email protected]89a8dd5d2014-07-11 12:02:071// 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
lalitmca47d9c42015-07-08 13:48:145#include "chrome/browser/permissions/permission_context_base.h"
[email protected]89a8dd5d2014-07-11 12:02:076
thestig9bdf7f22016-09-28 00:56:207#include <map>
meredithl62b8c3d2017-01-10 05:47:538#include <set>
thestig9bdf7f22016-09-28 00:56:209#include <string>
10#include <utility>
johnme7fa91f72016-01-29 22:13:4411#include <vector>
12
[email protected]89a8dd5d2014-07-11 12:02:0713#include "base/bind.h"
dominickn6947d752016-08-10 02:00:0614#include "base/feature_list.h"
avib896c712015-12-26 02:10:4315#include "base/macros.h"
robliao79393ffb2016-09-21 18:45:2916#include "base/memory/ptr_util.h"
kcarattini2ee48ad52015-10-26 23:45:3117#include "base/metrics/field_trial.h"
meredithl62b8c3d2017-01-10 05:47:5318#include "base/run_loop.h"
dominickn6947d752016-08-10 02:00:0619#include "base/test/histogram_tester.h"
kcarattini2ee48ad52015-10-26 23:45:3120#include "base/test/mock_entropy_provider.h"
dominicknc2726ec2016-09-15 12:15:3921#include "base/test/scoped_feature_list.h"
avib896c712015-12-26 02:10:4322#include "build/build_config.h"
peconn5100d432015-09-16 12:03:0823#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
[email protected]89a8dd5d2014-07-11 12:02:0724#include "chrome/browser/infobars/infobar_service.h"
dominickn6947d752016-08-10 02:00:0625#include "chrome/browser/permissions/permission_decision_auto_blocker.h"
kcarattini2ee48ad52015-10-26 23:45:3126#include "chrome/browser/permissions/permission_queue_controller.h"
mlamouridfbf5692015-06-06 18:53:4127#include "chrome/browser/permissions/permission_request_id.h"
timloh90e8cec2017-05-22 04:26:1928#include "chrome/browser/permissions/permission_request_manager.h"
dominickn79b96cc2017-02-14 04:14:2129#include "chrome/browser/permissions/permission_uma_util.h"
kcarattini2ee48ad52015-10-26 23:45:3130#include "chrome/browser/permissions/permission_util.h"
timloh86d8eaf2017-05-09 03:43:0931#include "chrome/browser/ui/permission_bubble/mock_permission_prompt_factory.h"
dominickn6947d752016-08-10 02:00:0632#include "chrome/common/chrome_features.h"
felt88bf98cb2014-12-16 03:50:2333#include "chrome/common/chrome_switches.h"
[email protected]89a8dd5d2014-07-11 12:02:0734#include "chrome/test/base/chrome_render_view_host_test_harness.h"
35#include "chrome/test/base/testing_profile.h"
mukai8eaec822014-10-25 17:53:1636#include "components/content_settings/core/browser/host_content_settings_map.h"
mukai077089f2014-09-11 18:41:5237#include "components/content_settings/core/common/content_settings.h"
[email protected]08f71012014-07-25 10:27:5438#include "components/content_settings/core/common/content_settings_types.h"
meredithl62b8c3d2017-01-10 05:47:5339#include "components/safe_browsing_db/database_manager.h"
40#include "components/safe_browsing_db/test_database_manager.h"
kcarattini2ee48ad52015-10-26 23:45:3141#include "components/variations/variations_associated_data.h"
meredithl62b8c3d2017-01-10 05:47:5342#include "content/public/browser/browser_thread.h"
mlamouri5fc460f2015-06-03 17:30:2843#include "content/public/browser/render_frame_host.h"
[email protected]89a8dd5d2014-07-11 12:02:0744#include "content/public/browser/web_contents.h"
45#include "content/public/test/mock_render_process_host.h"
[email protected]89a8dd5d2014-07-11 12:02:0746#include "testing/gtest/include/gtest/gtest.h"
47
thestig9bdf7f22016-09-28 00:56:2048const char* const kPermissionsKillSwitchFieldStudy =
kcarattini2ee48ad52015-10-26 23:45:3149 PermissionContextBase::kPermissionsKillSwitchFieldStudy;
thestig9bdf7f22016-09-28 00:56:2050const char* const kPermissionsKillSwitchBlockedValue =
kcarattini2ee48ad52015-10-26 23:45:3151 PermissionContextBase::kPermissionsKillSwitchBlockedValue;
52const char kPermissionsKillSwitchTestGroup[] = "TestGroup";
thestig9bdf7f22016-09-28 00:56:2053const char* const kPromptGroupName = kPermissionsKillSwitchTestGroup;
dominickn6947d752016-08-10 02:00:0654const char kPromptTrialName[] = "PermissionPromptsUX";
kcarattini2ee48ad52015-10-26 23:45:3155
meredithl48ad16812017-02-08 03:15:3756namespace {
57
meredithl62b8c3d2017-01-10 05:47:5358class MockSafeBrowsingDatabaseManager
59 : public safe_browsing::TestSafeBrowsingDatabaseManager {
60 public:
61 explicit MockSafeBrowsingDatabaseManager(bool perform_callback)
62 : perform_callback_(perform_callback) {}
63
64 bool CheckApiBlacklistUrl(
65 const GURL& url,
66 safe_browsing::SafeBrowsingDatabaseManager::Client* client) override {
67 if (perform_callback_) {
68 safe_browsing::ThreatMetadata metadata;
69 const auto& blacklisted_permissions = permissions_blacklist_.find(url);
70 if (blacklisted_permissions != permissions_blacklist_.end())
71 metadata.api_permissions = blacklisted_permissions->second;
72 client->OnCheckApiBlacklistUrlResult(url, metadata);
73 }
74 // Returns false if scheme is HTTP/HTTPS and able to be checked.
75 return false;
76 }
77
78 bool CancelApiCheck(Client* client) override {
79 DCHECK(!perform_callback_);
80 // Returns true when client check could be stopped.
81 return true;
82 }
83
84 void BlacklistUrlPermissions(const GURL& url,
85 const std::set<std::string> permissions) {
86 permissions_blacklist_[url] = permissions;
87 }
88
89 protected:
90 ~MockSafeBrowsingDatabaseManager() override {}
91
92 private:
93 bool perform_callback_;
94 std::map<GURL, std::set<std::string>> permissions_blacklist_;
95
96 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
97};
98
meredithl48ad16812017-02-08 03:15:3799} // namespace
100
[email protected]89a8dd5d2014-07-11 12:02:07101class TestPermissionContext : public PermissionContextBase {
102 public:
103 TestPermissionContext(Profile* profile,
lshang88ec36a2015-12-09 04:50:17104 const ContentSettingsType content_settings_type)
timloh9a180ad2017-02-20 07:15:23105 : PermissionContextBase(profile, content_settings_type),
dominickn6947d752016-08-10 02:00:06106 tab_context_updated_(false) {}
[email protected]89a8dd5d2014-07-11 12:02:07107
Daniel Chenga542fca2014-10-21 09:51:29108 ~TestPermissionContext() override {}
[email protected]89a8dd5d2014-07-11 12:02:07109
estade6d95d1d2015-10-02 18:55:23110#if defined(OS_ANDROID)
[email protected]89a8dd5d2014-07-11 12:02:07111 PermissionQueueController* GetInfoBarController() {
112 return GetQueueController();
113 }
estade6d95d1d2015-10-02 18:55:23114#endif
[email protected]89a8dd5d2014-07-11 12:02:07115
thestig9bdf7f22016-09-28 00:56:20116 const std::vector<ContentSetting>& decisions() const { return decisions_; }
[email protected]89a8dd5d2014-07-11 12:02:07117
thestig9bdf7f22016-09-28 00:56:20118 bool tab_context_updated() const { return tab_context_updated_; }
[email protected]89a8dd5d2014-07-11 12:02:07119
meredithl62b8c3d2017-01-10 05:47:53120 // Once a decision for the requested permission has been made, run the
121 // callback.
mlamouridf357a312015-03-03 17:34:05122 void TrackPermissionDecision(ContentSetting content_setting) {
johnme7fa91f72016-01-29 22:13:44123 decisions_.push_back(content_setting);
meredithl62b8c3d2017-01-10 05:47:53124 // Null check required here as the quit_closure_ can also be run and reset
125 // first from within DecidePermission.
126 if (quit_closure_) {
127 quit_closure_.Run();
128 quit_closure_.Reset();
129 }
[email protected]89a8dd5d2014-07-11 12:02:07130 }
131
johnmec41dfee2016-01-13 14:35:16132 ContentSetting GetContentSettingFromMap(const GURL& url_a,
133 const GURL& url_b) {
thestig9bdf7f22016-09-28 00:56:20134 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
135 return map->GetContentSetting(url_a.GetOrigin(), url_b.GetOrigin(),
timloh9a180ad2017-02-20 07:15:23136 content_settings_storage_type(),
137 std::string());
johnmec41dfee2016-01-13 14:35:16138 }
139
meredithl62b8c3d2017-01-10 05:47:53140 void RequestPermission(content::WebContents* web_contents,
141 const PermissionRequestID& id,
142 const GURL& requesting_frame,
143 bool user_gesture,
144 const BrowserPermissionCallback& callback) override {
145 base::RunLoop run_loop;
146 quit_closure_ = run_loop.QuitClosure();
147 PermissionContextBase::RequestPermission(web_contents, id, requesting_frame,
148 true /* user_gesture */, callback);
149 run_loop.Run();
150 }
151
152 void DecidePermission(content::WebContents* web_contents,
153 const PermissionRequestID& id,
154 const GURL& requesting_origin,
155 const GURL& embedding_origin,
156 bool user_gesture,
157 const BrowserPermissionCallback& callback) override {
158 PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
159 embedding_origin, user_gesture,
160 callback);
161 if (respond_permission_) {
162 respond_permission_.Run();
163 respond_permission_.Reset();
164 } else {
165 // Stop the run loop from spinning indefinitely if no response callback
166 // has been set, as is the case with TestParallelRequests.
167 quit_closure_.Run();
168 quit_closure_.Reset();
169 }
170 }
171
meredithl03b12852017-01-25 05:08:01172 // Set the callback to run if the permission is being responded to in the
173 // test. This is left empty where no response is needed, such as in parallel
174 // requests, permissions blacklisting, invalid origin, and killswitch.
meredithl62b8c3d2017-01-10 05:47:53175 void SetRespondPermissionCallback(base::Closure callback) {
176 respond_permission_ = callback;
177 }
178
[email protected]89a8dd5d2014-07-11 12:02:07179 protected:
Daniel Chenga542fca2014-10-21 09:51:29180 void UpdateTabContext(const PermissionRequestID& id,
181 const GURL& requesting_origin,
182 bool allowed) override {
[email protected]89a8dd5d2014-07-11 12:02:07183 tab_context_updated_ = true;
184 }
185
dominickn2e27dea2017-02-23 23:00:25186 bool IsRestrictedToSecureOrigins() const override { return false; }
mlamouria31c6ff12015-06-01 15:40:52187
[email protected]89a8dd5d2014-07-11 12:02:07188 private:
johnme7fa91f72016-01-29 22:13:44189 std::vector<ContentSetting> decisions_;
190 bool tab_context_updated_;
meredithl62b8c3d2017-01-10 05:47:53191 base::Closure quit_closure_;
192 // Callback for responding to a permission once the request has been completed
193 // (valid URL, kill switch disabled, not blacklisted)
194 base::Closure respond_permission_;
thestig9bdf7f22016-09-28 00:56:20195 DISALLOW_COPY_AND_ASSIGN(TestPermissionContext);
dominickn6947d752016-08-10 02:00:06196};
197
198class TestKillSwitchPermissionContext : public TestPermissionContext {
199 public:
200 TestKillSwitchPermissionContext(
201 Profile* profile,
dominickn6947d752016-08-10 02:00:06202 const ContentSettingsType content_settings_type)
timloh9a180ad2017-02-20 07:15:23203 : TestPermissionContext(profile, content_settings_type),
thestig9bdf7f22016-09-28 00:56:20204 field_trial_list_(base::MakeUnique<base::FieldTrialList>(
205 base::MakeUnique<base::MockEntropyProvider>())) {}
dominickn6947d752016-08-10 02:00:06206
207 void ResetFieldTrialList() {
208 // Destroy the existing FieldTrialList before creating a new one to avoid
209 // a DCHECK.
210 field_trial_list_.reset();
thestig9bdf7f22016-09-28 00:56:20211 field_trial_list_ = base::MakeUnique<base::FieldTrialList>(
212 base::MakeUnique<base::MockEntropyProvider>());
dominickn6947d752016-08-10 02:00:06213 variations::testing::ClearAllVariationParams();
214 }
215
216 private:
dcheng4af48582016-04-19 00:29:35217 std::unique_ptr<base::FieldTrialList> field_trial_list_;
thestig9bdf7f22016-09-28 00:56:20218
219 DISALLOW_COPY_AND_ASSIGN(TestKillSwitchPermissionContext);
[email protected]89a8dd5d2014-07-11 12:02:07220};
221
timloh90e8cec2017-05-22 04:26:19222enum class TestType {
223 PERMISSION_REQUEST_MANAGER,
224 PERMISSION_QUEUE_CONTROLLER,
225};
226
227class PermissionContextBaseTests
228 : public ChromeRenderViewHostTestHarness,
229 public ::testing::WithParamInterface<TestType> {
felt88bf98cb2014-12-16 03:50:23230 protected:
231 PermissionContextBaseTests() {}
thestig9bdf7f22016-09-28 00:56:20232 ~PermissionContextBaseTests() override {}
felt88bf98cb2014-12-16 03:50:23233
234 // Accept or dismiss the permission bubble or infobar.
235 void RespondToPermission(TestPermissionContext* context,
236 const PermissionRequestID& id,
237 const GURL& url,
dominicknd4e446a2016-09-13 07:44:13238 bool persist,
johnme7fa91f72016-01-29 22:13:44239 ContentSetting response) {
240 DCHECK(response == CONTENT_SETTING_ALLOW ||
241 response == CONTENT_SETTING_BLOCK ||
242 response == CONTENT_SETTING_ASK);
timloh90e8cec2017-05-22 04:26:19243 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
244 PermissionRequestManager* manager =
245 PermissionRequestManager::FromWebContents(web_contents());
246 manager->TogglePersist(persist);
247 using AutoResponseType = PermissionRequestManager::AutoResponseType;
248 AutoResponseType decision = AutoResponseType::DISMISS;
249 if (response == CONTENT_SETTING_ALLOW)
250 decision = AutoResponseType::ACCEPT_ALL;
251 else if (response == CONTENT_SETTING_BLOCK)
252 decision = AutoResponseType::DENY_ALL;
253 prompt_factory_->set_response_type(decision);
254 } else {
estade6d95d1d2015-10-02 18:55:23255#if defined(OS_ANDROID)
timloh90e8cec2017-05-22 04:26:19256 PermissionAction decision = PermissionAction::DISMISSED;
257 if (response == CONTENT_SETTING_ALLOW)
258 decision = PermissionAction::GRANTED;
259 else if (response == CONTENT_SETTING_BLOCK)
260 decision = PermissionAction::DENIED;
261 context->GetInfoBarController()->OnPermissionSet(
262 id, url, url, false /* user_gesture */, persist, decision);
estade6d95d1d2015-10-02 18:55:23263#endif
timloh90e8cec2017-05-22 04:26:19264 }
felt88bf98cb2014-12-16 03:50:23265 }
266
timloh9a180ad2017-02-20 07:15:23267 void TestAskAndDecide_TestContent(ContentSettingsType content_settings_type,
dominicknd4e446a2016-09-13 07:44:13268 ContentSetting decision,
269 bool persist) {
timloh9a180ad2017-02-20 07:15:23270 TestPermissionContext permission_context(profile(), content_settings_type);
dominicknd4e446a2016-09-13 07:44:13271 GURL url("https://www.google.com");
timloh86d8eaf2017-05-09 03:43:09272 SetUpUrl(url);
dominickn6da2b382016-08-23 20:21:30273 base::HistogramTester histograms;
felt88bf98cb2014-12-16 03:50:23274
275 const PermissionRequestID id(
276 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25277 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl62b8c3d2017-01-10 05:47:53278 permission_context.SetRespondPermissionCallback(
279 base::Bind(&PermissionContextBaseTests::RespondToPermission,
280 base::Unretained(this), &permission_context, id, url,
281 persist, decision));
felt88bf98cb2014-12-16 03:50:23282 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25283 web_contents(), id, url, true /* user_gesture */,
felt88bf98cb2014-12-16 03:50:23284 base::Bind(&TestPermissionContext::TrackPermissionDecision,
285 base::Unretained(&permission_context)));
thestig9bdf7f22016-09-28 00:56:20286 ASSERT_EQ(1u, permission_context.decisions().size());
dominicknd4e446a2016-09-13 07:44:13287 EXPECT_EQ(decision, permission_context.decisions()[0]);
felt88bf98cb2014-12-16 03:50:23288 EXPECT_TRUE(permission_context.tab_context_updated());
dominickn6da2b382016-08-23 20:21:30289
thestig9bdf7f22016-09-28 00:56:20290 std::string decision_string;
dominicknd4e446a2016-09-13 07:44:13291 if (decision == CONTENT_SETTING_ALLOW)
292 decision_string = "Accepted";
293 else if (decision == CONTENT_SETTING_BLOCK)
294 decision_string = "Denied";
295 else if (decision == CONTENT_SETTING_ASK)
296 decision_string = "Dismissed";
felt88bf98cb2014-12-16 03:50:23297
dominicknd4e446a2016-09-13 07:44:13298 if (decision_string.size()) {
299 histograms.ExpectUniqueSample(
300 "Permissions.Prompt." + decision_string + ".PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23301 PermissionUtil::GetPermissionString(content_settings_type),
dominicknd4e446a2016-09-13 07:44:13302 0, 1);
303 histograms.ExpectUniqueSample(
304 "Permissions.Prompt." + decision_string + ".PriorIgnoreCount." +
timloh9a180ad2017-02-20 07:15:23305 PermissionUtil::GetPermissionString(content_settings_type),
dominicknd4e446a2016-09-13 07:44:13306 0, 1);
307 }
felt88bf98cb2014-12-16 03:50:23308
dominicknd4e446a2016-09-13 07:44:13309 if (persist) {
310 EXPECT_EQ(decision,
311 permission_context.GetContentSettingFromMap(url, url));
312 } else {
313 EXPECT_EQ(CONTENT_SETTING_ASK,
314 permission_context.GetContentSettingFromMap(url, url));
315 }
dominickn79b96cc2017-02-14 04:14:21316
dominickn23913152017-02-23 12:04:02317 histograms.ExpectUniqueSample(
318 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25319 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);
320 histograms.ExpectUniqueSample(
321 "Permissions.AutoBlocker.EmbargoStatus",
322 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);
felt88bf98cb2014-12-16 03:50:23323 }
324
dominickn6947d752016-08-10 02:00:06325 void DismissMultipleTimesAndExpectBlock(
326 const GURL& url,
dominickn6947d752016-08-10 02:00:06327 ContentSettingsType content_settings_type,
328 uint32_t iterations) {
329 base::HistogramTester histograms;
330
331 // Dismiss |iterations| times. The final dismiss should change the decision
332 // from dismiss to block, and hence change the persisted content setting.
333 for (uint32_t i = 0; i < iterations; ++i) {
timloh9a180ad2017-02-20 07:15:23334 TestPermissionContext permission_context(profile(),
335 content_settings_type);
dominickn6947d752016-08-10 02:00:06336 const PermissionRequestID id(
337 web_contents()->GetRenderProcessHost()->GetID(),
338 web_contents()->GetMainFrame()->GetRoutingID(), i);
meredithl62b8c3d2017-01-10 05:47:53339
340 permission_context.SetRespondPermissionCallback(
341 base::Bind(&PermissionContextBaseTests::RespondToPermission,
342 base::Unretained(this), &permission_context, id, url,
343 false, CONTENT_SETTING_ASK));
344
dominickn6947d752016-08-10 02:00:06345 permission_context.RequestPermission(
346 web_contents(), id, url, true /* user_gesture */,
347 base::Bind(&TestPermissionContext::TrackPermissionDecision,
dominickn2e27dea2017-02-23 23:00:25348 base::Unretained(&permission_context)));
dominickn6947d752016-08-10 02:00:06349 histograms.ExpectTotalCount(
dominickn6da2b382016-08-23 20:21:30350 "Permissions.Prompt.Dismissed.PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23351 PermissionUtil::GetPermissionString(content_settings_type),
dominickn6947d752016-08-10 02:00:06352 i + 1);
dominickn6da2b382016-08-23 20:21:30353 histograms.ExpectBucketCount(
354 "Permissions.Prompt.Dismissed.PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23355 PermissionUtil::GetPermissionString(content_settings_type),
dominickn6da2b382016-08-23 20:21:30356 i, 1);
dominickn23913152017-02-23 12:04:02357
timloh90e8cec2017-05-22 04:26:19358 // On Android, repeatedly requesting and deciding permissions has the side
359 // effect of overcounting any metrics recorded in the
360 // PermissionInfoBarDelegate destructor. This is because we directly call
361 // PermissionQueueController::OnPermissionSet without setting the
362 // action_taken bit in PermissionInfoBarDelegate. When
363 // PermissionQueueController is deleted these expectations can be made
364 // unconditional.
365 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
366 histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
367 i + 1);
368 }
dominickn23913152017-02-23 12:04:02369
raymesf6104d492017-03-09 01:20:18370 PermissionResult result = permission_context.GetPermissionStatus(
371 nullptr /* render_frame_host */, url, url);
dominickn23913152017-02-23 12:04:02372
373 histograms.ExpectUniqueSample(
374 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25375 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn79b96cc2017-02-14 04:14:21376 if (i < 2) {
dominickn23913152017-02-23 12:04:02377 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
378 EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
timloh90e8cec2017-05-22 04:26:19379 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
380 histograms.ExpectUniqueSample(
381 "Permissions.AutoBlocker.EmbargoStatus",
382 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
383 }
dominickn79b96cc2017-02-14 04:14:21384 } else {
dominickn23913152017-02-23 12:04:02385 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
386 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
timloh90e8cec2017-05-22 04:26:19387 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
388 histograms.ExpectBucketCount(
389 "Permissions.AutoBlocker.EmbargoStatus",
390 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS),
391 1);
392 }
dominickn79b96cc2017-02-14 04:14:21393 }
394
thestig9bdf7f22016-09-28 00:56:20395 ASSERT_EQ(1u, permission_context.decisions().size());
dominickn79b96cc2017-02-14 04:14:21396 EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
dominickn6947d752016-08-10 02:00:06397 EXPECT_TRUE(permission_context.tab_context_updated());
dominickn6947d752016-08-10 02:00:06398 }
399
timloh9a180ad2017-02-20 07:15:23400 TestPermissionContext permission_context(profile(), content_settings_type);
meredithl03b12852017-01-25 05:08:01401 const PermissionRequestID id(
402 web_contents()->GetRenderProcessHost()->GetID(),
403 web_contents()->GetMainFrame()->GetRoutingID(), -1);
404
405 permission_context.SetRespondPermissionCallback(
406 base::Bind(&PermissionContextBaseTests::RespondToPermission,
407 base::Unretained(this), &permission_context, id, url, false,
408 CONTENT_SETTING_ASK));
409
410 permission_context.RequestPermission(
411 web_contents(), id, url, true /* user_gesture */,
412 base::Bind(&TestPermissionContext::TrackPermissionDecision,
413 base::Unretained(&permission_context)));
meredithlcda94daf2017-01-19 03:03:35414
raymesf6104d492017-03-09 01:20:18415 PermissionResult result = permission_context.GetPermissionStatus(
416 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25417 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
dominickn23913152017-02-23 12:04:02418 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
419 histograms.ExpectBucketCount(
420 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25421 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
dominickn6947d752016-08-10 02:00:06422 }
423
424 void TestBlockOnSeveralDismissals_TestContent() {
425 GURL url("https://www.google.com");
timloh86d8eaf2017-05-09 03:43:09426 SetUpUrl(url);
dominickn6947d752016-08-10 02:00:06427 base::HistogramTester histograms;
428
dominickn5b41f222017-05-11 03:44:26429 {
430 // Ensure that > 3 dismissals behaves correctly when the
431 // BlockPromptsIfDismissedOften feature is off.
432 base::test::ScopedFeatureList feature_list;
timloh90e8cec2017-05-22 04:26:19433 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
434 feature_list.InitWithFeatures(
435 {features::kUseGroupedPermissionInfobars},
436 {features::kBlockPromptsIfDismissedOften});
437 } else {
438 feature_list.InitWithFeatures(
439 {}, {features::kUseGroupedPermissionInfobars,
440 features::kBlockPromptsIfDismissedOften});
441 }
dominickn6947d752016-08-10 02:00:06442
dominickn5b41f222017-05-11 03:44:26443 for (uint32_t i = 0; i < 4; ++i) {
444 TestPermissionContext permission_context(
445 profile(), CONTENT_SETTINGS_TYPE_GEOLOCATION);
meredithl62b8c3d2017-01-10 05:47:53446
dominickn5b41f222017-05-11 03:44:26447 const PermissionRequestID id(
448 web_contents()->GetRenderProcessHost()->GetID(),
449 web_contents()->GetMainFrame()->GetRoutingID(), i);
450
451 permission_context.SetRespondPermissionCallback(
452 base::Bind(&PermissionContextBaseTests::RespondToPermission,
453 base::Unretained(this), &permission_context, id, url,
454 false, CONTENT_SETTING_ASK));
455 permission_context.RequestPermission(
456 web_contents(), id, url, true /* user_gesture */,
457 base::Bind(&TestPermissionContext::TrackPermissionDecision,
458 base::Unretained(&permission_context)));
459 histograms.ExpectTotalCount(
460 "Permissions.Prompt.Dismissed.PriorDismissCount.Geolocation",
461 i + 1);
462 histograms.ExpectBucketCount(
463 "Permissions.Prompt.Dismissed.PriorDismissCount.Geolocation", i, 1);
464 histograms.ExpectUniqueSample(
465 "Permissions.AutoBlocker.EmbargoPromptSuppression",
466 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn23913152017-02-23 12:04:02467
timloh90e8cec2017-05-22 04:26:19468 // On Android, repeatedly requesting and deciding permissions has the
469 // side effect of overcounting any metrics recorded in the
470 // PermissionInfoBarDelegate destructor. This is because we directly
471 // call PermissionQueueController::OnPermissionSet without setting the
472 // action_taken bit in PermissionInfoBarDelegate. When
473 // PermissionQueueController is deleted this expectation can be made
474 // unconditional.
475 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
476 histograms.ExpectUniqueSample(
477 "Permissions.AutoBlocker.EmbargoStatus",
478 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
479 }
dominickn79b96cc2017-02-14 04:14:21480
dominickn5b41f222017-05-11 03:44:26481 ASSERT_EQ(1u, permission_context.decisions().size());
482 EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
483 EXPECT_TRUE(permission_context.tab_context_updated());
484 EXPECT_EQ(CONTENT_SETTING_ASK,
485 permission_context.GetContentSettingFromMap(url, url));
486 }
487
488 // Flush the dismissal counts.
489 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
490 map->ClearSettingsForOneType(
491 CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA);
dominickn6947d752016-08-10 02:00:06492 }
493
dominickn6947d752016-08-10 02:00:06494 EXPECT_TRUE(
495 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
496
497 // Sanity check independence per permission type by checking two of them.
dominickn2e27dea2017-02-23 23:00:25498 DismissMultipleTimesAndExpectBlock(url, CONTENT_SETTINGS_TYPE_GEOLOCATION,
499 3);
500 DismissMultipleTimesAndExpectBlock(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
501 3);
dominickn6947d752016-08-10 02:00:06502 }
503
504 void TestVariationBlockOnSeveralDismissals_TestContent() {
505 GURL url("https://www.google.com");
timloh86d8eaf2017-05-09 03:43:09506 SetUpUrl(url);
dominickn6da2b382016-08-23 20:21:30507 base::HistogramTester histograms;
dominickn6947d752016-08-10 02:00:06508
509 // Set up the custom parameter and custom value.
thestig9bdf7f22016-09-28 00:56:20510 base::FieldTrialList field_trials(nullptr);
dominickn6947d752016-08-10 02:00:06511 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
512 kPromptTrialName, kPromptGroupName);
513 std::map<std::string, std::string> params;
514 params[PermissionDecisionAutoBlocker::kPromptDismissCountKey] = "5";
dominickn2e27dea2017-02-23 23:00:25515 ASSERT_TRUE(variations::AssociateVariationParams(kPromptTrialName,
516 kPromptGroupName, params));
dominickn6947d752016-08-10 02:00:06517
thestig9bdf7f22016-09-28 00:56:20518 std::unique_ptr<base::FeatureList> feature_list =
519 base::MakeUnique<base::FeatureList>();
timloh90e8cec2017-05-22 04:26:19520 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
521 feature_list->InitializeFromCommandLine(
522 features::kUseGroupedPermissionInfobars.name, "");
523 } else {
524 feature_list->InitializeFromCommandLine(
525 "", features::kUseGroupedPermissionInfobars.name);
526 }
dominickn6947d752016-08-10 02:00:06527 feature_list->RegisterFieldTrialOverride(
528 features::kBlockPromptsIfDismissedOften.name,
529 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
thestig9bdf7f22016-09-28 00:56:20530
531 base::test::ScopedFeatureList scoped_feature_list;
532 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
533
dominickn6947d752016-08-10 02:00:06534 EXPECT_EQ(base::FeatureList::GetFieldTrial(
535 features::kBlockPromptsIfDismissedOften),
536 trial);
537
thestig9bdf7f22016-09-28 00:56:20538 {
539 std::map<std::string, std::string> actual_params;
540 EXPECT_TRUE(variations::GetVariationParamsByFeature(
541 features::kBlockPromptsIfDismissedOften, &actual_params));
542 EXPECT_EQ(params, actual_params);
543 }
dominickn6947d752016-08-10 02:00:06544
545 for (uint32_t i = 0; i < 5; ++i) {
546 TestPermissionContext permission_context(
timloh9a180ad2017-02-20 07:15:23547 profile(), CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
dominickn6947d752016-08-10 02:00:06548
dominickn6947d752016-08-10 02:00:06549 const PermissionRequestID id(
550 web_contents()->GetRenderProcessHost()->GetID(),
551 web_contents()->GetMainFrame()->GetRoutingID(), i);
meredithl62b8c3d2017-01-10 05:47:53552 permission_context.SetRespondPermissionCallback(
553 base::Bind(&PermissionContextBaseTests::RespondToPermission,
554 base::Unretained(this), &permission_context, id, url,
555 false, CONTENT_SETTING_ASK));
dominickn6947d752016-08-10 02:00:06556 permission_context.RequestPermission(
557 web_contents(), id, url, true /* user_gesture */,
558 base::Bind(&TestPermissionContext::TrackPermissionDecision,
meredithl62b8c3d2017-01-10 05:47:53559 base::Unretained(&permission_context)));
dominickn6947d752016-08-10 02:00:06560
dominickn6947d752016-08-10 02:00:06561 EXPECT_EQ(1u, permission_context.decisions().size());
dominickn79b96cc2017-02-14 04:14:21562 ASSERT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
dominickn6947d752016-08-10 02:00:06563 EXPECT_TRUE(permission_context.tab_context_updated());
raymesf6104d492017-03-09 01:20:18564 PermissionResult result = permission_context.GetPermissionStatus(
565 nullptr /* render_frame_host */, url, url);
dominickn6da2b382016-08-23 20:21:30566
567 histograms.ExpectTotalCount(
568 "Permissions.Prompt.Dismissed.PriorDismissCount.MidiSysEx", i + 1);
569 histograms.ExpectBucketCount(
570 "Permissions.Prompt.Dismissed.PriorDismissCount.MidiSysEx", i, 1);
dominickn23913152017-02-23 12:04:02571 histograms.ExpectUniqueSample(
572 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25573 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn79b96cc2017-02-14 04:14:21574
timloh90e8cec2017-05-22 04:26:19575 // On Android, repeatedly requesting and deciding permissions has the side
576 // effect of overcounting any metrics recorded in the
577 // PermissionInfoBarDelegate destructor. This is because we directly call
578 // PermissionQueueController::OnPermissionSet without setting the
579 // action_taken bit in PermissionInfoBarDelegate. When
580 // PermissionQueueController is deleted these expectations can be made
581 // unconditional.
582 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
583 histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
584 i + 1);
585 }
dominickn79b96cc2017-02-14 04:14:21586 if (i < 4) {
dominickn23913152017-02-23 12:04:02587 EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
588 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
timloh90e8cec2017-05-22 04:26:19589 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
590 histograms.ExpectUniqueSample(
591 "Permissions.AutoBlocker.EmbargoStatus",
592 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
593 }
dominickn79b96cc2017-02-14 04:14:21594 } else {
dominickn23913152017-02-23 12:04:02595 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
596 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
timloh90e8cec2017-05-22 04:26:19597 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
598 histograms.ExpectBucketCount(
599 "Permissions.AutoBlocker.EmbargoStatus",
600 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS),
601 1);
602 }
dominickn79b96cc2017-02-14 04:14:21603 }
dominickn6947d752016-08-10 02:00:06604 }
605
606 // Ensure that we finish in the block state.
timloh9a180ad2017-02-20 07:15:23607 TestPermissionContext permission_context(profile(),
608 CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
raymesf6104d492017-03-09 01:20:18609 PermissionResult result = permission_context.GetPermissionStatus(
610 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25611 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
dominickn23913152017-02-23 12:04:02612 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
dominickn6947d752016-08-10 02:00:06613 variations::testing::ClearAllVariationParams();
614 }
615
lshang88ec36a2015-12-09 04:50:17616 void TestRequestPermissionInvalidUrl(
lshang88ec36a2015-12-09 04:50:17617 ContentSettingsType content_settings_type) {
dominickn23913152017-02-23 12:04:02618 base::HistogramTester histograms;
timloh9a180ad2017-02-20 07:15:23619 TestPermissionContext permission_context(profile(), content_settings_type);
timvolodinea2830552015-01-20 17:21:23620 GURL url;
621 ASSERT_FALSE(url.is_valid());
timloh86d8eaf2017-05-09 03:43:09622 SetUpUrl(url);
timvolodinea2830552015-01-20 17:21:23623
624 const PermissionRequestID id(
625 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25626 web_contents()->GetMainFrame()->GetRoutingID(), -1);
timvolodinea2830552015-01-20 17:21:23627 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25628 web_contents(), id, url, true /* user_gesture */,
timvolodinea2830552015-01-20 17:21:23629 base::Bind(&TestPermissionContext::TrackPermissionDecision,
630 base::Unretained(&permission_context)));
631
thestig9bdf7f22016-09-28 00:56:20632 ASSERT_EQ(1u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44633 EXPECT_EQ(CONTENT_SETTING_BLOCK, permission_context.decisions()[0]);
timvolodinea2830552015-01-20 17:21:23634 EXPECT_TRUE(permission_context.tab_context_updated());
johnmec41dfee2016-01-13 14:35:16635 EXPECT_EQ(CONTENT_SETTING_ASK,
636 permission_context.GetContentSettingFromMap(url, url));
dominickn23913152017-02-23 12:04:02637 histograms.ExpectTotalCount(
638 "Permissions.AutoBlocker.EmbargoPromptSuppression", 0);
timvolodinea2830552015-01-20 17:21:23639 }
640
timloh9a180ad2017-02-20 07:15:23641 void TestGrantAndRevoke_TestContent(ContentSettingsType content_settings_type,
timvolodine16be5202015-02-02 17:44:54642 ContentSetting expected_default) {
timloh9a180ad2017-02-20 07:15:23643 TestPermissionContext permission_context(profile(), content_settings_type);
toyoshim9eb573f42015-03-30 10:39:39644 GURL url("https://www.google.com");
timloh86d8eaf2017-05-09 03:43:09645 SetUpUrl(url);
timvolodine16be5202015-02-02 17:44:54646
647 const PermissionRequestID id(
648 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25649 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl62b8c3d2017-01-10 05:47:53650 permission_context.SetRespondPermissionCallback(
651 base::Bind(&PermissionContextBaseTests::RespondToPermission,
652 base::Unretained(this), &permission_context, id, url, true,
653 CONTENT_SETTING_ALLOW));
654
timvolodine16be5202015-02-02 17:44:54655 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25656 web_contents(), id, url, true /* user_gesture */,
timvolodine16be5202015-02-02 17:44:54657 base::Bind(&TestPermissionContext::TrackPermissionDecision,
658 base::Unretained(&permission_context)));
659
thestig9bdf7f22016-09-28 00:56:20660 ASSERT_EQ(1u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44661 EXPECT_EQ(CONTENT_SETTING_ALLOW, permission_context.decisions()[0]);
timvolodine16be5202015-02-02 17:44:54662 EXPECT_TRUE(permission_context.tab_context_updated());
johnmec41dfee2016-01-13 14:35:16663 EXPECT_EQ(CONTENT_SETTING_ALLOW,
664 permission_context.GetContentSettingFromMap(url, url));
timvolodine16be5202015-02-02 17:44:54665
666 // Try to reset permission.
667 permission_context.ResetPermission(url.GetOrigin(), url.GetOrigin());
668 ContentSetting setting_after_reset =
johnmec41dfee2016-01-13 14:35:16669 permission_context.GetContentSettingFromMap(url, url);
timvolodine16be5202015-02-02 17:44:54670 ContentSetting default_setting =
peconn5100d432015-09-16 12:03:08671 HostContentSettingsMapFactory::GetForProfile(profile())
lshang88ec36a2015-12-09 04:50:17672 ->GetDefaultContentSetting(content_settings_type, nullptr);
timvolodine16be5202015-02-02 17:44:54673 EXPECT_EQ(default_setting, setting_after_reset);
674 }
675
lshang88ec36a2015-12-09 04:50:17676 void TestGlobalPermissionsKillSwitch(
lshang88ec36a2015-12-09 04:50:17677 ContentSettingsType content_settings_type) {
timloh9a180ad2017-02-20 07:15:23678 TestKillSwitchPermissionContext permission_context(profile(),
679 content_settings_type);
kcarattini2ee48ad52015-10-26 23:45:31680 permission_context.ResetFieldTrialList();
681
682 EXPECT_FALSE(permission_context.IsPermissionKillSwitchOn());
683 std::map<std::string, std::string> params;
timloh9a180ad2017-02-20 07:15:23684 params[PermissionUtil::GetPermissionString(content_settings_type)] =
kcarattini2ee48ad52015-10-26 23:45:31685 kPermissionsKillSwitchBlockedValue;
dominickn2e27dea2017-02-23 23:00:25686 variations::AssociateVariationParams(kPermissionsKillSwitchFieldStudy,
687 kPermissionsKillSwitchTestGroup,
688 params);
kcarattini2ee48ad52015-10-26 23:45:31689 base::FieldTrialList::CreateFieldTrial(kPermissionsKillSwitchFieldStudy,
690 kPermissionsKillSwitchTestGroup);
691 EXPECT_TRUE(permission_context.IsPermissionKillSwitchOn());
692 }
693
johnme7fa91f72016-01-29 22:13:44694 // Don't call this more than once in the same test, as it persists data to
695 // HostContentSettingsMap.
696 void TestParallelRequests(ContentSetting response) {
697 TestPermissionContext permission_context(
timloh9a180ad2017-02-20 07:15:23698 profile(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
johnme7fa91f72016-01-29 22:13:44699 GURL url("http://www.google.com");
timloh86d8eaf2017-05-09 03:43:09700 SetUpUrl(url);
johnme7fa91f72016-01-29 22:13:44701
702 const PermissionRequestID id0(
703 web_contents()->GetRenderProcessHost()->GetID(),
704 web_contents()->GetMainFrame()->GetRoutingID(), 0);
705 const PermissionRequestID id1(
706 web_contents()->GetRenderProcessHost()->GetID(),
707 web_contents()->GetMainFrame()->GetRoutingID(), 1);
708
meredithl62b8c3d2017-01-10 05:47:53709 bool persist = (response == CONTENT_SETTING_ALLOW ||
710 response == CONTENT_SETTING_BLOCK);
711
712 // Request a permission without setting the callback to DecidePermission.
johnme7fa91f72016-01-29 22:13:44713 permission_context.RequestPermission(
benwellsfd2b1552016-07-05 04:26:53714 web_contents(), id0, url, true /* user_gesture */,
johnme7fa91f72016-01-29 22:13:44715 base::Bind(&TestPermissionContext::TrackPermissionDecision,
716 base::Unretained(&permission_context)));
johnme7fa91f72016-01-29 22:13:44717
718 EXPECT_EQ(0u, permission_context.decisions().size());
719
meredithl62b8c3d2017-01-10 05:47:53720 // Set the callback, and make a second permission request.
721 permission_context.SetRespondPermissionCallback(
722 base::Bind(&PermissionContextBaseTests::RespondToPermission,
723 base::Unretained(this), &permission_context, id0, url,
724 persist, response));
725 permission_context.RequestPermission(
726 web_contents(), id1, url, true /* user_gesture */,
727 base::Bind(&TestPermissionContext::TrackPermissionDecision,
728 base::Unretained(&permission_context)));
johnme7fa91f72016-01-29 22:13:44729
thestig9bdf7f22016-09-28 00:56:20730 ASSERT_EQ(2u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44731 EXPECT_EQ(response, permission_context.decisions()[0]);
732 EXPECT_EQ(response, permission_context.decisions()[1]);
733 EXPECT_TRUE(permission_context.tab_context_updated());
734
735 EXPECT_EQ(response, permission_context.GetContentSettingFromMap(url, url));
736 }
737
meredithl62b8c3d2017-01-10 05:47:53738 void TestPermissionsBlacklisting(
meredithl62b8c3d2017-01-10 05:47:53739 ContentSettingsType content_settings_type,
740 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
741 const GURL& url,
742 int timeout,
dominickn79b96cc2017-02-14 04:14:21743 ContentSetting expected_permission_status,
744 PermissionEmbargoStatus expected_embargo_reason) {
timloh86d8eaf2017-05-09 03:43:09745 SetUpUrl(url);
dominickn79b96cc2017-02-14 04:14:21746 base::HistogramTester histograms;
meredithl62b8c3d2017-01-10 05:47:53747 base::test::ScopedFeatureList scoped_feature_list;
timloh90e8cec2017-05-22 04:26:19748 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER) {
749 scoped_feature_list.InitWithFeatures(
750 {features::kUseGroupedPermissionInfobars,
751 features::kPermissionsBlacklist},
752 {});
753 } else {
754 scoped_feature_list.InitWithFeatures(
755 {features::kPermissionsBlacklist},
756 {features::kUseGroupedPermissionInfobars});
757 }
timloh9a180ad2017-02-20 07:15:23758 TestPermissionContext permission_context(profile(), content_settings_type);
meredithl03b12852017-01-25 05:08:01759 PermissionDecisionAutoBlocker::GetForProfile(profile())
760 ->SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
761 timeout);
meredithl62b8c3d2017-01-10 05:47:53762 const PermissionRequestID id(
763 web_contents()->GetRenderProcessHost()->GetID(),
764 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl03b12852017-01-25 05:08:01765
766 // A response only needs to be made to the permission request if we do not
dominickn23913152017-02-23 12:04:02767 // expect the permission to be blacklisted.
meredithl03b12852017-01-25 05:08:01768 if (expected_permission_status == CONTENT_SETTING_ALLOW) {
769 permission_context.SetRespondPermissionCallback(
770 base::Bind(&PermissionContextBaseTests::RespondToPermission,
771 base::Unretained(this), &permission_context, id, url,
772 true /* persist */, expected_permission_status));
773 }
774
meredithl62b8c3d2017-01-10 05:47:53775 permission_context.RequestPermission(
776 web_contents(), id, url, true /* user_gesture */,
777 base::Bind(&TestPermissionContext::TrackPermissionDecision,
778 base::Unretained(&permission_context)));
raymesf6104d492017-03-09 01:20:18779 PermissionResult result = permission_context.GetPermissionStatus(
780 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25781 EXPECT_EQ(expected_permission_status, result.content_setting);
meredithl62b8c3d2017-01-10 05:47:53782
meredithl03b12852017-01-25 05:08:01783 if (expected_permission_status == CONTENT_SETTING_ALLOW) {
784 ASSERT_EQ(1u, permission_context.decisions().size());
785 EXPECT_EQ(expected_permission_status, permission_context.decisions()[0]);
dominickn23913152017-02-23 12:04:02786 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
787 } else {
788 EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);
meredithl03b12852017-01-25 05:08:01789 }
dominickn23913152017-02-23 12:04:02790 histograms.ExpectUniqueSample(
791 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25792 static_cast<int>(expected_embargo_reason), 1);
dominickn79b96cc2017-02-14 04:14:21793 histograms.ExpectUniqueSample("Permissions.AutoBlocker.EmbargoStatus",
dominickn2e27dea2017-02-23 23:00:25794 static_cast<int>(expected_embargo_reason), 1);
meredithl62b8c3d2017-01-10 05:47:53795 }
796
timloh86d8eaf2017-05-09 03:43:09797 void SetUpUrl(const GURL& url) {
798 NavigateAndCommit(url);
timloh90e8cec2017-05-22 04:26:19799 if (GetParam() == TestType::PERMISSION_REQUEST_MANAGER)
800 prompt_factory_->DocumentOnLoadCompletedInMainFrame();
timloh86d8eaf2017-05-09 03:43:09801 }
802
felt88bf98cb2014-12-16 03:50:23803 private:
804 // ChromeRenderViewHostTestHarness:
dcheng171318362014-12-29 18:31:25805 void SetUp() override {
felt88bf98cb2014-12-16 03:50:23806 ChromeRenderViewHostTestHarness::SetUp();
timloh90e8cec2017-05-22 04:26:19807 if (GetParam() == TestType::PERMISSION_QUEUE_CONTROLLER) {
808 scoped_feature_list_.InitAndDisableFeature(
809 features::kUseGroupedPermissionInfobars);
810 InfoBarService::CreateForWebContents(web_contents());
811 } else {
812 scoped_feature_list_.InitAndEnableFeature(
813 features::kUseGroupedPermissionInfobars);
814 PermissionRequestManager::CreateForWebContents(web_contents());
815 PermissionRequestManager* manager =
816 PermissionRequestManager::FromWebContents(web_contents());
817 prompt_factory_.reset(new MockPermissionPromptFactory(manager));
818 manager->DisplayPendingRequests();
819 }
felt88bf98cb2014-12-16 03:50:23820 }
821
timloh86d8eaf2017-05-09 03:43:09822 void TearDown() override {
823 prompt_factory_.reset();
824 ChromeRenderViewHostTestHarness::TearDown();
825 }
826
827 std::unique_ptr<MockPermissionPromptFactory> prompt_factory_;
828
timloh90e8cec2017-05-22 04:26:19829 // For testing the PermissionRequestManager on Android
830 base::test::ScopedFeatureList scoped_feature_list_;
831
felt88bf98cb2014-12-16 03:50:23832 DISALLOW_COPY_AND_ASSIGN(PermissionContextBaseTests);
833};
834
[email protected]89a8dd5d2014-07-11 12:02:07835// Simulates clicking Accept. The permission should be granted and
836// saved for future use.
timloh90e8cec2017-05-22 04:26:19837TEST_P(PermissionContextBaseTests, TestAskAndGrantPersist) {
timloh9a180ad2017-02-20 07:15:23838 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
dominicknd4e446a2016-09-13 07:44:13839 CONTENT_SETTING_ALLOW, true);
840}
841
842// Simulates clicking Accept. The permission should be granted, but not
843// persisted.
timloh90e8cec2017-05-22 04:26:19844TEST_P(PermissionContextBaseTests, TestAskAndGrantNoPersist) {
timloh9a180ad2017-02-20 07:15:23845 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
dominicknd4e446a2016-09-13 07:44:13846 CONTENT_SETTING_ALLOW, false);
847}
848
849// Simulates clicking Block. The permission should be denied and
850// saved for future use.
timloh90e8cec2017-05-22 04:26:19851TEST_P(PermissionContextBaseTests, TestAskAndBlockPersist) {
timloh9a180ad2017-02-20 07:15:23852 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
dominicknd4e446a2016-09-13 07:44:13853 CONTENT_SETTING_BLOCK, true);
854}
855
856// Simulates clicking Block. The permission should be denied, but not persisted.
timloh90e8cec2017-05-22 04:26:19857TEST_P(PermissionContextBaseTests, TestAskAndBlockNoPersist) {
timloh9a180ad2017-02-20 07:15:23858 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
dominicknd4e446a2016-09-13 07:44:13859 CONTENT_SETTING_BLOCK, false);
timvolodinea2830552015-01-20 17:21:23860}
[email protected]89a8dd5d2014-07-11 12:02:07861
felt88bf98cb2014-12-16 03:50:23862// Simulates clicking Dismiss (X) in the infobar/bubble.
[email protected]89a8dd5d2014-07-11 12:02:07863// The permission should be denied but not saved for future use.
timloh90e8cec2017-05-22 04:26:19864TEST_P(PermissionContextBaseTests, TestAskAndDismiss) {
timloh9a180ad2017-02-20 07:15:23865 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
dominicknd4e446a2016-09-13 07:44:13866 CONTENT_SETTING_ASK, false);
timvolodinea2830552015-01-20 17:21:23867}
868
dominickn6947d752016-08-10 02:00:06869// Simulates clicking Dismiss (X) in the infobar/bubble with the block on too
870// many dismissals feature active. The permission should be blocked after
871// several dismissals.
timloh90e8cec2017-05-22 04:26:19872TEST_P(PermissionContextBaseTests, TestDismissUntilBlocked) {
dominickn6947d752016-08-10 02:00:06873 TestBlockOnSeveralDismissals_TestContent();
874}
875
876// Test setting a custom number of dismissals before block via variations.
timloh90e8cec2017-05-22 04:26:19877TEST_P(PermissionContextBaseTests, TestDismissVariations) {
dominickn6947d752016-08-10 02:00:06878 TestVariationBlockOnSeveralDismissals_TestContent();
879}
880
timvolodinea2830552015-01-20 17:21:23881// Simulates non-valid requesting URL.
882// The permission should be denied but not saved for future use.
timloh90e8cec2017-05-22 04:26:19883TEST_P(PermissionContextBaseTests, TestNonValidRequestingUrl) {
timloh9a180ad2017-02-20 07:15:23884 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_GEOLOCATION);
885 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
886 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
887 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
timvolodinea2830552015-01-20 17:21:23888#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
889 TestRequestPermissionInvalidUrl(
890 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
891#endif
892}
timvolodine16be5202015-02-02 17:44:54893
timloh90e8cec2017-05-22 04:26:19894// Simulates granting and revoking of permissions.
895TEST_P(PermissionContextBaseTests, TestGrantAndRevoke) {
timloh9a180ad2017-02-20 07:15:23896 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
timvolodine16be5202015-02-02 17:44:54897 CONTENT_SETTING_ASK);
timloh9a180ad2017-02-20 07:15:23898 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
timvolodine16be5202015-02-02 17:44:54899 CONTENT_SETTING_ASK);
timloh90e8cec2017-05-22 04:26:19900#if defined(OS_ANDROID)
timvolodine16be5202015-02-02 17:44:54901 TestGrantAndRevoke_TestContent(
902 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, CONTENT_SETTING_ASK);
timvolodine16be5202015-02-02 17:44:54903 // TODO(timvolodine): currently no test for
904 // CONTENT_SETTINGS_TYPE_NOTIFICATIONS because notification permissions work
905 // differently with infobars as compared to bubbles (crbug.com/453784).
timloh90e8cec2017-05-22 04:26:19906#else
timloh9a180ad2017-02-20 07:15:23907 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
timvolodine16be5202015-02-02 17:44:54908 CONTENT_SETTING_ASK);
feltcb9e7362015-06-25 00:36:43909#endif
timloh90e8cec2017-05-22 04:26:19910}
kcarattini2ee48ad52015-10-26 23:45:31911
912// Tests the global kill switch by enabling/disabling the Field Trials.
timloh90e8cec2017-05-22 04:26:19913TEST_P(PermissionContextBaseTests, TestGlobalKillSwitch) {
timloh9a180ad2017-02-20 07:15:23914 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_GEOLOCATION);
915 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
916 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
917 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
918 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_DURABLE_STORAGE);
kcarattini2ee48ad52015-10-26 23:45:31919#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
920 TestGlobalPermissionsKillSwitch(
921 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
922#endif
timloh9a180ad2017-02-20 07:15:23923 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
924 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
kcarattini2ee48ad52015-10-26 23:45:31925}
johnme7fa91f72016-01-29 22:13:44926
timloh90e8cec2017-05-22 04:26:19927TEST_P(PermissionContextBaseTests, TestParallelRequestsAllowed) {
johnme7fa91f72016-01-29 22:13:44928 TestParallelRequests(CONTENT_SETTING_ALLOW);
929}
930
timloh90e8cec2017-05-22 04:26:19931TEST_P(PermissionContextBaseTests, TestParallelRequestsBlocked) {
johnme7fa91f72016-01-29 22:13:44932 TestParallelRequests(CONTENT_SETTING_BLOCK);
933}
934
timloh90e8cec2017-05-22 04:26:19935TEST_P(PermissionContextBaseTests, TestParallelRequestsDismissed) {
johnme7fa91f72016-01-29 22:13:44936 TestParallelRequests(CONTENT_SETTING_ASK);
937}
meredithl62b8c3d2017-01-10 05:47:53938
939// Tests a blacklisted (URL, permission) pair has had its permission request
940// blocked.
timloh90e8cec2017-05-22 04:26:19941TEST_P(PermissionContextBaseTests, TestPermissionsBlacklistingBlocked) {
meredithl62b8c3d2017-01-10 05:47:53942 scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
943 new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
944 const GURL url("https://www.example.com");
meredithl03b12852017-01-25 05:08:01945 std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
meredithl62b8c3d2017-01-10 05:47:53946 db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
dominickn79b96cc2017-02-14 04:14:21947 TestPermissionsBlacklisting(
dominickn2e27dea2017-02-23 23:00:25948 CONTENT_SETTINGS_TYPE_GEOLOCATION, db_manager, url, 2000 /* timeout */,
949 CONTENT_SETTING_BLOCK, PermissionEmbargoStatus::PERMISSIONS_BLACKLISTING);
meredithl62b8c3d2017-01-10 05:47:53950}
951
meredithl03b12852017-01-25 05:08:01952// Tests that a URL that is blacklisted for one permission can still request
953// another and grant another.
timloh90e8cec2017-05-22 04:26:19954TEST_P(PermissionContextBaseTests, TestPermissionsBlacklistingAllowed) {
meredithl62b8c3d2017-01-10 05:47:53955 scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
956 new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
957 const GURL url("https://www.example.com");
meredithl03b12852017-01-25 05:08:01958 std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
meredithl62b8c3d2017-01-10 05:47:53959 db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
timloh9a180ad2017-02-20 07:15:23960 TestPermissionsBlacklisting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, db_manager,
dominickn79b96cc2017-02-14 04:14:21961 url, 2000 /* timeout */, CONTENT_SETTING_ALLOW,
962 PermissionEmbargoStatus::NOT_EMBARGOED);
meredithl62b8c3d2017-01-10 05:47:53963}
timloh90e8cec2017-05-22 04:26:19964
965#if defined(OS_ANDROID)
966INSTANTIATE_TEST_CASE_P(
967 PermissionContextBaseTestsInstance,
968 PermissionContextBaseTests,
969 ::testing::Values(TestType::PERMISSION_REQUEST_MANAGER,
970 TestType::PERMISSION_QUEUE_CONTROLLER));
971#else
972INSTANTIATE_TEST_CASE_P(
973 PermissionContextBaseTestsInstance,
974 PermissionContextBaseTests,
975 ::testing::Values(TestType::PERMISSION_REQUEST_MANAGER));
976#endif