blob: 31d87fa18cdfaf8cdb6b7a5624ecd759a732acc3 [file] [log] [blame]
// Copyright 2019 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 "chrome/browser/nfc/nfc_permission_context.h"
#include "build/build_config.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/permissions/permission_manager.h"
#include "components/permissions/permission_request_id.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/test/mock_permission_prompt_factory.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_utils.h"
#if defined(OS_ANDROID)
#include "chrome/browser/nfc/android/mock_nfc_system_level_setting.h"
#include "chrome/browser/nfc/nfc_permission_context_android.h"
#endif
using content::MockRenderProcessHost;
// NfcPermissionContextTests ------------------------------------------
class NfcPermissionContextTests : public ChromeRenderViewHostTestHarness {
protected:
// ChromeRenderViewHostTestHarness:
void SetUp() override;
void TearDown() override;
permissions::PermissionRequestID RequestID(int request_id);
void RequestNfcPermission(content::WebContents* web_contents,
const permissions::PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture);
void PermissionResponse(const permissions::PermissionRequestID& id,
ContentSetting content_setting);
void CheckPermissionMessageSent(int request_id, bool allowed);
void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
int request_id,
bool allowed);
void SetupRequestManager(content::WebContents* web_contents);
void RequestManagerDocumentLoadCompleted();
void RequestManagerDocumentLoadCompleted(content::WebContents* web_contents);
ContentSetting GetNfcContentSetting(GURL frame_0, GURL frame_1);
void SetNfcContentSetting(GURL frame_0,
GURL frame_1,
ContentSetting content_setting);
bool HasActivePrompt();
bool HasActivePrompt(content::WebContents* web_contents);
void AcceptPrompt();
void AcceptPrompt(content::WebContents* web_contents);
void DenyPrompt();
void ClosePrompt();
// owned by the browser context
NfcPermissionContext* nfc_permission_context_;
std::vector<std::unique_ptr<permissions::MockPermissionPromptFactory>>
mock_permission_prompt_factories_;
// A map between renderer child id and a pair represending the bridge id and
// whether the requested permission was allowed.
std::map<int, std::pair<int, bool>> responses_;
};
permissions::PermissionRequestID NfcPermissionContextTests::RequestID(
int request_id) {
return permissions::PermissionRequestID(
web_contents()->GetMainFrame()->GetProcess()->GetID(),
web_contents()->GetMainFrame()->GetRoutingID(), request_id);
}
void NfcPermissionContextTests::RequestNfcPermission(
content::WebContents* web_contents,
const permissions::PermissionRequestID& id,
const GURL& requesting_frame,
bool user_gesture) {
nfc_permission_context_->RequestPermission(
web_contents, id, requesting_frame, user_gesture,
base::Bind(&NfcPermissionContextTests::PermissionResponse,
base::Unretained(this), id));
content::RunAllTasksUntilIdle();
}
void NfcPermissionContextTests::PermissionResponse(
const permissions::PermissionRequestID& id,
ContentSetting content_setting) {
responses_[id.render_process_id()] =
std::make_pair(id.request_id(), content_setting == CONTENT_SETTING_ALLOW);
}
void NfcPermissionContextTests::CheckPermissionMessageSent(int request_id,
bool allowed) {
CheckPermissionMessageSentInternal(process(), request_id, allowed);
}
void NfcPermissionContextTests::CheckPermissionMessageSentInternal(
MockRenderProcessHost* process,
int request_id,
bool allowed) {
ASSERT_EQ(responses_.count(process->GetID()), 1U);
EXPECT_EQ(request_id, responses_[process->GetID()].first);
EXPECT_EQ(allowed, responses_[process->GetID()].second);
responses_.erase(process->GetID());
}
void NfcPermissionContextTests::SetUp() {
ChromeRenderViewHostTestHarness::SetUp();
TabSpecificContentSettings::CreateForWebContents(web_contents());
nfc_permission_context_ = static_cast<NfcPermissionContext*>(
PermissionManagerFactory::GetForProfile(profile())
->GetPermissionContextForTesting(ContentSettingsType::NFC));
SetupRequestManager(web_contents());
#if defined(OS_ANDROID)
static_cast<NfcPermissionContextAndroid*>(nfc_permission_context_)
->set_nfc_system_level_setting_for_testing(
std::unique_ptr<NfcSystemLevelSetting>(
new MockNfcSystemLevelSetting()));
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(true);
MockNfcSystemLevelSetting::SetNfcAccessIsPossible(true);
MockNfcSystemLevelSetting::ClearHasShownNfcSettingPrompt();
#endif
}
void NfcPermissionContextTests::TearDown() {
mock_permission_prompt_factories_.clear();
ChromeRenderViewHostTestHarness::TearDown();
}
void NfcPermissionContextTests::SetupRequestManager(
content::WebContents* web_contents) {
// Create PermissionRequestManager.
permissions::PermissionRequestManager::CreateForWebContents(web_contents);
permissions::PermissionRequestManager* permission_request_manager =
permissions::PermissionRequestManager::FromWebContents(web_contents);
// Create a MockPermissionPromptFactory for the PermissionRequestManager.
mock_permission_prompt_factories_.push_back(
std::make_unique<permissions::MockPermissionPromptFactory>(
permission_request_manager));
}
void NfcPermissionContextTests::RequestManagerDocumentLoadCompleted() {
NfcPermissionContextTests::RequestManagerDocumentLoadCompleted(
web_contents());
}
void NfcPermissionContextTests::RequestManagerDocumentLoadCompleted(
content::WebContents* web_contents) {
permissions::PermissionRequestManager::FromWebContents(web_contents)
->DocumentOnLoadCompletedInMainFrame();
}
ContentSetting NfcPermissionContextTests::GetNfcContentSetting(GURL frame_0,
GURL frame_1) {
return HostContentSettingsMapFactory::GetForProfile(profile())
->GetContentSetting(frame_0, frame_1, ContentSettingsType::NFC,
std::string());
}
void NfcPermissionContextTests::SetNfcContentSetting(
GURL frame_0,
GURL frame_1,
ContentSetting content_setting) {
return HostContentSettingsMapFactory::GetForProfile(profile())
->SetContentSettingDefaultScope(frame_0, frame_1,
ContentSettingsType::NFC, std::string(),
content_setting);
}
bool NfcPermissionContextTests::HasActivePrompt() {
return HasActivePrompt(web_contents());
}
bool NfcPermissionContextTests::HasActivePrompt(
content::WebContents* web_contents) {
permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents);
return manager->IsRequestInProgress();
}
void NfcPermissionContextTests::AcceptPrompt() {
return AcceptPrompt(web_contents());
base::RunLoop().RunUntilIdle();
}
void NfcPermissionContextTests::AcceptPrompt(
content::WebContents* web_contents) {
permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents);
manager->Accept();
base::RunLoop().RunUntilIdle();
}
void NfcPermissionContextTests::DenyPrompt() {
permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents());
manager->Deny();
base::RunLoop().RunUntilIdle();
}
void NfcPermissionContextTests::ClosePrompt() {
permissions::PermissionRequestManager* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents());
manager->Closing();
base::RunLoop().RunUntilIdle();
}
// Tests ----------------------------------------------------------------------
TEST_F(NfcPermissionContextTests, SinglePermissionPrompt) {
GURL requesting_frame("https://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame,
true /* user_gesture */);
#if defined(OS_ANDROID)
ASSERT_TRUE(HasActivePrompt());
#else
ASSERT_FALSE(HasActivePrompt());
#endif
}
TEST_F(NfcPermissionContextTests, SinglePermissionPromptFailsOnInsecureOrigin) {
GURL requesting_frame("http://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_FALSE(HasActivePrompt());
}
#if defined(OS_ANDROID)
// Tests concerning Android NFC setting
TEST_F(NfcPermissionContextTests,
SystemNfcSettingDisabledWhenNfcPermissionGetsGranted) {
GURL requesting_frame("https://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_TRUE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
AcceptPrompt();
ASSERT_TRUE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingDisabledWhenNfcPermissionGetsDenied) {
GURL requesting_frame("https://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_TRUE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
DenyPrompt();
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
CheckPermissionMessageSent(0 /* request _id */, false /* allowed */);
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingDisabledWhenNfcPermissionAlreadyGranted) {
GURL requesting_frame("https://www.example.com/nfc");
SetNfcContentSetting(requesting_frame, requesting_frame,
CONTENT_SETTING_ALLOW);
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_FALSE(HasActivePrompt());
ASSERT_TRUE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingEnabledWhenNfcPermissionAlreadyGranted) {
GURL requesting_frame("https://www.example.com/nfc");
SetNfcContentSetting(requesting_frame, requesting_frame,
CONTENT_SETTING_ALLOW);
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_FALSE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingCantBeEnabledWhenNfcPermissionGetsGranted) {
GURL requesting_frame("https://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_TRUE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
AcceptPrompt();
ASSERT_FALSE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingCantBeEnabledWhenNfcPermissionGetsDenied) {
GURL requesting_frame("https://www.example.com/nfc");
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_TRUE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
DenyPrompt();
ASSERT_FALSE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
CheckPermissionMessageSent(0 /* request _id */, false /* allowed */);
}
TEST_F(NfcPermissionContextTests,
SystemNfcSettingCantBeEnabledWhenNfcPermissionAlreadyGranted) {
GURL requesting_frame("https://www.example.com/nfc");
SetNfcContentSetting(requesting_frame, requesting_frame,
CONTENT_SETTING_ALLOW);
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
MockNfcSystemLevelSetting::SetNfcSystemLevelSettingEnabled(false);
MockNfcSystemLevelSetting::SetNfcAccessIsPossible(false);
EXPECT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_FALSE(HasActivePrompt());
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
CheckPermissionMessageSent(0 /* request _id */, true /* allowed */);
}
TEST_F(NfcPermissionContextTests, CancelNfcPermissionRequest) {
GURL requesting_frame("https://www.example.com/nfc");
EXPECT_EQ(CONTENT_SETTING_ASK,
GetNfcContentSetting(requesting_frame, requesting_frame));
NavigateAndCommit(requesting_frame);
RequestManagerDocumentLoadCompleted();
ASSERT_FALSE(HasActivePrompt());
RequestNfcPermission(web_contents(), RequestID(0), requesting_frame, true);
ASSERT_TRUE(HasActivePrompt());
// Simulate the frame going away; the request should be removed.
ClosePrompt();
ASSERT_FALSE(MockNfcSystemLevelSetting::HasShownNfcSettingPrompt());
// Ensure permission isn't persisted.
EXPECT_EQ(CONTENT_SETTING_ASK,
GetNfcContentSetting(requesting_frame, requesting_frame));
}
#endif