#include "content/public/browser/render_process_host.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/scoped_observation.h"
#include "base/strings/string_split.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/bind_post_task.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/test_timeouts.h"
#include "base/threading/hang_watcher.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_process_host_internal_observer.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host_creation_observer.h"
#include "content/public/browser/render_process_host_observer.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/pseudonymization_util.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/browsing_data_remover_test_util.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_content_browser_client.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_service.mojom.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_browser_main_parts.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "content/test/storage_partition_test_helpers.h"
#include "media/base/media_switches.h"
#include "media/base/test_data_util.h"
#include "media/mojo/buildflags.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_status_code.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "third_party/blink/public/common/features.h"
#if BUILDFLAG(IS_WIN)
#include "base/features.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "mojo/public/cpp/platform/platform_handle_security_util_win.h"
#include "sandbox/policy/switches.h"
#endif
_;
InSequence;
Mock;
StrictMock;
Test;
namespace content {
namespace {
class DelayedHttpResponseWithResolver final
: public net::test_server::BasicHttpResponse { … };
std::unique_ptr<net::test_server::HttpResponse> HandleBeacon(
const net::test_server::HttpRequest& request) { … }
std::unique_ptr<net::test_server::HttpResponse> HandleHungBeacon(
const base::RepeatingClosure& on_called,
const net::test_server::HttpRequest& request) { … }
std::unique_ptr<net::test_server::HttpResponse> HandleHungBeaconWithResolver(
scoped_refptr<DelayedHttpResponseWithResolver::Resolver> resolver,
const net::test_server::HttpRequest& request) { … }
}
class RenderProcessHostTestBase : public ContentBrowserTest,
public RenderProcessHostObserver { … };
class KeepAliveHandleContentBrowserClient
: public ContentBrowserTestContentBrowserClient { … };
class RenderProcessHostTest : public RenderProcessHostTestBase,
public ::testing::WithParamInterface<bool> { … };
INSTANTIATE_TEST_SUITE_P(
All,
RenderProcessHostTest,
testing::Values(false, true),
[](const testing::TestParamInfo<RenderProcessHostTest::ParamType>& info) { … };
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, GuestsAreNotSuitableHosts) { … }
class ShellCloser : public RenderProcessHostObserver { … };
class ObserverLogger : public RenderProcessHostObserver { … };
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls …
#else
#define MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls …
#endif
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
MAYBE_AllProcessExitedCallsBeforeAnyHostDestroyedCalls) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, KillProcessOnBadMojoMessage) { … }
class AudioStartObserver : public WebContentsObserver { … };
#if BUILDFLAG(ENABLE_MOJO_RENDERER) || BUILDFLAG(IS_ANDROID)
#define KillProcessZerosAudioStreams …
#endif
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, KillProcessZerosAudioStreams) { … }
class CaptureStreamRenderProcessHostTest : public RenderProcessHostTestBase { … };
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
GetUserMediaIncrementsVideoCaptureStreams) { … }
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
StopResetsVideoCaptureStreams) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_KillProcessZerosVideoCaptureStreams …
#else
#define MAYBE_KillProcessZerosVideoCaptureStreams …
#endif
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
MAYBE_KillProcessZerosVideoCaptureStreams) { … }
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
GetUserMediaAudioOnlyIncrementsMediaStreams) { … }
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_KillProcessZerosVideoCaptureStreams …
#else
#define MAYBE_KillProcessZerosVideoCaptureStreams …
#endif
IN_PROC_BROWSER_TEST_F(CaptureStreamRenderProcessHostTest,
KillProcessZerosAudioCaptureStreams) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, KeepAliveRendererProcess) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
DISABLED_KeepAliveRendererProcessWithServiceWorker) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
#define MAYBE_KeepAliveRendererProcess_Hung …
#else
#define MAYBE_KeepAliveRendererProcess_Hung …
#endif
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
MAYBE_KeepAliveRendererProcess_Hung) { … }
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_WIN)
#define MAYBE_FetchKeepAliveRendererProcess_Hung …
#else
#define MAYBE_FetchKeepAliveRendererProcess_Hung …
#endif
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
MAYBE_FetchKeepAliveRendererProcess_Hung) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ManyKeepaliveRequests) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, TooManyKeepaliveRequests) { … }
class IsProcessBackgroundedObserver : public RenderProcessHostInternalObserver { … };
#if !BUILDFLAG(IS_ANDROID)
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, PriorityOverride) { … }
#endif
struct BoostRenderProcessForLoadingBrowserTestParam { … };
class BoostRenderProcessForLoadingBrowserTest
: public RenderProcessHostTestBase,
public content::WebContentsObserver,
public ::testing::WithParamInterface<
BoostRenderProcessForLoadingBrowserTestParam> { … };
const BoostRenderProcessForLoadingBrowserTestParam
kBoostRenderProcessForLoadingBrowserTestParams[] = …;
INSTANTIATE_TEST_SUITE_P(…);
IN_PROC_BROWSER_TEST_P(BoostRenderProcessForLoadingBrowserTest,
VerifyRenderProcessBackgrounded) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ConstructedButNotInitializedYet) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, FastShutdownForStartingProcess) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
FastShutdownWithKeepAliveRequest) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ForEachRenderFrameHost) { … }
namespace {
class LeakCleanupObserver : public WebContentsObserver { … };
class FastShutdownExitObserver : public RenderProcessHostObserver { … };
}
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, AllowUnusedProcessToExit) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
AllowUnusedProcessToExitAfterCrash) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, HandleNestedFrameDeletion) { … }
namespace {
class RenderFrameDeletionObserver : public WebContentsObserver { … };
}
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ForEachFrameNestedFrameDeletion) { … }
#if BUILDFLAG(IS_WIN)
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ZeroExecutionTimes) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
sandbox::policy::switches::kNoSandbox)) {
return;
}
base::HistogramTester histogram_tester;
RenderProcessHost* process = RenderProcessHostImpl::CreateRenderProcessHost(
ShellContentBrowserClient::Get()->browser_context(), nullptr);
RenderProcessHostWatcher process_watcher(
process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_READY);
process->Init();
process_watcher.Wait();
EXPECT_TRUE(process->IsReady());
histogram_tester.ExpectUniqueSample(
"BrowserRenderProcessHost.SuspendedChild.UserExecutionRecorded", false,
1);
histogram_tester.ExpectUniqueSample(
"BrowserRenderProcessHost.SuspendedChild.KernelExecutionRecorded", false,
1);
process->Cleanup();
}
class RenderProcessHostWriteableFileTest
: public RenderProcessHostTestBase,
public ::testing::WithParamInterface<
std::tuple<bool,
bool>> {
public:
void SetUp() override {
enforcement_feature_.InitWithFeatureState(
base::features::kEnforceNoExecutableFileHandles,
IsEnforcementEnabled());
RenderProcessHostTestBase::SetUp();
}
protected:
bool IsEnforcementEnabled() { return std::get<0>(GetParam()); }
bool ShouldMarkNoExecute() { return std::get<1>(GetParam()); }
private:
base::test::ScopedFeatureList enforcement_feature_;
};
IN_PROC_BROWSER_TEST_P(RenderProcessHostWriteableFileTest,
PassUnsafeWriteableExecutableFile) {
#if !DCHECK_IS_ON()
GTEST_SKIP();
#else
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
sandbox::policy::switches::kNoSandbox)) {
GTEST_SKIP();
}
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(embedded_test_server()->Start());
GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
EXPECT_TRUE(NavigateToURL(shell(), test_url));
RenderProcessHost* rph =
shell()->web_contents()->GetPrimaryMainFrame()->GetProcess();
mojo::Remote<mojom::TestService> test_service;
rph->BindReceiver(test_service.BindNewPipeAndPassReceiver());
uint32_t flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
base::File::FLAG_WRITE;
if (ShouldMarkNoExecute()) {
flags = base::File::AddFlagsForPassingToUntrustedProcess(flags);
}
base::FilePath file_path;
base::CreateTemporaryFile(&file_path);
base::File temp_file_writeable(file_path, flags);
ASSERT_TRUE(temp_file_writeable.IsValid());
bool error_was_called = false;
mojo::SetUnsafeFileHandleCallbackForTesting(
base::BindLambdaForTesting([&error_was_called]() -> bool {
error_was_called = true;
return true;
}));
base::RunLoop run_loop;
test_service->PassWriteableFile(std::move(temp_file_writeable),
run_loop.QuitClosure());
run_loop.Run();
bool should_violation_occur =
IsEnforcementEnabled() && !ShouldMarkNoExecute();
EXPECT_EQ(should_violation_occur, error_was_called);
#endif
}
INSTANTIATE_TEST_SUITE_P(
All,
RenderProcessHostWriteableFileTest,
testing::Combine(testing::Bool(),
testing::Bool()));
#endif
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
SetPseudonymizationSaltSynchronized) { … }
class CreationObserver : public RenderProcessHostCreationObserver { … };
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, HostCreationObserved) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
HostCreationObserversAddedDuringNotification) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest,
HostCreationObserversDestroyedDuringNotification) { … }
namespace {
bool FetchScript(Shell* shell, GURL url) { … }
}
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ClearResourceCache) { … }
IN_PROC_BROWSER_TEST_P(RenderProcessHostTest, ReuseSiteURLChanges) { … }
#if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
class FakeStableVideoDecoderFactoryService
: public media::stable::mojom::StableVideoDecoderFactory { … };
class RenderProcessHostTestStableVideoDecoderTest
: public RenderProcessHostTestBase { … };
IN_PROC_BROWSER_TEST_F(RenderProcessHostTestStableVideoDecoderTest,
FactoryIsResetAfterDelay) { … }
IN_PROC_BROWSER_TEST_F(RenderProcessHostTestStableVideoDecoderTest,
FactoryResetTimerIsStoppedOnRequestBeforeResetDelay) { … }
#endif
}