blob: 0ac6afd1308488532949ca268cc97fe69ebf6d90 [file] [log] [blame]
// Copyright 2020 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 "content/shell/browser/web_test/web_test_client_impl.h"
#include <memory>
#include <string>
#include <utility>
#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/content_index_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "content/shell/browser/web_test/blink_test_controller.h"
#include "content/shell/browser/web_test/web_test_browser_context.h"
#include "content/shell/browser/web_test/web_test_content_browser_client.h"
#include "content/shell/browser/web_test/web_test_content_index_provider.h"
#include "content/shell/browser/web_test/web_test_permission_manager.h"
#include "content/shell/common/web_test/web_test_constants.h"
#include "content/test/mock_platform_notification_service.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "storage/browser/database/database_tracker.h"
#include "storage/browser/file_system/isolated_context.h"
#include "storage/browser/quota/quota_manager.h"
namespace content {
namespace {
MockPlatformNotificationService* GetMockPlatformNotificationService() {
auto* client = WebTestContentBrowserClient::Get();
auto* context = client->GetWebTestBrowserContext();
auto* service = client->GetPlatformNotificationService(context);
return static_cast<MockPlatformNotificationService*>(service);
}
WebTestContentIndexProvider* GetWebTestContentIndexProvider() {
auto* client = WebTestContentBrowserClient::Get();
auto* context = client->GetWebTestBrowserContext();
return static_cast<WebTestContentIndexProvider*>(
context->GetContentIndexProvider());
}
ContentIndexContext* GetContentIndexContext(const url::Origin& origin) {
auto* client = WebTestContentBrowserClient::Get();
auto* context = client->GetWebTestBrowserContext();
auto* storage_partition = BrowserContext::GetStoragePartitionForSite(
context, origin.GetURL(), /* can_create= */ false);
return storage_partition->GetContentIndexContext();
}
void SetDatabaseQuotaOnIOThread(
scoped_refptr<storage::QuotaManager> quota_manager,
int32_t quota) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(quota >= 0 || quota == kDefaultDatabaseQuota);
if (quota == kDefaultDatabaseQuota) {
// Reset quota to settings with a zero refresh interval to force
// QuotaManager to refresh settings immediately.
storage::QuotaSettings default_settings;
default_settings.refresh_interval = base::TimeDelta();
quota_manager->SetQuotaSettings(default_settings);
} else {
quota_manager->SetQuotaSettings(storage::GetHardCodedSettings(quota));
}
}
} // namespace
// static
void WebTestClientImpl::Create(
int render_process_id,
storage::QuotaManager* quota_manager,
storage::DatabaseTracker* database_tracker,
network::mojom::NetworkContext* network_context,
mojo::PendingAssociatedReceiver<mojom::WebTestClient> receiver) {
mojo::MakeSelfOwnedAssociatedReceiver(
std::make_unique<WebTestClientImpl>(render_process_id, quota_manager,
database_tracker, network_context),
std::move(receiver));
}
WebTestClientImpl::WebTestClientImpl(
int render_process_id,
storage::QuotaManager* quota_manager,
storage::DatabaseTracker* database_tracker,
network::mojom::NetworkContext* network_context)
: render_process_id_(render_process_id),
quota_manager_(quota_manager),
database_tracker_(database_tracker) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
network_context->GetCookieManager(
cookie_manager_.BindNewPipeAndPassReceiver());
}
WebTestClientImpl::~WebTestClientImpl() = default;
void WebTestClientImpl::InspectSecondaryWindow() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (BlinkTestController::Get())
BlinkTestController::Get()->OnInspectSecondaryWindow();
}
void WebTestClientImpl::TestFinishedInSecondaryRenderer() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (BlinkTestController::Get())
BlinkTestController::Get()->OnTestFinishedInSecondaryRenderer();
}
void WebTestClientImpl::SimulateWebNotificationClick(
const std::string& title,
int32_t action_index,
const base::Optional<base::string16>& reply) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
GetMockPlatformNotificationService()->SimulateClick(
title,
action_index == std::numeric_limits<int32_t>::min()
? base::Optional<int>()
: base::Optional<int>(action_index),
reply);
}
void WebTestClientImpl::SimulateWebNotificationClose(const std::string& title,
bool by_user) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
GetMockPlatformNotificationService()->SimulateClose(title, by_user);
}
void WebTestClientImpl::SimulateWebContentIndexDelete(const std::string& id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto* provider = GetWebTestContentIndexProvider();
std::pair<int64_t, url::Origin> registration_data =
provider->GetRegistrationDataFromId(id);
auto* context = GetContentIndexContext(registration_data.second);
context->OnUserDeletedItem(registration_data.first, registration_data.second,
id);
}
void WebTestClientImpl::BlockThirdPartyCookies(bool block) {
BlinkTestController::Get()->BlockThirdPartyCookies(block);
}
void WebTestClientImpl::ResetPermissions() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
WebTestContentBrowserClient::Get()
->GetWebTestBrowserContext()
->GetWebTestPermissionManager()
->ResetPermissions();
}
void WebTestClientImpl::SetPermission(const std::string& name,
blink::mojom::PermissionStatus status,
const GURL& origin,
const GURL& embedding_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
content::PermissionType type;
if (name == "midi") {
type = PermissionType::MIDI;
} else if (name == "midi-sysex") {
type = PermissionType::MIDI_SYSEX;
} else if (name == "push-messaging" || name == "notifications") {
type = PermissionType::NOTIFICATIONS;
} else if (name == "geolocation") {
type = PermissionType::GEOLOCATION;
} else if (name == "protected-media-identifier") {
type = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
} else if (name == "background-sync") {
type = PermissionType::BACKGROUND_SYNC;
} else if (name == "accessibility-events") {
type = PermissionType::ACCESSIBILITY_EVENTS;
} else if (name == "clipboard-read-write") {
type = PermissionType::CLIPBOARD_READ_WRITE;
} else if (name == "clipboard-sanitized-write") {
type = PermissionType::CLIPBOARD_SANITIZED_WRITE;
} else if (name == "payment-handler") {
type = PermissionType::PAYMENT_HANDLER;
} else if (name == "accelerometer" || name == "gyroscope" ||
name == "magnetometer" || name == "ambient-light-sensor") {
type = PermissionType::SENSORS;
} else if (name == "background-fetch") {
type = PermissionType::BACKGROUND_FETCH;
} else if (name == "periodic-background-sync") {
type = PermissionType::PERIODIC_BACKGROUND_SYNC;
} else if (name == "wake-lock-screen") {
type = PermissionType::WAKE_LOCK_SCREEN;
} else if (name == "wake-lock-system") {
type = PermissionType::WAKE_LOCK_SYSTEM;
} else if (name == "nfc") {
type = PermissionType::NFC;
} else if (name == "storage-access") {
type = PermissionType::STORAGE_ACCESS_GRANT;
} else {
NOTREACHED();
type = PermissionType::NOTIFICATIONS;
}
WebTestContentBrowserClient::Get()
->GetWebTestBrowserContext()
->GetWebTestPermissionManager()
->SetPermission(type, status, origin, embedding_origin);
}
void WebTestClientImpl::WebTestRuntimeFlagsChanged(
base::Value changed_web_test_runtime_flags) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!BlinkTestController::Get())
return;
base::DictionaryValue* changed_web_test_runtime_flags_dictionary = nullptr;
bool ok = changed_web_test_runtime_flags.GetAsDictionary(
&changed_web_test_runtime_flags_dictionary);
DCHECK(ok);
BlinkTestController::Get()->OnWebTestRuntimeFlagsChanged(
render_process_id_, *changed_web_test_runtime_flags_dictionary);
}
void WebTestClientImpl::DeleteAllCookies() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
cookie_manager_->DeleteCookies(network::mojom::CookieDeletionFilter::New(),
base::BindOnce([](uint32_t) {}));
}
void WebTestClientImpl::GetWritableDirectory(
GetWritableDirectoryCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::FilePath path;
if (BlinkTestController::Get())
path = BlinkTestController::Get()->GetWritableDirectoryForTests();
std::move(callback).Run(path);
}
void WebTestClientImpl::RegisterIsolatedFileSystem(
const std::vector<base::FilePath>& absolute_filenames,
RegisterIsolatedFileSystemCallback callback) {
storage::IsolatedContext::FileInfoSet files;
std::string filesystem_id;
ChildProcessSecurityPolicy* policy =
ChildProcessSecurityPolicy::GetInstance();
for (auto& filename : absolute_filenames) {
files.AddPath(filename, nullptr);
if (!policy->CanReadFile(render_process_id_, filename))
policy->GrantReadFile(render_process_id_, filename);
}
filesystem_id =
storage::IsolatedContext::GetInstance()->RegisterDraggedFileSystem(files);
policy->GrantReadFileSystem(render_process_id_, filesystem_id);
std::move(callback).Run(filesystem_id);
}
void WebTestClientImpl::SetFilePathForMockFileDialog(
const base::FilePath& path) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (BlinkTestController::Get())
BlinkTestController::Get()->SetFilePathForMockFileDialog(path);
}
void WebTestClientImpl::ClearAllDatabases() {
database_tracker_->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
[](scoped_refptr<storage::DatabaseTracker> db_tracker) {
DCHECK(db_tracker->task_runner()->RunsTasksInCurrentSequence());
db_tracker->DeleteDataModifiedSince(base::Time(),
net::CompletionOnceCallback());
},
database_tracker_));
}
void WebTestClientImpl::SetDatabaseQuota(int32_t quota) {
base::PostTask(
FROM_HERE, {content::BrowserThread::IO},
base::BindOnce(&SetDatabaseQuotaOnIOThread, quota_manager_, quota));
}
void WebTestClientImpl::InitiateCaptureDump(bool capture_navigation_history,
bool capture_pixels) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (BlinkTestController::Get()) {
BlinkTestController::Get()->OnInitiateCaptureDump(
capture_navigation_history, capture_pixels);
}
}
} // namespace content