blob: 4bd7650387c98c5181c9bcb487b7a8e2d16dd6fd [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"
dominickn79b96cc2017-02-14 04:14:2128#include "chrome/browser/permissions/permission_uma_util.h"
kcarattini2ee48ad52015-10-26 23:45:3129#include "chrome/browser/permissions/permission_util.h"
dominickn6947d752016-08-10 02:00:0630#include "chrome/common/chrome_features.h"
felt88bf98cb2014-12-16 03:50:2331#include "chrome/common/chrome_switches.h"
[email protected]89a8dd5d2014-07-11 12:02:0732#include "chrome/test/base/chrome_render_view_host_test_harness.h"
33#include "chrome/test/base/testing_profile.h"
mukai8eaec822014-10-25 17:53:1634#include "components/content_settings/core/browser/host_content_settings_map.h"
mukai077089f2014-09-11 18:41:5235#include "components/content_settings/core/common/content_settings.h"
[email protected]08f71012014-07-25 10:27:5436#include "components/content_settings/core/common/content_settings_types.h"
meredithl62b8c3d2017-01-10 05:47:5337#include "components/safe_browsing_db/database_manager.h"
38#include "components/safe_browsing_db/test_database_manager.h"
kcarattini2ee48ad52015-10-26 23:45:3139#include "components/variations/variations_associated_data.h"
meredithl62b8c3d2017-01-10 05:47:5340#include "content/public/browser/browser_thread.h"
mlamouri5fc460f2015-06-03 17:30:2841#include "content/public/browser/render_frame_host.h"
[email protected]89a8dd5d2014-07-11 12:02:0742#include "content/public/browser/web_contents.h"
43#include "content/public/test/mock_render_process_host.h"
[email protected]89a8dd5d2014-07-11 12:02:0744#include "testing/gtest/include/gtest/gtest.h"
45
thestig9bdf7f22016-09-28 00:56:2046#if !defined(OS_ANDROID)
tsergeanta771c23e2016-07-13 04:54:5247#include "chrome/browser/permissions/permission_request_manager.h"
estade6d95d1d2015-10-02 18:55:2348#endif
49
thestig9bdf7f22016-09-28 00:56:2050const char* const kPermissionsKillSwitchFieldStudy =
kcarattini2ee48ad52015-10-26 23:45:3151 PermissionContextBase::kPermissionsKillSwitchFieldStudy;
thestig9bdf7f22016-09-28 00:56:2052const char* const kPermissionsKillSwitchBlockedValue =
kcarattini2ee48ad52015-10-26 23:45:3153 PermissionContextBase::kPermissionsKillSwitchBlockedValue;
54const char kPermissionsKillSwitchTestGroup[] = "TestGroup";
thestig9bdf7f22016-09-28 00:56:2055const char* const kPromptGroupName = kPermissionsKillSwitchTestGroup;
dominickn6947d752016-08-10 02:00:0656const char kPromptTrialName[] = "PermissionPromptsUX";
kcarattini2ee48ad52015-10-26 23:45:3157
meredithl48ad16812017-02-08 03:15:3758namespace {
59
meredithl62b8c3d2017-01-10 05:47:5360class MockSafeBrowsingDatabaseManager
61 : public safe_browsing::TestSafeBrowsingDatabaseManager {
62 public:
63 explicit MockSafeBrowsingDatabaseManager(bool perform_callback)
64 : perform_callback_(perform_callback) {}
65
66 bool CheckApiBlacklistUrl(
67 const GURL& url,
68 safe_browsing::SafeBrowsingDatabaseManager::Client* client) override {
69 if (perform_callback_) {
70 safe_browsing::ThreatMetadata metadata;
71 const auto& blacklisted_permissions = permissions_blacklist_.find(url);
72 if (blacklisted_permissions != permissions_blacklist_.end())
73 metadata.api_permissions = blacklisted_permissions->second;
74 client->OnCheckApiBlacklistUrlResult(url, metadata);
75 }
76 // Returns false if scheme is HTTP/HTTPS and able to be checked.
77 return false;
78 }
79
80 bool CancelApiCheck(Client* client) override {
81 DCHECK(!perform_callback_);
82 // Returns true when client check could be stopped.
83 return true;
84 }
85
86 void BlacklistUrlPermissions(const GURL& url,
87 const std::set<std::string> permissions) {
88 permissions_blacklist_[url] = permissions;
89 }
90
91 protected:
92 ~MockSafeBrowsingDatabaseManager() override {}
93
94 private:
95 bool perform_callback_;
96 std::map<GURL, std::set<std::string>> permissions_blacklist_;
97
98 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
99};
100
meredithl48ad16812017-02-08 03:15:37101} // namespace
102
[email protected]89a8dd5d2014-07-11 12:02:07103class TestPermissionContext : public PermissionContextBase {
104 public:
105 TestPermissionContext(Profile* profile,
lshang88ec36a2015-12-09 04:50:17106 const ContentSettingsType content_settings_type)
timloh9a180ad2017-02-20 07:15:23107 : PermissionContextBase(profile, content_settings_type),
dominickn6947d752016-08-10 02:00:06108 tab_context_updated_(false) {}
[email protected]89a8dd5d2014-07-11 12:02:07109
Daniel Chenga542fca2014-10-21 09:51:29110 ~TestPermissionContext() override {}
[email protected]89a8dd5d2014-07-11 12:02:07111
estade6d95d1d2015-10-02 18:55:23112#if defined(OS_ANDROID)
[email protected]89a8dd5d2014-07-11 12:02:07113 PermissionQueueController* GetInfoBarController() {
114 return GetQueueController();
115 }
estade6d95d1d2015-10-02 18:55:23116#endif
[email protected]89a8dd5d2014-07-11 12:02:07117
thestig9bdf7f22016-09-28 00:56:20118 const std::vector<ContentSetting>& decisions() const { return decisions_; }
[email protected]89a8dd5d2014-07-11 12:02:07119
thestig9bdf7f22016-09-28 00:56:20120 bool tab_context_updated() const { return tab_context_updated_; }
[email protected]89a8dd5d2014-07-11 12:02:07121
meredithl62b8c3d2017-01-10 05:47:53122 // Once a decision for the requested permission has been made, run the
123 // callback.
mlamouridf357a312015-03-03 17:34:05124 void TrackPermissionDecision(ContentSetting content_setting) {
johnme7fa91f72016-01-29 22:13:44125 decisions_.push_back(content_setting);
meredithl62b8c3d2017-01-10 05:47:53126 // Null check required here as the quit_closure_ can also be run and reset
127 // first from within DecidePermission.
128 if (quit_closure_) {
129 quit_closure_.Run();
130 quit_closure_.Reset();
131 }
[email protected]89a8dd5d2014-07-11 12:02:07132 }
133
johnmec41dfee2016-01-13 14:35:16134 ContentSetting GetContentSettingFromMap(const GURL& url_a,
135 const GURL& url_b) {
thestig9bdf7f22016-09-28 00:56:20136 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
137 return map->GetContentSetting(url_a.GetOrigin(), url_b.GetOrigin(),
timloh9a180ad2017-02-20 07:15:23138 content_settings_storage_type(),
139 std::string());
johnmec41dfee2016-01-13 14:35:16140 }
141
meredithl62b8c3d2017-01-10 05:47:53142 void RequestPermission(content::WebContents* web_contents,
143 const PermissionRequestID& id,
144 const GURL& requesting_frame,
145 bool user_gesture,
146 const BrowserPermissionCallback& callback) override {
147 base::RunLoop run_loop;
148 quit_closure_ = run_loop.QuitClosure();
149 PermissionContextBase::RequestPermission(web_contents, id, requesting_frame,
150 true /* user_gesture */, callback);
151 run_loop.Run();
152 }
153
154 void DecidePermission(content::WebContents* web_contents,
155 const PermissionRequestID& id,
156 const GURL& requesting_origin,
157 const GURL& embedding_origin,
158 bool user_gesture,
159 const BrowserPermissionCallback& callback) override {
160 PermissionContextBase::DecidePermission(web_contents, id, requesting_origin,
161 embedding_origin, user_gesture,
162 callback);
163 if (respond_permission_) {
164 respond_permission_.Run();
165 respond_permission_.Reset();
166 } else {
167 // Stop the run loop from spinning indefinitely if no response callback
168 // has been set, as is the case with TestParallelRequests.
169 quit_closure_.Run();
170 quit_closure_.Reset();
171 }
172 }
173
meredithl03b12852017-01-25 05:08:01174 // Set the callback to run if the permission is being responded to in the
175 // test. This is left empty where no response is needed, such as in parallel
176 // requests, permissions blacklisting, invalid origin, and killswitch.
meredithl62b8c3d2017-01-10 05:47:53177 void SetRespondPermissionCallback(base::Closure callback) {
178 respond_permission_ = callback;
179 }
180
[email protected]89a8dd5d2014-07-11 12:02:07181 protected:
Daniel Chenga542fca2014-10-21 09:51:29182 void UpdateTabContext(const PermissionRequestID& id,
183 const GURL& requesting_origin,
184 bool allowed) override {
[email protected]89a8dd5d2014-07-11 12:02:07185 tab_context_updated_ = true;
186 }
187
dominickn2e27dea2017-02-23 23:00:25188 bool IsRestrictedToSecureOrigins() const override { return false; }
mlamouria31c6ff12015-06-01 15:40:52189
[email protected]89a8dd5d2014-07-11 12:02:07190 private:
johnme7fa91f72016-01-29 22:13:44191 std::vector<ContentSetting> decisions_;
192 bool tab_context_updated_;
meredithl62b8c3d2017-01-10 05:47:53193 base::Closure quit_closure_;
194 // Callback for responding to a permission once the request has been completed
195 // (valid URL, kill switch disabled, not blacklisted)
196 base::Closure respond_permission_;
thestig9bdf7f22016-09-28 00:56:20197 DISALLOW_COPY_AND_ASSIGN(TestPermissionContext);
dominickn6947d752016-08-10 02:00:06198};
199
200class TestKillSwitchPermissionContext : public TestPermissionContext {
201 public:
202 TestKillSwitchPermissionContext(
203 Profile* profile,
dominickn6947d752016-08-10 02:00:06204 const ContentSettingsType content_settings_type)
timloh9a180ad2017-02-20 07:15:23205 : TestPermissionContext(profile, content_settings_type),
thestig9bdf7f22016-09-28 00:56:20206 field_trial_list_(base::MakeUnique<base::FieldTrialList>(
207 base::MakeUnique<base::MockEntropyProvider>())) {}
dominickn6947d752016-08-10 02:00:06208
209 void ResetFieldTrialList() {
210 // Destroy the existing FieldTrialList before creating a new one to avoid
211 // a DCHECK.
212 field_trial_list_.reset();
thestig9bdf7f22016-09-28 00:56:20213 field_trial_list_ = base::MakeUnique<base::FieldTrialList>(
214 base::MakeUnique<base::MockEntropyProvider>());
dominickn6947d752016-08-10 02:00:06215 variations::testing::ClearAllVariationParams();
216 }
217
218 private:
dcheng4af48582016-04-19 00:29:35219 std::unique_ptr<base::FieldTrialList> field_trial_list_;
thestig9bdf7f22016-09-28 00:56:20220
221 DISALLOW_COPY_AND_ASSIGN(TestKillSwitchPermissionContext);
[email protected]89a8dd5d2014-07-11 12:02:07222};
223
felt88bf98cb2014-12-16 03:50:23224class PermissionContextBaseTests : public ChromeRenderViewHostTestHarness {
225 protected:
226 PermissionContextBaseTests() {}
thestig9bdf7f22016-09-28 00:56:20227 ~PermissionContextBaseTests() override {}
felt88bf98cb2014-12-16 03:50:23228
229 // Accept or dismiss the permission bubble or infobar.
230 void RespondToPermission(TestPermissionContext* context,
231 const PermissionRequestID& id,
232 const GURL& url,
dominicknd4e446a2016-09-13 07:44:13233 bool persist,
johnme7fa91f72016-01-29 22:13:44234 ContentSetting response) {
235 DCHECK(response == CONTENT_SETTING_ALLOW ||
236 response == CONTENT_SETTING_BLOCK ||
237 response == CONTENT_SETTING_ASK);
estade6d95d1d2015-10-02 18:55:23238#if defined(OS_ANDROID)
dominickn2e27dea2017-02-23 23:00:25239 PermissionAction decision = PermissionAction::DISMISSED;
dominickn6957a9c2016-08-16 06:06:36240 if (response == CONTENT_SETTING_ALLOW)
dominickn2e27dea2017-02-23 23:00:25241 decision = PermissionAction::GRANTED;
dominickn6957a9c2016-08-16 06:06:36242 else if (response == CONTENT_SETTING_BLOCK)
dominickn2e27dea2017-02-23 23:00:25243 decision = PermissionAction::DENIED;
johnme7fa91f72016-01-29 22:13:44244 context->GetInfoBarController()->OnPermissionSet(
dominicknd4e446a2016-09-13 07:44:13245 id, url, url, false /* user_gesture */, persist, decision);
estade6d95d1d2015-10-02 18:55:23246#else
tsergeanta771c23e2016-07-13 04:54:52247 PermissionRequestManager* manager =
248 PermissionRequestManager::FromWebContents(web_contents());
dominicknd4e446a2016-09-13 07:44:13249 manager->TogglePersist(persist);
johnme7fa91f72016-01-29 22:13:44250 switch (response) {
251 case CONTENT_SETTING_ALLOW:
252 manager->Accept();
253 break;
254 case CONTENT_SETTING_BLOCK:
255 manager->Deny();
256 break;
257 case CONTENT_SETTING_ASK:
258 manager->Closing();
259 break;
260 default:
261 NOTREACHED();
262 }
estade6d95d1d2015-10-02 18:55:23263#endif
felt88bf98cb2014-12-16 03:50:23264 }
265
timloh9a180ad2017-02-20 07:15:23266 void TestAskAndDecide_TestContent(ContentSettingsType content_settings_type,
dominicknd4e446a2016-09-13 07:44:13267 ContentSetting decision,
268 bool persist) {
timloh9a180ad2017-02-20 07:15:23269 TestPermissionContext permission_context(profile(), content_settings_type);
dominicknd4e446a2016-09-13 07:44:13270 GURL url("https://www.google.com");
johnme7fa91f72016-01-29 22:13:44271 NavigateAndCommit(url);
dominickn6da2b382016-08-23 20:21:30272 base::HistogramTester histograms;
felt88bf98cb2014-12-16 03:50:23273
274 const PermissionRequestID id(
275 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25276 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl62b8c3d2017-01-10 05:47:53277 permission_context.SetRespondPermissionCallback(
278 base::Bind(&PermissionContextBaseTests::RespondToPermission,
279 base::Unretained(this), &permission_context, id, url,
280 persist, decision));
felt88bf98cb2014-12-16 03:50:23281 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25282 web_contents(), id, url, true /* user_gesture */,
felt88bf98cb2014-12-16 03:50:23283 base::Bind(&TestPermissionContext::TrackPermissionDecision,
284 base::Unretained(&permission_context)));
thestig9bdf7f22016-09-28 00:56:20285 ASSERT_EQ(1u, permission_context.decisions().size());
dominicknd4e446a2016-09-13 07:44:13286 EXPECT_EQ(decision, permission_context.decisions()[0]);
felt88bf98cb2014-12-16 03:50:23287 EXPECT_TRUE(permission_context.tab_context_updated());
dominickn6da2b382016-08-23 20:21:30288
thestig9bdf7f22016-09-28 00:56:20289 std::string decision_string;
dominicknd4e446a2016-09-13 07:44:13290 if (decision == CONTENT_SETTING_ALLOW)
291 decision_string = "Accepted";
292 else if (decision == CONTENT_SETTING_BLOCK)
293 decision_string = "Denied";
294 else if (decision == CONTENT_SETTING_ASK)
295 decision_string = "Dismissed";
felt88bf98cb2014-12-16 03:50:23296
dominicknd4e446a2016-09-13 07:44:13297 if (decision_string.size()) {
298 histograms.ExpectUniqueSample(
299 "Permissions.Prompt." + decision_string + ".PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23300 PermissionUtil::GetPermissionString(content_settings_type),
dominicknd4e446a2016-09-13 07:44:13301 0, 1);
302 histograms.ExpectUniqueSample(
303 "Permissions.Prompt." + decision_string + ".PriorIgnoreCount." +
timloh9a180ad2017-02-20 07:15:23304 PermissionUtil::GetPermissionString(content_settings_type),
dominicknd4e446a2016-09-13 07:44:13305 0, 1);
306 }
felt88bf98cb2014-12-16 03:50:23307
dominicknd4e446a2016-09-13 07:44:13308 if (persist) {
309 EXPECT_EQ(decision,
310 permission_context.GetContentSettingFromMap(url, url));
311 } else {
312 EXPECT_EQ(CONTENT_SETTING_ASK,
313 permission_context.GetContentSettingFromMap(url, url));
314 }
dominickn79b96cc2017-02-14 04:14:21315
dominickn23913152017-02-23 12:04:02316 histograms.ExpectUniqueSample(
317 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25318 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);
319 histograms.ExpectUniqueSample(
320 "Permissions.AutoBlocker.EmbargoStatus",
321 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), 1);
felt88bf98cb2014-12-16 03:50:23322 }
323
dominickn6947d752016-08-10 02:00:06324 void DismissMultipleTimesAndExpectBlock(
325 const GURL& url,
dominickn6947d752016-08-10 02:00:06326 ContentSettingsType content_settings_type,
327 uint32_t iterations) {
328 base::HistogramTester histograms;
329
330 // Dismiss |iterations| times. The final dismiss should change the decision
331 // from dismiss to block, and hence change the persisted content setting.
332 for (uint32_t i = 0; i < iterations; ++i) {
timloh9a180ad2017-02-20 07:15:23333 TestPermissionContext permission_context(profile(),
334 content_settings_type);
dominickn6947d752016-08-10 02:00:06335 const PermissionRequestID id(
336 web_contents()->GetRenderProcessHost()->GetID(),
337 web_contents()->GetMainFrame()->GetRoutingID(), i);
meredithl62b8c3d2017-01-10 05:47:53338
339 permission_context.SetRespondPermissionCallback(
340 base::Bind(&PermissionContextBaseTests::RespondToPermission,
341 base::Unretained(this), &permission_context, id, url,
342 false, CONTENT_SETTING_ASK));
343
dominickn6947d752016-08-10 02:00:06344 permission_context.RequestPermission(
345 web_contents(), id, url, true /* user_gesture */,
346 base::Bind(&TestPermissionContext::TrackPermissionDecision,
dominickn2e27dea2017-02-23 23:00:25347 base::Unretained(&permission_context)));
dominickn6947d752016-08-10 02:00:06348 histograms.ExpectTotalCount(
dominickn6da2b382016-08-23 20:21:30349 "Permissions.Prompt.Dismissed.PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23350 PermissionUtil::GetPermissionString(content_settings_type),
dominickn6947d752016-08-10 02:00:06351 i + 1);
dominickn6da2b382016-08-23 20:21:30352 histograms.ExpectBucketCount(
353 "Permissions.Prompt.Dismissed.PriorDismissCount." +
timloh9a180ad2017-02-20 07:15:23354 PermissionUtil::GetPermissionString(content_settings_type),
dominickn6da2b382016-08-23 20:21:30355 i, 1);
dominickn23913152017-02-23 12:04:02356
357// On Android, repeatedly requesting and deciding permissions has the side
358// effect of overcounting any metrics recorded in the PermissionInfoBarDelegate
359// destructor. This is because we directly call
360// PermissionQueueController::OnPermissionSet without setting the action_taken
361// bit in PermissionInfoBarDelegate. When PermissionQueueController is deleted
362// all OS_ANDROID ifdefs in this test can be removed.
363#if !defined(OS_ANDROID)
dominickn79b96cc2017-02-14 04:14:21364 histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
365 i + 1);
dominickn23913152017-02-23 12:04:02366#endif
367
raymesf6104d492017-03-09 01:20:18368 PermissionResult result = permission_context.GetPermissionStatus(
369 nullptr /* render_frame_host */, url, url);
dominickn23913152017-02-23 12:04:02370
371 histograms.ExpectUniqueSample(
372 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25373 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn79b96cc2017-02-14 04:14:21374 if (i < 2) {
dominickn23913152017-02-23 12:04:02375 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
376 EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
377#if !defined(OS_ANDROID)
dominickn2e27dea2017-02-23 23:00:25378 histograms.ExpectUniqueSample(
379 "Permissions.AutoBlocker.EmbargoStatus",
380 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn23913152017-02-23 12:04:02381#endif
dominickn79b96cc2017-02-14 04:14:21382 } else {
dominickn23913152017-02-23 12:04:02383 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
384 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
385#if !defined(OS_ANDROID)
dominickn79b96cc2017-02-14 04:14:21386 histograms.ExpectBucketCount(
387 "Permissions.AutoBlocker.EmbargoStatus",
dominickn2e27dea2017-02-23 23:00:25388 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
dominickn23913152017-02-23 12:04:02389#endif
dominickn79b96cc2017-02-14 04:14:21390 }
391
thestig9bdf7f22016-09-28 00:56:20392 ASSERT_EQ(1u, permission_context.decisions().size());
dominickn79b96cc2017-02-14 04:14:21393 EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
dominickn6947d752016-08-10 02:00:06394 EXPECT_TRUE(permission_context.tab_context_updated());
dominickn6947d752016-08-10 02:00:06395 }
396
timloh9a180ad2017-02-20 07:15:23397 TestPermissionContext permission_context(profile(), content_settings_type);
meredithl03b12852017-01-25 05:08:01398 const PermissionRequestID id(
399 web_contents()->GetRenderProcessHost()->GetID(),
400 web_contents()->GetMainFrame()->GetRoutingID(), -1);
401
402 permission_context.SetRespondPermissionCallback(
403 base::Bind(&PermissionContextBaseTests::RespondToPermission,
404 base::Unretained(this), &permission_context, id, url, false,
405 CONTENT_SETTING_ASK));
406
407 permission_context.RequestPermission(
408 web_contents(), id, url, true /* user_gesture */,
409 base::Bind(&TestPermissionContext::TrackPermissionDecision,
410 base::Unretained(&permission_context)));
meredithlcda94daf2017-01-19 03:03:35411
raymesf6104d492017-03-09 01:20:18412 PermissionResult result = permission_context.GetPermissionStatus(
413 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25414 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
dominickn23913152017-02-23 12:04:02415 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
416 histograms.ExpectBucketCount(
417 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25418 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
dominickn6947d752016-08-10 02:00:06419 }
420
421 void TestBlockOnSeveralDismissals_TestContent() {
422 GURL url("https://www.google.com");
423 NavigateAndCommit(url);
424 base::HistogramTester histograms;
425
426 // First, ensure that > 3 dismissals behaves correctly.
427 for (uint32_t i = 0; i < 4; ++i) {
428 TestPermissionContext permission_context(
timloh9a180ad2017-02-20 07:15:23429 profile(), CONTENT_SETTINGS_TYPE_GEOLOCATION);
dominickn6947d752016-08-10 02:00:06430
431 const PermissionRequestID id(
432 web_contents()->GetRenderProcessHost()->GetID(),
433 web_contents()->GetMainFrame()->GetRoutingID(), i);
meredithl62b8c3d2017-01-10 05:47:53434
435 permission_context.SetRespondPermissionCallback(
436 base::Bind(&PermissionContextBaseTests::RespondToPermission,
437 base::Unretained(this), &permission_context, id, url,
438 false, CONTENT_SETTING_ASK));
dominickn6947d752016-08-10 02:00:06439 permission_context.RequestPermission(
440 web_contents(), id, url, true /* user_gesture */,
441 base::Bind(&TestPermissionContext::TrackPermissionDecision,
dominickn2e27dea2017-02-23 23:00:25442 base::Unretained(&permission_context)));
dominickn6da2b382016-08-23 20:21:30443 histograms.ExpectTotalCount(
dominickn2e27dea2017-02-23 23:00:25444 "Permissions.Prompt.Dismissed.PriorDismissCount.Geolocation", i + 1);
dominickn6da2b382016-08-23 20:21:30445 histograms.ExpectBucketCount(
446 "Permissions.Prompt.Dismissed.PriorDismissCount.Geolocation", i, 1);
dominickn23913152017-02-23 12:04:02447 histograms.ExpectUniqueSample(
448 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25449 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn23913152017-02-23 12:04:02450
451// On Android, repeatedly requesting and deciding permissions has the side
452// effect of overcounting any metrics recorded in the PermissionInfoBarDelegate
453// destructor. This is because we directly call
454// PermissionQueueController::OnPermissionSet without setting the action_taken
455// bit in PermissionInfoBarDelegate. When PermissionQueueController is deleted
456// all OS_ANDROID ifdefs in this test can be removed.
457#if !defined(OS_ANDROID)
dominickn2e27dea2017-02-23 23:00:25458 histograms.ExpectUniqueSample(
459 "Permissions.AutoBlocker.EmbargoStatus",
460 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn23913152017-02-23 12:04:02461#endif
dominickn79b96cc2017-02-14 04:14:21462
thestig9bdf7f22016-09-28 00:56:20463 ASSERT_EQ(1u, permission_context.decisions().size());
dominickn6947d752016-08-10 02:00:06464 EXPECT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
465 EXPECT_TRUE(permission_context.tab_context_updated());
466 EXPECT_EQ(CONTENT_SETTING_ASK,
467 permission_context.GetContentSettingFromMap(url, url));
468 }
469
470 // Flush the dismissal counts. Enable the block on too many dismissals
471 // feature, which is disabled by default.
thestig9bdf7f22016-09-28 00:56:20472 auto* map = HostContentSettingsMapFactory::GetForProfile(profile());
473 map->ClearSettingsForOneType(
raymesd9c50e12017-02-01 20:03:35474 CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA);
dominickn6947d752016-08-10 02:00:06475
dominicknc2726ec2016-09-15 12:15:39476 base::test::ScopedFeatureList feature_list;
477 feature_list.InitAndEnableFeature(features::kBlockPromptsIfDismissedOften);
dominickn6947d752016-08-10 02:00:06478
479 EXPECT_TRUE(
480 base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften));
481
482 // Sanity check independence per permission type by checking two of them.
dominickn2e27dea2017-02-23 23:00:25483 DismissMultipleTimesAndExpectBlock(url, CONTENT_SETTINGS_TYPE_GEOLOCATION,
484 3);
485 DismissMultipleTimesAndExpectBlock(url, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
486 3);
dominickn6947d752016-08-10 02:00:06487 }
488
489 void TestVariationBlockOnSeveralDismissals_TestContent() {
490 GURL url("https://www.google.com");
491 NavigateAndCommit(url);
dominickn6da2b382016-08-23 20:21:30492 base::HistogramTester histograms;
dominickn6947d752016-08-10 02:00:06493
494 // Set up the custom parameter and custom value.
thestig9bdf7f22016-09-28 00:56:20495 base::FieldTrialList field_trials(nullptr);
dominickn6947d752016-08-10 02:00:06496 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
497 kPromptTrialName, kPromptGroupName);
498 std::map<std::string, std::string> params;
499 params[PermissionDecisionAutoBlocker::kPromptDismissCountKey] = "5";
dominickn2e27dea2017-02-23 23:00:25500 ASSERT_TRUE(variations::AssociateVariationParams(kPromptTrialName,
501 kPromptGroupName, params));
dominickn6947d752016-08-10 02:00:06502
thestig9bdf7f22016-09-28 00:56:20503 std::unique_ptr<base::FeatureList> feature_list =
504 base::MakeUnique<base::FeatureList>();
dominickn6947d752016-08-10 02:00:06505 feature_list->RegisterFieldTrialOverride(
506 features::kBlockPromptsIfDismissedOften.name,
507 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
thestig9bdf7f22016-09-28 00:56:20508
509 base::test::ScopedFeatureList scoped_feature_list;
510 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
511
dominickn6947d752016-08-10 02:00:06512 EXPECT_EQ(base::FeatureList::GetFieldTrial(
513 features::kBlockPromptsIfDismissedOften),
514 trial);
515
thestig9bdf7f22016-09-28 00:56:20516 {
517 std::map<std::string, std::string> actual_params;
518 EXPECT_TRUE(variations::GetVariationParamsByFeature(
519 features::kBlockPromptsIfDismissedOften, &actual_params));
520 EXPECT_EQ(params, actual_params);
521 }
dominickn6947d752016-08-10 02:00:06522
523 for (uint32_t i = 0; i < 5; ++i) {
524 TestPermissionContext permission_context(
timloh9a180ad2017-02-20 07:15:23525 profile(), CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
dominickn6947d752016-08-10 02:00:06526
dominickn6947d752016-08-10 02:00:06527 const PermissionRequestID id(
528 web_contents()->GetRenderProcessHost()->GetID(),
529 web_contents()->GetMainFrame()->GetRoutingID(), i);
meredithl62b8c3d2017-01-10 05:47:53530 permission_context.SetRespondPermissionCallback(
531 base::Bind(&PermissionContextBaseTests::RespondToPermission,
532 base::Unretained(this), &permission_context, id, url,
533 false, CONTENT_SETTING_ASK));
dominickn6947d752016-08-10 02:00:06534 permission_context.RequestPermission(
535 web_contents(), id, url, true /* user_gesture */,
536 base::Bind(&TestPermissionContext::TrackPermissionDecision,
meredithl62b8c3d2017-01-10 05:47:53537 base::Unretained(&permission_context)));
dominickn6947d752016-08-10 02:00:06538
dominickn6947d752016-08-10 02:00:06539 EXPECT_EQ(1u, permission_context.decisions().size());
dominickn79b96cc2017-02-14 04:14:21540 ASSERT_EQ(CONTENT_SETTING_ASK, permission_context.decisions()[0]);
dominickn6947d752016-08-10 02:00:06541 EXPECT_TRUE(permission_context.tab_context_updated());
raymesf6104d492017-03-09 01:20:18542 PermissionResult result = permission_context.GetPermissionStatus(
543 nullptr /* render_frame_host */, url, url);
dominickn6da2b382016-08-23 20:21:30544
545 histograms.ExpectTotalCount(
546 "Permissions.Prompt.Dismissed.PriorDismissCount.MidiSysEx", i + 1);
547 histograms.ExpectBucketCount(
548 "Permissions.Prompt.Dismissed.PriorDismissCount.MidiSysEx", i, 1);
dominickn23913152017-02-23 12:04:02549 histograms.ExpectUniqueSample(
550 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25551 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn79b96cc2017-02-14 04:14:21552
dominickn23913152017-02-23 12:04:02553// On Android, repeatedly requesting and deciding permissions has the side
554// effect of overcounting any metrics recorded in the PermissionInfoBarDelegate
555// destructor. This is because we directly call
556// PermissionQueueController::OnPermissionSet without setting the action_taken
557// bit in PermissionInfoBarDelegate. When PermissionQueueController is deleted
558// all OS_ANDROID ifdefs in this test can be removed.
559#if !defined(OS_ANDROID)
dominickn79b96cc2017-02-14 04:14:21560 histograms.ExpectTotalCount("Permissions.AutoBlocker.EmbargoStatus",
561 i + 1);
dominickn23913152017-02-23 12:04:02562#endif
dominickn79b96cc2017-02-14 04:14:21563 if (i < 4) {
dominickn23913152017-02-23 12:04:02564 EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting);
565 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
566#if !defined(OS_ANDROID)
dominickn2e27dea2017-02-23 23:00:25567 histograms.ExpectUniqueSample(
568 "Permissions.AutoBlocker.EmbargoStatus",
569 static_cast<int>(PermissionEmbargoStatus::NOT_EMBARGOED), i + 1);
dominickn23913152017-02-23 12:04:02570#endif
dominickn79b96cc2017-02-14 04:14:21571 } else {
dominickn23913152017-02-23 12:04:02572 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
573 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
574#if !defined(OS_ANDROID)
dominickn79b96cc2017-02-14 04:14:21575 histograms.ExpectBucketCount(
576 "Permissions.AutoBlocker.EmbargoStatus",
dominickn2e27dea2017-02-23 23:00:25577 static_cast<int>(PermissionEmbargoStatus::REPEATED_DISMISSALS), 1);
dominickn23913152017-02-23 12:04:02578#endif
dominickn79b96cc2017-02-14 04:14:21579 }
dominickn6947d752016-08-10 02:00:06580 }
581
582 // Ensure that we finish in the block state.
timloh9a180ad2017-02-20 07:15:23583 TestPermissionContext permission_context(profile(),
584 CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
raymesf6104d492017-03-09 01:20:18585 PermissionResult result = permission_context.GetPermissionStatus(
586 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25587 EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting);
dominickn23913152017-02-23 12:04:02588 EXPECT_EQ(PermissionStatusSource::MULTIPLE_DISMISSALS, result.source);
dominickn6947d752016-08-10 02:00:06589 variations::testing::ClearAllVariationParams();
590 }
591
lshang88ec36a2015-12-09 04:50:17592 void TestRequestPermissionInvalidUrl(
lshang88ec36a2015-12-09 04:50:17593 ContentSettingsType content_settings_type) {
dominickn23913152017-02-23 12:04:02594 base::HistogramTester histograms;
timloh9a180ad2017-02-20 07:15:23595 TestPermissionContext permission_context(profile(), content_settings_type);
timvolodinea2830552015-01-20 17:21:23596 GURL url;
597 ASSERT_FALSE(url.is_valid());
johnme7fa91f72016-01-29 22:13:44598 NavigateAndCommit(url);
timvolodinea2830552015-01-20 17:21:23599
600 const PermissionRequestID id(
601 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25602 web_contents()->GetMainFrame()->GetRoutingID(), -1);
timvolodinea2830552015-01-20 17:21:23603 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25604 web_contents(), id, url, true /* user_gesture */,
timvolodinea2830552015-01-20 17:21:23605 base::Bind(&TestPermissionContext::TrackPermissionDecision,
606 base::Unretained(&permission_context)));
607
thestig9bdf7f22016-09-28 00:56:20608 ASSERT_EQ(1u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44609 EXPECT_EQ(CONTENT_SETTING_BLOCK, permission_context.decisions()[0]);
timvolodinea2830552015-01-20 17:21:23610 EXPECT_TRUE(permission_context.tab_context_updated());
johnmec41dfee2016-01-13 14:35:16611 EXPECT_EQ(CONTENT_SETTING_ASK,
612 permission_context.GetContentSettingFromMap(url, url));
dominickn23913152017-02-23 12:04:02613 histograms.ExpectTotalCount(
614 "Permissions.AutoBlocker.EmbargoPromptSuppression", 0);
timvolodinea2830552015-01-20 17:21:23615 }
616
timloh9a180ad2017-02-20 07:15:23617 void TestGrantAndRevoke_TestContent(ContentSettingsType content_settings_type,
timvolodine16be5202015-02-02 17:44:54618 ContentSetting expected_default) {
timloh9a180ad2017-02-20 07:15:23619 TestPermissionContext permission_context(profile(), content_settings_type);
toyoshim9eb573f42015-03-30 10:39:39620 GURL url("https://www.google.com");
johnme7fa91f72016-01-29 22:13:44621 NavigateAndCommit(url);
timvolodine16be5202015-02-02 17:44:54622
623 const PermissionRequestID id(
624 web_contents()->GetRenderProcessHost()->GetID(),
dominickn2e27dea2017-02-23 23:00:25625 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl62b8c3d2017-01-10 05:47:53626 permission_context.SetRespondPermissionCallback(
627 base::Bind(&PermissionContextBaseTests::RespondToPermission,
628 base::Unretained(this), &permission_context, id, url, true,
629 CONTENT_SETTING_ALLOW));
630
timvolodine16be5202015-02-02 17:44:54631 permission_context.RequestPermission(
dominickn2e27dea2017-02-23 23:00:25632 web_contents(), id, url, true /* user_gesture */,
timvolodine16be5202015-02-02 17:44:54633 base::Bind(&TestPermissionContext::TrackPermissionDecision,
634 base::Unretained(&permission_context)));
635
thestig9bdf7f22016-09-28 00:56:20636 ASSERT_EQ(1u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44637 EXPECT_EQ(CONTENT_SETTING_ALLOW, permission_context.decisions()[0]);
timvolodine16be5202015-02-02 17:44:54638 EXPECT_TRUE(permission_context.tab_context_updated());
johnmec41dfee2016-01-13 14:35:16639 EXPECT_EQ(CONTENT_SETTING_ALLOW,
640 permission_context.GetContentSettingFromMap(url, url));
timvolodine16be5202015-02-02 17:44:54641
642 // Try to reset permission.
643 permission_context.ResetPermission(url.GetOrigin(), url.GetOrigin());
644 ContentSetting setting_after_reset =
johnmec41dfee2016-01-13 14:35:16645 permission_context.GetContentSettingFromMap(url, url);
timvolodine16be5202015-02-02 17:44:54646 ContentSetting default_setting =
peconn5100d432015-09-16 12:03:08647 HostContentSettingsMapFactory::GetForProfile(profile())
lshang88ec36a2015-12-09 04:50:17648 ->GetDefaultContentSetting(content_settings_type, nullptr);
timvolodine16be5202015-02-02 17:44:54649 EXPECT_EQ(default_setting, setting_after_reset);
650 }
651
lshang88ec36a2015-12-09 04:50:17652 void TestGlobalPermissionsKillSwitch(
lshang88ec36a2015-12-09 04:50:17653 ContentSettingsType content_settings_type) {
timloh9a180ad2017-02-20 07:15:23654 TestKillSwitchPermissionContext permission_context(profile(),
655 content_settings_type);
kcarattini2ee48ad52015-10-26 23:45:31656 permission_context.ResetFieldTrialList();
657
658 EXPECT_FALSE(permission_context.IsPermissionKillSwitchOn());
659 std::map<std::string, std::string> params;
timloh9a180ad2017-02-20 07:15:23660 params[PermissionUtil::GetPermissionString(content_settings_type)] =
kcarattini2ee48ad52015-10-26 23:45:31661 kPermissionsKillSwitchBlockedValue;
dominickn2e27dea2017-02-23 23:00:25662 variations::AssociateVariationParams(kPermissionsKillSwitchFieldStudy,
663 kPermissionsKillSwitchTestGroup,
664 params);
kcarattini2ee48ad52015-10-26 23:45:31665 base::FieldTrialList::CreateFieldTrial(kPermissionsKillSwitchFieldStudy,
666 kPermissionsKillSwitchTestGroup);
667 EXPECT_TRUE(permission_context.IsPermissionKillSwitchOn());
668 }
669
johnme7fa91f72016-01-29 22:13:44670 // Don't call this more than once in the same test, as it persists data to
671 // HostContentSettingsMap.
672 void TestParallelRequests(ContentSetting response) {
673 TestPermissionContext permission_context(
timloh9a180ad2017-02-20 07:15:23674 profile(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
johnme7fa91f72016-01-29 22:13:44675 GURL url("http://www.google.com");
676 NavigateAndCommit(url);
677
678 const PermissionRequestID id0(
679 web_contents()->GetRenderProcessHost()->GetID(),
680 web_contents()->GetMainFrame()->GetRoutingID(), 0);
681 const PermissionRequestID id1(
682 web_contents()->GetRenderProcessHost()->GetID(),
683 web_contents()->GetMainFrame()->GetRoutingID(), 1);
684
meredithl62b8c3d2017-01-10 05:47:53685 bool persist = (response == CONTENT_SETTING_ALLOW ||
686 response == CONTENT_SETTING_BLOCK);
687
688 // Request a permission without setting the callback to DecidePermission.
johnme7fa91f72016-01-29 22:13:44689 permission_context.RequestPermission(
benwellsfd2b1552016-07-05 04:26:53690 web_contents(), id0, url, true /* user_gesture */,
johnme7fa91f72016-01-29 22:13:44691 base::Bind(&TestPermissionContext::TrackPermissionDecision,
692 base::Unretained(&permission_context)));
johnme7fa91f72016-01-29 22:13:44693
694 EXPECT_EQ(0u, permission_context.decisions().size());
695
meredithl62b8c3d2017-01-10 05:47:53696 // Set the callback, and make a second permission request.
697 permission_context.SetRespondPermissionCallback(
698 base::Bind(&PermissionContextBaseTests::RespondToPermission,
699 base::Unretained(this), &permission_context, id0, url,
700 persist, response));
701 permission_context.RequestPermission(
702 web_contents(), id1, url, true /* user_gesture */,
703 base::Bind(&TestPermissionContext::TrackPermissionDecision,
704 base::Unretained(&permission_context)));
johnme7fa91f72016-01-29 22:13:44705
thestig9bdf7f22016-09-28 00:56:20706 ASSERT_EQ(2u, permission_context.decisions().size());
johnme7fa91f72016-01-29 22:13:44707 EXPECT_EQ(response, permission_context.decisions()[0]);
708 EXPECT_EQ(response, permission_context.decisions()[1]);
709 EXPECT_TRUE(permission_context.tab_context_updated());
710
711 EXPECT_EQ(response, permission_context.GetContentSettingFromMap(url, url));
712 }
713
meredithl62b8c3d2017-01-10 05:47:53714 void TestPermissionsBlacklisting(
meredithl62b8c3d2017-01-10 05:47:53715 ContentSettingsType content_settings_type,
716 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager,
717 const GURL& url,
718 int timeout,
dominickn79b96cc2017-02-14 04:14:21719 ContentSetting expected_permission_status,
720 PermissionEmbargoStatus expected_embargo_reason) {
meredithl62b8c3d2017-01-10 05:47:53721 NavigateAndCommit(url);
dominickn79b96cc2017-02-14 04:14:21722 base::HistogramTester histograms;
meredithl62b8c3d2017-01-10 05:47:53723 base::test::ScopedFeatureList scoped_feature_list;
724 scoped_feature_list.InitAndEnableFeature(features::kPermissionsBlacklist);
timloh9a180ad2017-02-20 07:15:23725 TestPermissionContext permission_context(profile(), content_settings_type);
meredithl03b12852017-01-25 05:08:01726 PermissionDecisionAutoBlocker::GetForProfile(profile())
727 ->SetSafeBrowsingDatabaseManagerAndTimeoutForTesting(db_manager,
728 timeout);
meredithl62b8c3d2017-01-10 05:47:53729 const PermissionRequestID id(
730 web_contents()->GetRenderProcessHost()->GetID(),
731 web_contents()->GetMainFrame()->GetRoutingID(), -1);
meredithl03b12852017-01-25 05:08:01732
733 // A response only needs to be made to the permission request if we do not
dominickn23913152017-02-23 12:04:02734 // expect the permission to be blacklisted.
meredithl03b12852017-01-25 05:08:01735 if (expected_permission_status == CONTENT_SETTING_ALLOW) {
736 permission_context.SetRespondPermissionCallback(
737 base::Bind(&PermissionContextBaseTests::RespondToPermission,
738 base::Unretained(this), &permission_context, id, url,
739 true /* persist */, expected_permission_status));
740 }
741
meredithl62b8c3d2017-01-10 05:47:53742 permission_context.RequestPermission(
743 web_contents(), id, url, true /* user_gesture */,
744 base::Bind(&TestPermissionContext::TrackPermissionDecision,
745 base::Unretained(&permission_context)));
raymesf6104d492017-03-09 01:20:18746 PermissionResult result = permission_context.GetPermissionStatus(
747 nullptr /* render_frame_host */, url, url);
raymesab359712017-02-15 06:23:25748 EXPECT_EQ(expected_permission_status, result.content_setting);
meredithl62b8c3d2017-01-10 05:47:53749
meredithl03b12852017-01-25 05:08:01750 if (expected_permission_status == CONTENT_SETTING_ALLOW) {
751 ASSERT_EQ(1u, permission_context.decisions().size());
752 EXPECT_EQ(expected_permission_status, permission_context.decisions()[0]);
dominickn23913152017-02-23 12:04:02753 EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source);
754 } else {
755 EXPECT_EQ(PermissionStatusSource::SAFE_BROWSING_BLACKLIST, result.source);
meredithl03b12852017-01-25 05:08:01756 }
dominickn23913152017-02-23 12:04:02757 histograms.ExpectUniqueSample(
758 "Permissions.AutoBlocker.EmbargoPromptSuppression",
dominickn2e27dea2017-02-23 23:00:25759 static_cast<int>(expected_embargo_reason), 1);
dominickn79b96cc2017-02-14 04:14:21760 histograms.ExpectUniqueSample("Permissions.AutoBlocker.EmbargoStatus",
dominickn2e27dea2017-02-23 23:00:25761 static_cast<int>(expected_embargo_reason), 1);
meredithl62b8c3d2017-01-10 05:47:53762 }
763
felt88bf98cb2014-12-16 03:50:23764 private:
765 // ChromeRenderViewHostTestHarness:
dcheng171318362014-12-29 18:31:25766 void SetUp() override {
felt88bf98cb2014-12-16 03:50:23767 ChromeRenderViewHostTestHarness::SetUp();
estade6d95d1d2015-10-02 18:55:23768#if defined(OS_ANDROID)
felt88bf98cb2014-12-16 03:50:23769 InfoBarService::CreateForWebContents(web_contents());
estade6d95d1d2015-10-02 18:55:23770#else
tsergeanta771c23e2016-07-13 04:54:52771 PermissionRequestManager::CreateForWebContents(web_contents());
estade6d95d1d2015-10-02 18:55:23772#endif
felt88bf98cb2014-12-16 03:50:23773 }
774
775 DISALLOW_COPY_AND_ASSIGN(PermissionContextBaseTests);
776};
777
[email protected]89a8dd5d2014-07-11 12:02:07778// Simulates clicking Accept. The permission should be granted and
779// saved for future use.
dominicknd4e446a2016-09-13 07:44:13780TEST_F(PermissionContextBaseTests, TestAskAndGrantPersist) {
timloh9a180ad2017-02-20 07:15:23781 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
dominicknd4e446a2016-09-13 07:44:13782 CONTENT_SETTING_ALLOW, true);
783}
784
785// Simulates clicking Accept. The permission should be granted, but not
786// persisted.
787TEST_F(PermissionContextBaseTests, TestAskAndGrantNoPersist) {
timloh9a180ad2017-02-20 07:15:23788 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
dominicknd4e446a2016-09-13 07:44:13789 CONTENT_SETTING_ALLOW, false);
790}
791
792// Simulates clicking Block. The permission should be denied and
793// saved for future use.
794TEST_F(PermissionContextBaseTests, TestAskAndBlockPersist) {
timloh9a180ad2017-02-20 07:15:23795 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
dominicknd4e446a2016-09-13 07:44:13796 CONTENT_SETTING_BLOCK, true);
797}
798
799// Simulates clicking Block. The permission should be denied, but not persisted.
800TEST_F(PermissionContextBaseTests, TestAskAndBlockNoPersist) {
timloh9a180ad2017-02-20 07:15:23801 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
dominicknd4e446a2016-09-13 07:44:13802 CONTENT_SETTING_BLOCK, false);
timvolodinea2830552015-01-20 17:21:23803}
[email protected]89a8dd5d2014-07-11 12:02:07804
felt88bf98cb2014-12-16 03:50:23805// Simulates clicking Dismiss (X) in the infobar/bubble.
[email protected]89a8dd5d2014-07-11 12:02:07806// The permission should be denied but not saved for future use.
807TEST_F(PermissionContextBaseTests, TestAskAndDismiss) {
timloh9a180ad2017-02-20 07:15:23808 TestAskAndDecide_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
dominicknd4e446a2016-09-13 07:44:13809 CONTENT_SETTING_ASK, false);
timvolodinea2830552015-01-20 17:21:23810}
811
dominickn6947d752016-08-10 02:00:06812// Simulates clicking Dismiss (X) in the infobar/bubble with the block on too
813// many dismissals feature active. The permission should be blocked after
814// several dismissals.
815TEST_F(PermissionContextBaseTests, TestDismissUntilBlocked) {
816 TestBlockOnSeveralDismissals_TestContent();
817}
818
819// Test setting a custom number of dismissals before block via variations.
820TEST_F(PermissionContextBaseTests, TestDismissVariations) {
821 TestVariationBlockOnSeveralDismissals_TestContent();
822}
823
timvolodinea2830552015-01-20 17:21:23824// Simulates non-valid requesting URL.
825// The permission should be denied but not saved for future use.
826TEST_F(PermissionContextBaseTests, TestNonValidRequestingUrl) {
timloh9a180ad2017-02-20 07:15:23827 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_GEOLOCATION);
828 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
829 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
830 TestRequestPermissionInvalidUrl(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
timvolodinea2830552015-01-20 17:21:23831#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
832 TestRequestPermissionInvalidUrl(
833 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
834#endif
835}
timvolodine16be5202015-02-02 17:44:54836
feltcb9e7362015-06-25 00:36:43837#if defined(OS_ANDROID)
838// This test is specific to Android because other platforms use bubbles.
839TEST_F(PermissionContextBaseTests, TestGrantAndRevokeWithInfobars) {
timloh9a180ad2017-02-20 07:15:23840 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
timvolodine16be5202015-02-02 17:44:54841 CONTENT_SETTING_ASK);
timloh9a180ad2017-02-20 07:15:23842 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
timvolodine16be5202015-02-02 17:44:54843 CONTENT_SETTING_ASK);
timvolodine16be5202015-02-02 17:44:54844 TestGrantAndRevoke_TestContent(
845 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, CONTENT_SETTING_ASK);
timvolodine16be5202015-02-02 17:44:54846 // TODO(timvolodine): currently no test for
847 // CONTENT_SETTINGS_TYPE_NOTIFICATIONS because notification permissions work
848 // differently with infobars as compared to bubbles (crbug.com/453784).
timvolodine16be5202015-02-02 17:44:54849}
feltcb9e7362015-06-25 00:36:43850#endif
timvolodine16be5202015-02-02 17:44:54851
jam1c5a91492016-02-24 20:47:53852#if !defined(OS_ANDROID)
timvolodine16be5202015-02-02 17:44:54853// Simulates granting and revoking of permissions using permission bubbles.
feltcb9e7362015-06-25 00:36:43854// This test shouldn't run on mobile because mobile platforms use infobars.
timvolodine16be5202015-02-02 17:44:54855TEST_F(PermissionContextBaseTests, TestGrantAndRevokeWithBubbles) {
timloh9a180ad2017-02-20 07:15:23856 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_GEOLOCATION,
timvolodine16be5202015-02-02 17:44:54857 CONTENT_SETTING_ASK);
timloh9a180ad2017-02-20 07:15:23858 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
timvolodine16be5202015-02-02 17:44:54859 CONTENT_SETTING_ASK);
timloh9a180ad2017-02-20 07:15:23860 TestGrantAndRevoke_TestContent(CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
timvolodine16be5202015-02-02 17:44:54861 CONTENT_SETTING_ASK);
timvolodine16be5202015-02-02 17:44:54862}
feltcb9e7362015-06-25 00:36:43863#endif
kcarattini2ee48ad52015-10-26 23:45:31864
865// Tests the global kill switch by enabling/disabling the Field Trials.
866TEST_F(PermissionContextBaseTests, TestGlobalKillSwitch) {
timloh9a180ad2017-02-20 07:15:23867 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_GEOLOCATION);
868 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
869 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MIDI_SYSEX);
870 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING);
871 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_DURABLE_STORAGE);
kcarattini2ee48ad52015-10-26 23:45:31872#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
873 TestGlobalPermissionsKillSwitch(
874 CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
875#endif
timloh9a180ad2017-02-20 07:15:23876 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
877 TestGlobalPermissionsKillSwitch(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
kcarattini2ee48ad52015-10-26 23:45:31878}
johnme7fa91f72016-01-29 22:13:44879
880TEST_F(PermissionContextBaseTests, TestParallelRequestsAllowed) {
881 TestParallelRequests(CONTENT_SETTING_ALLOW);
882}
883
884TEST_F(PermissionContextBaseTests, TestParallelRequestsBlocked) {
885 TestParallelRequests(CONTENT_SETTING_BLOCK);
886}
887
888TEST_F(PermissionContextBaseTests, TestParallelRequestsDismissed) {
889 TestParallelRequests(CONTENT_SETTING_ASK);
890}
meredithl62b8c3d2017-01-10 05:47:53891
892// Tests a blacklisted (URL, permission) pair has had its permission request
893// blocked.
894TEST_F(PermissionContextBaseTests, TestPermissionsBlacklistingBlocked) {
895 scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
896 new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
897 const GURL url("https://www.example.com");
meredithl03b12852017-01-25 05:08:01898 std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
meredithl62b8c3d2017-01-10 05:47:53899 db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
dominickn79b96cc2017-02-14 04:14:21900 TestPermissionsBlacklisting(
dominickn2e27dea2017-02-23 23:00:25901 CONTENT_SETTINGS_TYPE_GEOLOCATION, db_manager, url, 2000 /* timeout */,
902 CONTENT_SETTING_BLOCK, PermissionEmbargoStatus::PERMISSIONS_BLACKLISTING);
meredithl62b8c3d2017-01-10 05:47:53903}
904
meredithl03b12852017-01-25 05:08:01905// Tests that a URL that is blacklisted for one permission can still request
906// another and grant another.
meredithl62b8c3d2017-01-10 05:47:53907TEST_F(PermissionContextBaseTests, TestPermissionsBlacklistingAllowed) {
908 scoped_refptr<MockSafeBrowsingDatabaseManager> db_manager =
909 new MockSafeBrowsingDatabaseManager(true /* perform_callback */);
910 const GURL url("https://www.example.com");
meredithl03b12852017-01-25 05:08:01911 std::set<std::string> blacklisted_permissions{"GEOLOCATION"};
meredithl62b8c3d2017-01-10 05:47:53912 db_manager->BlacklistUrlPermissions(url, blacklisted_permissions);
timloh9a180ad2017-02-20 07:15:23913 TestPermissionsBlacklisting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, db_manager,
dominickn79b96cc2017-02-14 04:14:21914 url, 2000 /* timeout */, CONTENT_SETTING_ALLOW,
915 PermissionEmbargoStatus::NOT_EMBARGOED);
meredithl62b8c3d2017-01-10 05:47:53916}