blob: 465d1df9494db2268fda7314de037a4b81b1c6bb [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "build/build_config.h"
#include "chrome/browser/content_settings/page_specific_content_settings_delegate.h"
#include "chrome/browser/permissions/permission_manager_factory.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/permissions/features.h"
#include "components/permissions/permission_manager.h"
#include "components/permissions/permission_request_manager.h"
#include "components/permissions/test/mock_permission_prompt_factory.h"
#include "content/public/browser/permission_descriptor_util.h"
#include "content/public/browser/permission_request_description.h"
#include "content/public/browser/permission_result.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/android/search_permissions/search_permissions_service.h"
#include "components/location/android/location_settings_dialog_outcome.h"
#include "components/location/android/mock_location_settings.h"
#include "components/permissions/contexts/geolocation_permission_context_android.h"
#endif
#if BUILDFLAG(IS_ANDROID)
namespace {
constexpr char kDSETestUrl[] = "https://www.dsetest.com";
class TestSearchEngineDelegate
: public SearchPermissionsService::SearchEngineDelegate {
public:
std::u16string GetDSEName() override { return std::u16string(); }
url::Origin GetDSEOrigin() override {
return url::Origin::Create(GURL(kDSETestUrl));
}
};
} // namespace
#endif
class GeolocationPermissionContextDelegateTests
: public ChromeRenderViewHostTestHarness {
protected:
// ChromeRenderViewHostTestHarness:
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
permissions::PermissionRequestManager::CreateForWebContents(web_contents());
content_settings::PageSpecificContentSettings::CreateForWebContents(
web_contents(),
std::make_unique<PageSpecificContentSettingsDelegate>(web_contents()));
#if BUILDFLAG(IS_ANDROID)
static_cast<permissions::GeolocationPermissionContextAndroid*>(
PermissionManagerFactory::GetForProfile(profile())
->GetPermissionContextForTesting(ContentSettingsType::GEOLOCATION))
->SetLocationSettingsForTesting(
std::make_unique<MockLocationSettings>());
MockLocationSettings::SetLocationStatus(
/*has_android_coarse_location_permission=*/true,
/*has_android_fine_location_permission=*/true,
/*is_system_location_setting_enabled=*/true);
MockLocationSettings::SetCanPromptForAndroidPermission(true);
MockLocationSettings::SetLocationSettingsDialogStatus(false /* enabled */,
GRANTED);
MockLocationSettings::ClearHasShownLocationSettingsDialog();
#endif
}
void RequestPermissionFromCurrentDocument(
blink::PermissionType permission,
content::RenderFrameHost* render_frame_host,
bool user_gesture,
base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
PermissionManagerFactory::GetForProfile(profile())
->RequestPermissionsFromCurrentDocument(
render_frame_host,
content::PermissionRequestDescription(
content::PermissionDescriptorUtil::
CreatePermissionDescriptorForPermissionType(permission),
user_gesture),
base::BindOnce(
[](base::OnceCallback<void(blink::mojom::PermissionStatus)>
callback,
const std::vector<blink::mojom::PermissionStatus>& state) {
DCHECK_EQ(state.size(), 1U);
std::move(callback).Run(state[0]);
},
std::move(callback)));
}
content::PermissionResult GetPermissionResultForOriginWithoutContext(
Profile* profile,
blink::PermissionType permission,
const url::Origin& origin) {
return PermissionManagerFactory::GetForProfile(profile)
->GetPermissionResultForOriginWithoutContext(
content::PermissionDescriptorUtil::
CreatePermissionDescriptorForPermissionType(permission),
origin, origin);
}
};
TEST_F(GeolocationPermissionContextDelegateTests, TabContentSettingIsUpdated) {
GURL requesting_frame_url("https://www.example.com/geolocation");
auto* manager =
permissions::PermissionRequestManager::FromWebContents(web_contents());
permissions::MockPermissionPromptFactory mock_prompt_factory(manager);
NavigateAndCommit(requesting_frame_url);
manager->DocumentOnLoadCompletedInPrimaryMainFrame();
base::RunLoop run_loop;
RequestPermissionFromCurrentDocument(
blink::PermissionType::GEOLOCATION, main_rfh(), true,
base::BindOnce(
[](base::RunLoop* run_loop, blink::mojom::PermissionStatus status) {
EXPECT_EQ(status, blink::mojom::PermissionStatus::GRANTED);
run_loop->Quit();
},
&run_loop));
task_environment()->RunUntilIdle();
ASSERT_TRUE(manager->IsRequestInProgress());
manager->Accept();
run_loop.Run();
content_settings::PageSpecificContentSettings* content_settings =
content_settings::PageSpecificContentSettings::GetForFrame(
web_contents()->GetPrimaryMainFrame());
EXPECT_TRUE(
content_settings->IsContentAllowed(ContentSettingsType::GEOLOCATION));
}
#if BUILDFLAG(IS_ANDROID)
// TODO(crbug.com/40835241): Flaky.
TEST_F(GeolocationPermissionContextDelegateTests,
DISABLED_SearchGeolocationInIncognito) {
url::Origin requesting_frame_url = url::Origin::Create(GURL(kDSETestUrl));
SearchPermissionsService* service =
SearchPermissionsService::Factory::GetForBrowserContext(profile());
std::unique_ptr<TestSearchEngineDelegate> delegate =
std::make_unique<TestSearchEngineDelegate>();
service->SetSearchEngineDelegateForTest(std::move(delegate));
service->InitializeSettingsIfNeeded();
// The DSE geolocation should not be auto-granted even in a non-OTR profile.
ASSERT_EQ(
blink::mojom::PermissionStatus::ASK,
GetPermissionResultForOriginWithoutContext(
profile(), blink::PermissionType::GEOLOCATION, requesting_frame_url)
.status);
Profile* otr_profile =
profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true);
// The DSE geolocation should not be auto-granted in an OTR profile.
ASSERT_EQ(
blink::mojom::PermissionStatus::ASK,
GetPermissionResultForOriginWithoutContext(
otr_profile, blink::PermissionType::GEOLOCATION, requesting_frame_url)
.status);
}
#endif