12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <stddef.h>
- #include <memory>
- #include <string>
- #include "base/bind.h"
- #include "base/command_line.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "build/build_config.h"
- #include "components/permissions/features.h"
- #include "components/permissions/permission_request.h"
- #include "components/permissions/permission_request_manager.h"
- #include "components/permissions/permission_ui_selector.h"
- #include "components/permissions/permission_uma_util.h"
- #include "components/permissions/request_type.h"
- #include "components/permissions/test/mock_permission_prompt_factory.h"
- #include "components/permissions/test/mock_permission_request.h"
- #include "components/permissions/test/test_permissions_client.h"
- #include "content/public/test/test_renderer_host.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace permissions {
- namespace {
- using QuietUiReason = PermissionUiSelector::QuietUiReason;
- }
- class PermissionRequestManagerTest
- : public content::RenderViewHostTestHarness,
- public ::testing::WithParamInterface<bool> {
- public:
- PermissionRequestManagerTest()
- : request1_(RequestType::kGeolocation,
- PermissionRequestGestureType::GESTURE),
- request2_(RequestType::kMultipleDownloads,
- PermissionRequestGestureType::NO_GESTURE),
- request_mic_(RequestType::kMicStream,
- PermissionRequestGestureType::NO_GESTURE),
- request_camera_(RequestType::kCameraStream,
- PermissionRequestGestureType::NO_GESTURE),
- #if !BUILDFLAG(IS_ANDROID)
- request_ptz_(RequestType::kCameraPanTiltZoom,
- PermissionRequestGestureType::NO_GESTURE),
- #endif
- iframe_request_same_domain_(GURL("https://www.google.com/some/url"),
- RequestType::kMidiSysex),
- iframe_request_other_domain_(GURL("https://www.youtube.com"),
- RequestType::kGeolocation),
- iframe_request_camera_other_domain_(GURL("https://www.youtube.com"),
- RequestType::kStorageAccess),
- iframe_request_mic_other_domain_(GURL("https://www.youtube.com"),
- RequestType::kMicStream) {
- if (GetParam()) {
- feature_list_.InitWithFeatures(
- {permissions::features::kPermissionChip},
- {permissions::features::kPermissionQuietChip});
- } else {
- feature_list_.InitWithFeatures(
- {}, {permissions::features::kPermissionChip,
- permissions::features::kPermissionQuietChip});
- }
- }
- void SetUp() override {
- content::RenderViewHostTestHarness::SetUp();
- SetContents(CreateTestWebContents());
- NavigateAndCommit(GURL(permissions::MockPermissionRequest::kDefaultOrigin));
- PermissionRequestManager::CreateForWebContents(web_contents());
- manager_ = PermissionRequestManager::FromWebContents(web_contents());
- manager_->set_enabled_app_level_notification_permission_for_testing(true);
- prompt_factory_ = std::make_unique<MockPermissionPromptFactory>(manager_);
- }
- void TearDown() override {
- prompt_factory_ = nullptr;
- content::RenderViewHostTestHarness::TearDown();
- }
- void Accept() {
- manager_->Accept();
- base::RunLoop().RunUntilIdle();
- }
- void Deny() {
- manager_->Deny();
- base::RunLoop().RunUntilIdle();
- }
- void Closing() {
- manager_->Dismiss();
- base::RunLoop().RunUntilIdle();
- }
- void WaitForFrameLoad() {
- // PermissionRequestManager ignores all parameters. Yay?
- manager_->DOMContentLoaded(nullptr);
- base::RunLoop().RunUntilIdle();
- }
- void WaitForBubbleToBeShown() {
- manager_->DocumentOnLoadCompletedInPrimaryMainFrame();
- base::RunLoop().RunUntilIdle();
- }
- void MockTabSwitchAway() {
- manager_->OnVisibilityChanged(content::Visibility::HIDDEN);
- }
- void MockTabSwitchBack() {
- manager_->OnVisibilityChanged(content::Visibility::VISIBLE);
- }
- virtual void NavigationEntryCommitted(
- const content::LoadCommittedDetails& details) {
- manager_->NavigationEntryCommitted(details);
- }
- std::unique_ptr<MockPermissionRequest> CreateAndAddRequest(
- RequestType type,
- bool should_be_seen,
- int expected_request_count) {
- std::unique_ptr<MockPermissionRequest> request =
- std::make_unique<MockPermissionRequest>(
- type, PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), request.get());
- WaitForBubbleToBeShown();
- if (should_be_seen) {
- EXPECT_TRUE(prompt_factory_->RequestTypeSeen(type));
- } else {
- EXPECT_FALSE(prompt_factory_->RequestTypeSeen(type));
- }
- EXPECT_EQ(prompt_factory_->TotalRequestCount(), expected_request_count);
- return request;
- }
- void WaitAndAcceptPromptForRequest(MockPermissionRequest* request) {
- WaitForBubbleToBeShown();
- EXPECT_FALSE(request->finished());
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request->granted());
- }
- protected:
- MockPermissionRequest request1_;
- MockPermissionRequest request2_;
- MockPermissionRequest request_mic_;
- MockPermissionRequest request_camera_;
- #if !BUILDFLAG(IS_ANDROID)
- MockPermissionRequest request_ptz_;
- #endif
- MockPermissionRequest iframe_request_same_domain_;
- MockPermissionRequest iframe_request_other_domain_;
- MockPermissionRequest iframe_request_camera_other_domain_;
- MockPermissionRequest iframe_request_mic_other_domain_;
- raw_ptr<PermissionRequestManager> manager_;
- std::unique_ptr<MockPermissionPromptFactory> prompt_factory_;
- TestPermissionsClient client_;
- base::test::ScopedFeatureList feature_list_;
- };
- ////////////////////////////////////////////////////////////////////////////////
- // General
- ////////////////////////////////////////////////////////////////////////////////
- TEST_P(PermissionRequestManagerTest, NoRequests) {
- WaitForBubbleToBeShown();
- EXPECT_FALSE(prompt_factory_->is_visible());
- }
- TEST_P(PermissionRequestManagerTest, SingleRequest) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request1_.granted());
- }
- TEST_P(PermissionRequestManagerTest, SequentialRequests) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- Accept();
- EXPECT_TRUE(request1_.granted());
- EXPECT_FALSE(prompt_factory_->is_visible());
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- Accept();
- EXPECT_FALSE(prompt_factory_->is_visible());
- EXPECT_TRUE(request2_.granted());
- }
- TEST_P(PermissionRequestManagerTest, ForgetRequestsOnPageNavigation) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_other_domain_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- NavigateAndCommit(GURL("http://www2.google.com/"));
- WaitForBubbleToBeShown();
- EXPECT_FALSE(prompt_factory_->is_visible());
- EXPECT_TRUE(request1_.finished());
- EXPECT_TRUE(request2_.finished());
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- }
- TEST_P(PermissionRequestManagerTest, RequestsDontNeedUserGesture) {
- WaitForFrameLoad();
- WaitForBubbleToBeShown();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_other_domain_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(prompt_factory_->is_visible());
- }
- TEST_P(PermissionRequestManagerTest, RequestsNotSupported) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- Accept();
- EXPECT_TRUE(request1_.granted());
- manager_->set_web_contents_supports_permission_requests(false);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- EXPECT_TRUE(request2_.cancelled());
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Requests grouping
- ////////////////////////////////////////////////////////////////////////////////
- // Most requests should never be grouped.
- TEST_P(PermissionRequestManagerTest, TwoRequestsUngrouped) {
- // Grouping for chip feature is tested in ThreeRequestsStackOrderChip.
- if (GetParam())
- return;
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request1_.granted());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request2_.granted());
- ASSERT_EQ(prompt_factory_->show_count(), 2);
- }
- TEST_P(PermissionRequestManagerTest, ThreeRequestsStackOrderChip) {
- if (!GetParam())
- return;
- // Test new permissions order, requests shouldn't be grouped.
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request_mic_.granted());
- EXPECT_FALSE(request2_.granted());
- EXPECT_FALSE(request1_.granted());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request2_.granted());
- EXPECT_FALSE(request1_.granted());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request1_.granted());
- }
- // Test new permissions order by adding requests one at a time.
- TEST_P(PermissionRequestManagerTest, ThreeRequestsOneByOneStackOrderChip) {
- if (!GetParam())
- return;
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- WaitForBubbleToBeShown();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request_mic_.granted());
- EXPECT_FALSE(request2_.granted());
- EXPECT_FALSE(request1_.granted());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request2_.granted());
- EXPECT_FALSE(request1_.granted());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request1_.granted());
- }
- // Only mic/camera requests from the same origin should be grouped.
- TEST_P(PermissionRequestManagerTest, MicCameraGrouped) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 2);
- Accept();
- EXPECT_TRUE(request_mic_.granted());
- EXPECT_TRUE(request_camera_.granted());
- }
- // If mic/camera requests come from different origins, they should not be
- // grouped.
- TEST_P(PermissionRequestManagerTest, MicCameraDifferentOrigins) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_mic_other_domain_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- }
- #if !BUILDFLAG(IS_ANDROID)
- // Only camera/ptz requests from the same origin should be grouped.
- TEST_P(PermissionRequestManagerTest, CameraPtzGrouped) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_ptz_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 2);
- Accept();
- EXPECT_TRUE(request_camera_.granted());
- EXPECT_TRUE(request_ptz_.granted());
- }
- TEST_P(PermissionRequestManagerTest, CameraPtzDifferentOrigins) {
- // If camera/ptz requests come from different origins, they should not be
- // grouped.
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_camera_other_domain_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_ptz_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- }
- // Only mic/camera/ptz requests from the same origin should be grouped.
- TEST_P(PermissionRequestManagerTest, MicCameraPtzGrouped) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_ptz_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 3);
- Accept();
- EXPECT_TRUE(request_mic_.granted());
- EXPECT_TRUE(request_camera_.granted());
- EXPECT_TRUE(request_ptz_.granted());
- }
- // If mic/camera/ptz requests come from different origins, they should not be
- // grouped.
- TEST_P(PermissionRequestManagerTest, MicCameraPtzDifferentOrigins) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_mic_other_domain_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_ptz_);
- WaitForBubbleToBeShown();
- // Requests should be split into two groups and each one will contain less
- // than 3 requests (1 request + 2 request for current logic and 2 requests + 1
- // request for chip).
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_LT(prompt_factory_->request_count(), 3);
- Accept();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_LT(prompt_factory_->request_count(), 3);
- }
- #endif // !BUILDFLAG(IS_ANDROID)
- // Tests mix of grouped media requests and non-groupable request.
- TEST_P(PermissionRequestManagerTest, MixOfMediaAndNotMediaRequests) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- WaitForBubbleToBeShown();
- // Requests should be split into two groups and each one will contain less
- // than 3 requests (1 request + 2 request for current logic and 2 requests + 1
- // request for chip).
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_LT(prompt_factory_->request_count(), 3);
- Accept();
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_LT(prompt_factory_->request_count(), 3);
- Accept();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Tab switching
- ////////////////////////////////////////////////////////////////////////////////
- TEST_P(PermissionRequestManagerTest, TwoRequestsTabSwitch) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_mic_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 2);
- MockTabSwitchAway();
- #if BUILDFLAG(IS_ANDROID)
- EXPECT_TRUE(prompt_factory_->is_visible());
- #else
- EXPECT_FALSE(prompt_factory_->is_visible());
- #endif
- MockTabSwitchBack();
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 2);
- Accept();
- EXPECT_TRUE(request_mic_.granted());
- EXPECT_TRUE(request_camera_.granted());
- }
- TEST_P(PermissionRequestManagerTest, PermissionRequestWhileTabSwitchedAway) {
- MockTabSwitchAway();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- EXPECT_FALSE(prompt_factory_->is_visible());
- MockTabSwitchBack();
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Duplicated requests
- ////////////////////////////////////////////////////////////////////////////////
- TEST_P(PermissionRequestManagerTest, SameRequestRejected) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- EXPECT_FALSE(request1_.finished());
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(request1_.granted());
- EXPECT_FALSE(prompt_factory_->is_visible());
- }
- TEST_P(PermissionRequestManagerTest, DuplicateRequest) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2_);
- auto dupe_request = request1_.CreateDuplicateRequest();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- dupe_request.get());
- EXPECT_FALSE(dupe_request->finished());
- EXPECT_FALSE(request1_.finished());
- auto dupe_request2 = request2_.CreateDuplicateRequest();
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- dupe_request2.get());
- EXPECT_FALSE(dupe_request2->finished());
- EXPECT_FALSE(request2_.finished());
- WaitForBubbleToBeShown();
- Accept();
- if (GetParam()) {
- EXPECT_TRUE(dupe_request2->finished());
- EXPECT_TRUE(request2_.finished());
- } else {
- EXPECT_TRUE(dupe_request->finished());
- EXPECT_TRUE(request1_.finished());
- }
- WaitForBubbleToBeShown();
- Accept();
- if (GetParam()) {
- EXPECT_TRUE(dupe_request->finished());
- EXPECT_TRUE(request1_.finished());
- } else {
- EXPECT_TRUE(dupe_request2->finished());
- EXPECT_TRUE(request2_.finished());
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Requests from iframes
- ////////////////////////////////////////////////////////////////////////////////
- TEST_P(PermissionRequestManagerTest, MainFrameNoRequestIFrameRequest) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_same_domain_);
- WaitForBubbleToBeShown();
- WaitForFrameLoad();
- EXPECT_TRUE(prompt_factory_->is_visible());
- Closing();
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- }
- TEST_P(PermissionRequestManagerTest, MainFrameAndIFrameRequestSameDomain) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_same_domain_);
- WaitForFrameLoad();
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(1, prompt_factory_->request_count());
- Closing();
- if (GetParam()) {
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- EXPECT_FALSE(request1_.finished());
- } else {
- EXPECT_TRUE(request1_.finished());
- EXPECT_FALSE(iframe_request_same_domain_.finished());
- }
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(1, prompt_factory_->request_count());
- Closing();
- EXPECT_FALSE(prompt_factory_->is_visible());
- if (GetParam())
- EXPECT_TRUE(request1_.finished());
- else
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- }
- TEST_P(PermissionRequestManagerTest, MainFrameAndIFrameRequestOtherDomain) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_other_domain_);
- WaitForFrameLoad();
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- Closing();
- if (GetParam()) {
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- EXPECT_FALSE(request1_.finished());
- } else {
- EXPECT_TRUE(request1_.finished());
- EXPECT_FALSE(iframe_request_other_domain_.finished());
- }
- EXPECT_TRUE(prompt_factory_->is_visible());
- Closing();
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- if (GetParam())
- EXPECT_TRUE(request1_.finished());
- else
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- }
- TEST_P(PermissionRequestManagerTest, IFrameRequestWhenMainRequestVisible) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_same_domain_);
- WaitForFrameLoad();
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Closing();
- if (GetParam()) {
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- EXPECT_FALSE(request1_.finished());
- } else {
- EXPECT_TRUE(request1_.finished());
- EXPECT_FALSE(iframe_request_same_domain_.finished());
- }
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Closing();
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- if (GetParam())
- EXPECT_TRUE(request1_.finished());
- else
- EXPECT_TRUE(iframe_request_same_domain_.finished());
- }
- TEST_P(PermissionRequestManagerTest,
- IFrameRequestOtherDomainWhenMainRequestVisible) {
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(),
- &iframe_request_other_domain_);
- WaitForFrameLoad();
- Closing();
- if (GetParam()) {
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- EXPECT_FALSE(request1_.finished());
- } else {
- EXPECT_TRUE(request1_.finished());
- EXPECT_FALSE(iframe_request_other_domain_.finished());
- }
- EXPECT_TRUE(prompt_factory_->is_visible());
- Closing();
- if (GetParam())
- EXPECT_TRUE(request1_.finished());
- else
- EXPECT_TRUE(iframe_request_other_domain_.finished());
- }
- ////////////////////////////////////////////////////////////////////////////////
- // UMA logging
- ////////////////////////////////////////////////////////////////////////////////
- // This code path (calling Accept on a non-merged bubble, with no accepted
- // permission) would never be used in actual Chrome, but its still tested for
- // completeness.
- TEST_P(PermissionRequestManagerTest, UMAForSimpleDeniedBubbleAlternatePath) {
- base::HistogramTester histograms;
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- // No need to test UMA for showing prompts again, they were tested in
- // UMAForSimpleAcceptedBubble.
- Deny();
- histograms.ExpectUniqueSample(PermissionUmaUtil::kPermissionsPromptDenied,
- static_cast<base::HistogramBase::Sample>(
- RequestTypeForUma::PERMISSION_GEOLOCATION),
- 1);
- }
- TEST_P(PermissionRequestManagerTest, UMAForTabSwitching) {
- base::HistogramTester histograms;
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1_);
- WaitForBubbleToBeShown();
- histograms.ExpectUniqueSample(PermissionUmaUtil::kPermissionsPromptShown,
- static_cast<base::HistogramBase::Sample>(
- RequestTypeForUma::PERMISSION_GEOLOCATION),
- 1);
- MockTabSwitchAway();
- MockTabSwitchBack();
- histograms.ExpectUniqueSample(PermissionUmaUtil::kPermissionsPromptShown,
- static_cast<base::HistogramBase::Sample>(
- RequestTypeForUma::PERMISSION_GEOLOCATION),
- 1);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // UI selectors
- ////////////////////////////////////////////////////////////////////////////////
- // Simulate a PermissionUiSelector that simply returns a predefined |ui_to_use|
- // every time.
- class MockNotificationPermissionUiSelector : public PermissionUiSelector {
- public:
- explicit MockNotificationPermissionUiSelector(
- absl::optional<QuietUiReason> quiet_ui_reason,
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- prediction_likelihood,
- bool async)
- : quiet_ui_reason_(quiet_ui_reason),
- prediction_likelihood_(prediction_likelihood),
- async_(async) {}
- void SelectUiToUse(PermissionRequest* request,
- DecisionMadeCallback callback) override {
- Decision decision(quiet_ui_reason_, Decision::ShowNoWarning());
- if (async_) {
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), decision));
- } else {
- std::move(callback).Run(decision);
- }
- }
- bool IsPermissionRequestSupported(RequestType request_type) override {
- return request_type == RequestType::kNotifications ||
- request_type == RequestType::kGeolocation;
- }
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- PredictedGrantLikelihoodForUKM() override {
- return prediction_likelihood_;
- }
- static void CreateForManager(
- PermissionRequestManager* manager,
- absl::optional<QuietUiReason> quiet_ui_reason,
- bool async,
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- prediction_likelihood = absl::nullopt) {
- manager->add_permission_ui_selector_for_testing(
- std::make_unique<MockNotificationPermissionUiSelector>(
- quiet_ui_reason, prediction_likelihood, async));
- }
- private:
- absl::optional<QuietUiReason> quiet_ui_reason_;
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- prediction_likelihood_;
- bool async_;
- };
- // Same as the MockNotificationPermissionUiSelector but handling only the
- // Camera stream request type
- class MockCameraStreamPermissionUiSelector
- : public MockNotificationPermissionUiSelector {
- public:
- explicit MockCameraStreamPermissionUiSelector(
- absl::optional<QuietUiReason> quiet_ui_reason,
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- prediction_likelihood,
- bool async)
- : MockNotificationPermissionUiSelector(quiet_ui_reason,
- prediction_likelihood,
- async) {}
- bool IsPermissionRequestSupported(RequestType request_type) override {
- return request_type == RequestType::kCameraStream;
- }
- static void CreateForManager(
- PermissionRequestManager* manager,
- absl::optional<QuietUiReason> quiet_ui_reason,
- bool async,
- absl::optional<PermissionUmaUtil::PredictionGrantLikelihood>
- prediction_likelihood = absl::nullopt) {
- manager->add_permission_ui_selector_for_testing(
- std::make_unique<MockCameraStreamPermissionUiSelector>(
- quiet_ui_reason, prediction_likelihood, async));
- }
- };
- TEST_P(PermissionRequestManagerTest,
- UiSelectorNotUsedForPermissionsOtherThanNotification) {
- manager_->clear_permission_ui_selector_for_testing();
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, PermissionUiSelector::QuietUiReason::kEnabledInPrefs,
- false /* async */);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request_camera_);
- WaitForBubbleToBeShown();
- ASSERT_TRUE(prompt_factory_->is_visible());
- ASSERT_TRUE(prompt_factory_->RequestTypeSeen(request_camera_.request_type()));
- EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- EXPECT_TRUE(request_camera_.granted());
- }
- TEST_P(PermissionRequestManagerTest, UiSelectorUsedForNotifications) {
- const struct {
- absl::optional<PermissionUiSelector::QuietUiReason> quiet_ui_reason;
- bool async;
- } kTests[] = {
- {QuietUiReason::kEnabledInPrefs, true},
- {PermissionUiSelector::Decision::UseNormalUi(), true},
- {QuietUiReason::kEnabledInPrefs, false},
- {PermissionUiSelector::Decision::UseNormalUi(), false},
- };
- for (const auto& test : kTests) {
- manager_->clear_permission_ui_selector_for_testing();
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, test.quiet_ui_reason, test.async);
- MockPermissionRequest request(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_TRUE(prompt_factory_->RequestTypeSeen(request.request_type()));
- EXPECT_EQ(!!test.quiet_ui_reason,
- manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- EXPECT_TRUE(request.granted());
- }
- }
- TEST_P(PermissionRequestManagerTest,
- UiSelectionHappensSeparatelyForEachRequest) {
- manager_->clear_permission_ui_selector_for_testing();
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, QuietUiReason::kEnabledInPrefs, true);
- MockPermissionRequest request1(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request1);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- MockPermissionRequest request2(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->clear_permission_ui_selector_for_testing();
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, PermissionUiSelector::Decision::UseNormalUi(), true);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2);
- WaitForBubbleToBeShown();
- EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- }
- TEST_P(PermissionRequestManagerTest, MultipleUiSelectors) {
- const struct {
- std::vector<absl::optional<QuietUiReason>> quiet_ui_reasons;
- std::vector<bool> simulate_delayed_decision;
- absl::optional<QuietUiReason> expected_reason;
- } kTests[] = {
- // Simple sync selectors, first one should take priority.
- {{QuietUiReason::kTriggeredByCrowdDeny, QuietUiReason::kEnabledInPrefs},
- {false, false},
- QuietUiReason::kTriggeredByCrowdDeny},
- // First selector is async but should still take priority even if it
- // returns later.
- {{QuietUiReason::kTriggeredByCrowdDeny, QuietUiReason::kEnabledInPrefs},
- {true, false},
- QuietUiReason::kTriggeredByCrowdDeny},
- // The first selector that has a quiet ui decision should be used.
- {{absl::nullopt, absl::nullopt,
- QuietUiReason::kTriggeredDueToAbusiveContent,
- QuietUiReason::kEnabledInPrefs},
- {false, true, true, false},
- QuietUiReason::kTriggeredDueToAbusiveContent},
- // If all selectors return a normal ui, it should use a normal ui.
- {{absl::nullopt, absl::nullopt}, {false, true}, absl::nullopt},
- // Use a bunch of selectors both async and sync.
- {{absl::nullopt, absl::nullopt, absl::nullopt, absl::nullopt,
- absl::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests,
- absl::nullopt, QuietUiReason::kEnabledInPrefs},
- {false, true, false, true, true, true, false, false},
- QuietUiReason::kTriggeredDueToAbusiveRequests},
- // Use a bunch of selectors all sync.
- {{absl::nullopt, absl::nullopt, absl::nullopt, absl::nullopt,
- absl::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests,
- absl::nullopt, QuietUiReason::kEnabledInPrefs},
- {false, false, false, false, false, false, false, false},
- QuietUiReason::kTriggeredDueToAbusiveRequests},
- // Use a bunch of selectors all async.
- {{absl::nullopt, absl::nullopt, absl::nullopt, absl::nullopt,
- absl::nullopt, QuietUiReason::kTriggeredDueToAbusiveRequests,
- absl::nullopt, QuietUiReason::kEnabledInPrefs},
- {true, true, true, true, true, true, true, true},
- QuietUiReason::kTriggeredDueToAbusiveRequests},
- };
- for (const auto& test : kTests) {
- manager_->clear_permission_ui_selector_for_testing();
- for (size_t i = 0; i < test.quiet_ui_reasons.size(); ++i) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, test.quiet_ui_reasons[i],
- test.simulate_delayed_decision[i]);
- }
- MockPermissionRequest request(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_TRUE(prompt_factory_->RequestTypeSeen(request.request_type()));
- if (test.expected_reason.has_value()) {
- EXPECT_EQ(test.expected_reason, manager_->ReasonForUsingQuietUi());
- } else {
- EXPECT_FALSE(manager_->ShouldCurrentRequestUseQuietUI());
- }
- Accept();
- EXPECT_TRUE(request.granted());
- }
- }
- TEST_P(PermissionRequestManagerTest, SelectorsPredictionLikelihood) {
- using PredictionLikelihood = PermissionUmaUtil::PredictionGrantLikelihood;
- const auto VeryLikely = PredictionLikelihood::
- PermissionPrediction_Likelihood_DiscretizedLikelihood_VERY_LIKELY;
- const auto Neutral = PredictionLikelihood::
- PermissionPrediction_Likelihood_DiscretizedLikelihood_NEUTRAL;
- const struct {
- std::vector<bool> enable_quiet_uis;
- std::vector<absl::optional<PredictionLikelihood>> prediction_likelihoods;
- absl::optional<PredictionLikelihood> expected_prediction_likelihood;
- } kTests[] = {
- // Sanity check: prediction likelihood is populated correctly.
- {{true}, {VeryLikely}, VeryLikely},
- {{false}, {Neutral}, Neutral},
- // Prediction likelihood is populated only if the selector was considered.
- {{true, true}, {absl::nullopt, VeryLikely}, absl::nullopt},
- {{false, true}, {absl::nullopt, VeryLikely}, VeryLikely},
- {{false, false}, {absl::nullopt, VeryLikely}, VeryLikely},
- // First considered selector is preserved.
- {{true, true}, {Neutral, VeryLikely}, Neutral},
- {{false, true}, {Neutral, VeryLikely}, Neutral},
- {{false, false}, {Neutral, VeryLikely}, Neutral},
- };
- for (const auto& test : kTests) {
- manager_->clear_permission_ui_selector_for_testing();
- for (size_t i = 0; i < test.enable_quiet_uis.size(); ++i) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- test.enable_quiet_uis[i]
- ? absl::optional<QuietUiReason>(QuietUiReason::kEnabledInPrefs)
- : absl::nullopt,
- false /* async */, test.prediction_likelihoods[i]);
- }
- MockPermissionRequest request(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- EXPECT_TRUE(prompt_factory_->RequestTypeSeen(request.request_type()));
- EXPECT_EQ(test.expected_prediction_likelihood,
- manager_->prediction_grant_likelihood_for_testing());
- Accept();
- EXPECT_TRUE(request.granted());
- }
- }
- TEST_P(PermissionRequestManagerTest, SelectorRequestTypes) {
- const struct {
- RequestType request_type;
- bool should_request_use_quiet_ui;
- } kTests[] = {
- {RequestType::kNotifications, true},
- {RequestType::kGeolocation, true},
- {RequestType::kCameraStream, false},
- };
- manager_->clear_permission_ui_selector_for_testing();
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_, QuietUiReason::kEnabledInPrefs, true);
- for (const auto& test : kTests) {
- MockPermissionRequest request(test.request_type,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
- WaitForBubbleToBeShown();
- EXPECT_EQ(test.should_request_use_quiet_ui,
- manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- }
- // Adding a mock PermissionUiSelector that handles Camera stream.
- MockCameraStreamPermissionUiSelector::CreateForManager(
- manager_, QuietUiReason::kEnabledInPrefs, true);
- // Now the RequestType::kCameraStream should show a quiet UI as well
- MockPermissionRequest request2(RequestType::kCameraStream,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request2);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(manager_->ShouldCurrentRequestUseQuietUI());
- Accept();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Quiet UI chip. Low priority for Notifications & Geolocation.
- ////////////////////////////////////////////////////////////////////////////////
- TEST_P(PermissionRequestManagerTest, NotificationsSingleBubbleAndChipRequest) {
- MockPermissionRequest request(RequestType::kNotifications,
- PermissionRequestGestureType::GESTURE);
- manager_->AddRequest(web_contents()->GetPrimaryMainFrame(), &request);
- WaitForBubbleToBeShown();
- EXPECT_TRUE(prompt_factory_->is_visible());
- ASSERT_EQ(prompt_factory_->request_count(), 1);
- Accept();
- EXPECT_TRUE(request.granted());
- EXPECT_EQ(prompt_factory_->show_count(), 1);
- }
- // Quiet UI feature is disabled. Chip is disabled. No low priority requests, the
- // first request is always shown.
- //
- // Permissions requested in order:
- // 1. Notification (non abusive)
- // 2. Geolocation
- // 3. Camera
- //
- // Prompt display order:
- // 1. Notification request shown
- // 2. Geolocation request shown
- // 3. Camera request shown
- TEST_P(PermissionRequestManagerTest,
- NotificationsGeolocationCameraBubbleRequest) {
- // permissions::features::kPermissionChip is enabled based on `GetParam()`.
- // That test is only for the default bubble.
- if (GetParam())
- return;
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 1);
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
- 1);
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/false, 1);
- for (auto* kRequest : {request_notifications.get(), request_geolocation.get(),
- request_camera.get()}) {
- WaitAndAcceptPromptForRequest(kRequest);
- }
- EXPECT_EQ(prompt_factory_->show_count(), 3);
- }
- // Quiet UI feature is disabled, no low priority requests, the last request is
- // always shown.
- //
- // Permissions requested in order:
- // 1. Notification (non abusive)
- // 2. Geolocation
- // 3. Camera
- //
- // Prompt display order:
- // 1. Notifications request shown but is preempted
- // 2. Geolocation request shown but is preempted
- // 3. Camera request shown
- // 4. Geolocation request shown again
- // 5. Notifications request shown again
- TEST_P(PermissionRequestManagerTest,
- NotificationsGeolocationCameraChipRequest) {
- // permissions::features::kPermissionChip is enabled based on `GetParam()`.
- // That test is only for the chip UI.
- if (!GetParam())
- return;
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 1);
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
- 2);
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 3);
- for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
- request_notifications.get()}) {
- WaitAndAcceptPromptForRequest(kRequest);
- }
- EXPECT_EQ(prompt_factory_->show_count(), 5);
- }
- // Quiet UI feature is disabled, no low priority requests, the last request is
- // always shown.
- //
- // Permissions requested in order:
- // 1. Camera
- // 2. Notification (non abusive)
- // 3. Geolocation
- //
- // Prompt display order:
- // 1. Camera request shown but is preempted
- // 2. Notifications request shown but is preempted
- // 3. Geolocation request shown
- // 4. Notifications request shown again
- // 5. Camera request shown again
- TEST_P(PermissionRequestManagerTest,
- CameraNotificationsGeolocationChipRequest) {
- // permissions::features::kPermissionChip is enabled based on `GetParam()`.
- // That test is only for the chip.
- if (!GetParam())
- return;
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 1);
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 2);
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
- 3);
- for (auto* kRequest : {request_geolocation.get(), request_notifications.get(),
- request_camera.get()}) {
- WaitAndAcceptPromptForRequest(kRequest);
- }
- EXPECT_EQ(prompt_factory_->show_count(), 5);
- }
- class PermissionRequestManagerTestQuietChip
- : public PermissionRequestManagerTest {
- public:
- PermissionRequestManagerTestQuietChip() {
- feature_list_.InitWithFeatureState(
- permissions::features::kPermissionQuietChip, true);
- }
- private:
- base::test::ScopedFeatureList feature_list_;
- };
- // Verifies that the quiet UI chip is not ignored if another request came in
- // less than 8.5 seconds after.
- // Permissions requested in order:
- // 1. Notification (abusive)
- // 2. After less than 8.5 seconds Geolocation
- //
- // Prompt display order:
- // 1. Notifications request shown but is preempted because of quiet UI.
- // 2. Geolocation request shown
- // 3. Notifications request shown again
- TEST_P(PermissionRequestManagerTestQuietChip,
- AbusiveNotificationsGeolocationQuietUIChipRequest) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
- false /* async */);
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 1);
- // Less then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(5000));
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
- 2);
- WaitAndAcceptPromptForRequest(request_geolocation.get());
- WaitAndAcceptPromptForRequest(request_notifications.get());
- EXPECT_EQ(prompt_factory_->show_count(), 3);
- }
- // Verifies that the quiet UI chip is ignored if another request came in more
- // than 8.5 seconds after.
- //
- // Permissions requested in order:
- // 1. Notification (abusive)
- // 2. After more than 8.5 seconds Geolocation
- //
- // Prompt display order:
- // 1. Notifications request shown but is preempted because of quiet UI.
- // 2. Geolocation request shown
- TEST_P(PermissionRequestManagerTestQuietChip,
- AbusiveNotificationsShownLongEnough) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
- false /* async */);
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 1);
- // More then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(9000));
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
- 2);
- // The second permission was requested after 8.5 second window, the quiet UI
- // Notifiations request for an abusive origin is automatically ignored.
- EXPECT_FALSE(request_notifications->granted());
- EXPECT_TRUE(request_notifications->finished());
- WaitAndAcceptPromptForRequest(request_geolocation.get());
- EXPECT_EQ(prompt_factory_->show_count(), 2);
- }
- // Verifies that the quiet UI chip is not ignored if another request came in
- // more than 8.5 seconds after. Verify different requests priority. Camera
- // request is shown despite being requested last.
- //
- // Permissions requested in order:
- // 1. Notification (abusive)
- // 2. After less than 8.5 seconds Geolocation
- // 3. Camera
- //
- // Prompt display order:
- // 1. Notifications request shown but is preempted because of quiet UI.
- // 2. Geolocation request shown but is preempted because of low priority.
- // 3. Camera request shown
- // 4. Geolocation request shown again
- // 5. Notifications quiet UI request shown again
- TEST_P(PermissionRequestManagerTestQuietChip,
- AbusiveNotificationsShownLongEnoughCamera) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
- false /* async */);
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/true,
- 1);
- // Less then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(5000));
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/true,
- 2);
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 3);
- // The second permission was requested in 8.5 second window, the quiet UI
- // Notifiations request for an abusive origin is not automatically ignored.
- EXPECT_FALSE(request_notifications->granted());
- EXPECT_FALSE(request_notifications->finished());
- for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
- request_notifications.get()}) {
- WaitAndAcceptPromptForRequest(kRequest);
- }
- EXPECT_EQ(prompt_factory_->show_count(), 5);
- }
- // Verifies that the quiet UI chip is not ignored if another request came in
- // more than 8.5 seconds after. Verify different requests priority. Camera
- // request is not preemted.
- //
- // Permissions requested in order:
- // 1. Camera
- // 2. Notification (abusive)
- // 3. After less than 8.5 seconds Geolocation
- //
- // Prompt display order:
- // 1. Camera request shown
- // 2. Geolocation request shown
- // 3. Camera request shown
- TEST_P(PermissionRequestManagerTestQuietChip,
- CameraAbusiveNotificationsGeolocation) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
- false /* async */);
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 1);
- // Quiet UI is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
- 1);
- // Less then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(5000));
- // Geolocation is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
- 1);
- // The second permission after quiet UI was requested in 8.5 second window,
- // the quiet UI Notifiations request for an abusive origin is not
- // automatically ignored.
- EXPECT_FALSE(request_notifications->granted());
- EXPECT_FALSE(request_notifications->finished());
- for (auto* kRequest : {request_camera.get(), request_geolocation.get(),
- request_notifications.get()}) {
- WaitAndAcceptPromptForRequest(kRequest);
- }
- EXPECT_EQ(prompt_factory_->show_count(), 3);
- }
- // Verifies that the quiet UI chip is not ignored if another request came in
- // more than 8.5 seconds after. Verify different requests priority. Camera
- // request is not preemted.
- //
- // Permissions requested in order:
- // 1. Camera
- // 2. Notification (abusive)
- // 3. After less than 8.5 seconds Geolocation
- // 4. MIDI
- //
- // Prompt display order:
- // 1. Camera request shown
- // 2. MIDI request shown (or MIDI and then Camera, the order depends on
- // `GetParam()`)
- // 3. Geolocation request shown
- // 4. Notifications request shown
- // If Chip is enabled MIDI will replace Camera, hence 5 prompts will be
- // shown. Otherwise 4.
- TEST_P(PermissionRequestManagerTestQuietChip,
- CameraAbusiveNotificationsGeolocationMIDI) {
- MockNotificationPermissionUiSelector::CreateForManager(
- manager_,
- PermissionUiSelector::QuietUiReason::kTriggeredDueToAbusiveRequests,
- false /* async */);
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 1);
- // Quiet UI is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
- 1);
- // Less then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(5000));
- // Geolocation is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
- 1);
- std::unique_ptr<MockPermissionRequest> request_midi;
- // If Chip is enabled, MIDI should be shown, otherwise MIDI should not be
- // shown.
- if (GetParam()) {
- request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
- /*should_be_seen=*/true, 2);
- } else {
- request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
- /*should_be_seen=*/false, 1);
- }
- // The second permission after quiet UI was requested in 8.5 second window,
- // the quiet UI Notifiations request for an abusive origin is not
- // automatically ignored.
- EXPECT_FALSE(request_notifications->granted());
- EXPECT_FALSE(request_notifications->finished());
- WaitAndAcceptPromptForRequest(GetParam() ? request_midi.get()
- : request_camera.get());
- WaitAndAcceptPromptForRequest(GetParam() ? request_camera.get()
- : request_midi.get());
- WaitAndAcceptPromptForRequest(request_geolocation.get());
- WaitAndAcceptPromptForRequest(request_notifications.get());
- EXPECT_EQ(prompt_factory_->show_count(), GetParam() ? 5 : 4);
- }
- // Verifies that non abusive chip behaves similar to others when Quiet UI Chip
- // is enabled.
- //
- // Permissions requested in order:
- // 1. Camera
- // 2. Notification (non abusive)
- // 3. After less than 8.5 seconds Geolocation
- // 4. MIDI
- //
- // Prompt display order:
- // 1. Camera request shown
- // 2. MIDI request shown (or MIDI and then Camera, the order depends on
- // `GetParam()`)
- // 3. Geolocation request shown
- // 4. Notifications request shown
- // If Chip is enabled MIDI will replace Camera, hence 5 prompts will be
- // shown. Otherwise 4.
- TEST_P(PermissionRequestManagerTestQuietChip,
- CameraNonAbusiveNotificationsGeolocationMIDI) {
- std::unique_ptr<MockPermissionRequest> request_camera = CreateAndAddRequest(
- RequestType::kCameraStream, /*should_be_seen=*/true, 1);
- // Quiet UI is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_notifications =
- CreateAndAddRequest(RequestType::kNotifications, /*should_be_seen=*/false,
- 1);
- // Less then 8.5 seconds.
- manager_->set_current_request_first_display_time_for_testing(
- base::Time::Now() - base::Milliseconds(5000));
- // Geolocation is not shown because Camera has higher priority.
- std::unique_ptr<MockPermissionRequest> request_geolocation =
- CreateAndAddRequest(RequestType::kGeolocation, /*should_be_seen=*/false,
- 1);
- std::unique_ptr<MockPermissionRequest> request_midi;
- // If Chip is enabled, MIDI should be shown, otherwise MIDI should not be
- // shown.
- if (GetParam()) {
- request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
- /*should_be_seen=*/true, 2);
- } else {
- request_midi = CreateAndAddRequest(RequestType::kMidiSysex,
- /*should_be_seen=*/false, 1);
- }
- // The second permission after quiet UI was requested in 8.5 second window,
- // the quiet UI Notifiations request for an abusive origin is not
- // automatically ignored.
- EXPECT_FALSE(request_notifications->granted());
- EXPECT_FALSE(request_notifications->finished());
- WaitAndAcceptPromptForRequest(GetParam() ? request_midi.get()
- : request_camera.get());
- WaitAndAcceptPromptForRequest(GetParam() ? request_camera.get()
- : request_midi.get());
- WaitAndAcceptPromptForRequest(request_geolocation.get());
- WaitAndAcceptPromptForRequest(request_notifications.get());
- EXPECT_EQ(prompt_factory_->show_count(), GetParam() ? 5 : 4);
- }
- INSTANTIATE_TEST_SUITE_P(All,
- PermissionRequestManagerTest,
- ::testing::Values(false, true));
- INSTANTIATE_TEST_SUITE_P(All,
- PermissionRequestManagerTestQuietChip,
- ::testing::Values(false, true));
- } // namespace permissions
|