#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/public/browser/service_process_host.h"
#include <string.h>
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "services/test/echo/public/mojom/echo.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "content/public/browser/service_process_host_passkeys.h"
#endif
namespace content {
#if BUILDFLAG(IS_WIN)
using LoadStatus = echo::mojom::EchoService::LoadStatus;
namespace {
constexpr const wchar_t* kEchoPreloadLibrary = L"echo_preload_library";
base::FilePath GetDllPath(std::wstring mod_name) {
mod_name.append(L".dll");
auto exe_dir = base::PathService::CheckedGet(base::BasePathKey::DIR_EXE);
return exe_dir.Append(mod_name);
}
}
#endif
constexpr char kTestUrl[] = …;
ServiceProcessHostBrowserTest;
class EchoServiceProcessObserver : public ServiceProcessHost::Observer { … };
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, Launch) { … }
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, LocalDisconnectQuits) { … }
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, RemoteDisconnectQuits) { … }
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, AllMessagesReceived) { … }
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, ObserveCrash) { … }
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, IdleTimeout) { … }
#if BUILDFLAG(IS_WIN)
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, PreloadLibraryNotSet) {
EchoServiceProcessObserver observer;
auto echo_service = ServiceProcessHost::Launch<echo::mojom::EchoService>(
ServiceProcessHost::Options().Pass());
observer.WaitForLaunch();
base::RunLoop loop;
echo_service->LoadNativeLibrary(
GetDllPath(kEchoPreloadLibrary), false,
base::BindLambdaForTesting([&](LoadStatus status, uint32_t result) {
EXPECT_EQ(LoadStatus::kFailedLoadLibrary, status);
EXPECT_EQ(DWORD{ERROR_ACCESS_DENIED}, result);
loop.Quit();
}));
loop.Run();
}
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, PreloadLibraryPreloaded) {
std::vector<base::FilePath> preloads;
preloads.push_back(GetDllPath(kEchoPreloadLibrary));
EchoServiceProcessObserver observer;
auto echo_service = ServiceProcessHost::Launch<echo::mojom::EchoService>(
ServiceProcessHost::Options()
.WithPreloadedLibraries(
preloads, ServiceProcessHostPreloadLibraries::GetPassKey())
.Pass());
observer.WaitForLaunch();
base::RunLoop loop;
echo_service->LoadNativeLibrary(
GetDllPath(kEchoPreloadLibrary),
true,
base::BindLambdaForTesting([&](LoadStatus status, uint32_t result) {
EXPECT_EQ(LoadStatus::kSuccess, status);
EXPECT_EQ(0u, result);
loop.Quit();
}));
loop.Run();
}
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, PreloadLibraryMultiple) {
std::vector<base::FilePath> preloads;
preloads.push_back(GetDllPath(L"dbghelp"));
preloads.push_back(GetDllPath(kEchoPreloadLibrary));
EchoServiceProcessObserver observer;
auto echo_service = ServiceProcessHost::Launch<echo::mojom::EchoService>(
ServiceProcessHost::Options()
.WithPreloadedLibraries(
preloads, ServiceProcessHostPreloadLibraries::GetPassKey())
.Pass());
observer.WaitForLaunch();
base::RunLoop loop;
echo_service->LoadNativeLibrary(
GetDllPath(kEchoPreloadLibrary), false,
base::BindLambdaForTesting([&](LoadStatus status, uint32_t result) {
EXPECT_EQ(LoadStatus::kSuccess, status);
EXPECT_EQ(0u, result);
loop.Quit();
}));
loop.Run();
}
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, PreloadLibraryModName) {
std::vector<base::FilePath> preloads;
preloads.push_back(GetDllPath(kEchoPreloadLibrary));
EchoServiceProcessObserver observer;
auto echo_service = ServiceProcessHost::Launch<echo::mojom::EchoService>(
ServiceProcessHost::Options()
.WithPreloadedLibraries(
preloads, ServiceProcessHostPreloadLibraries::GetPassKey())
.Pass());
observer.WaitForLaunch();
base::RunLoop loop;
echo_service->LoadNativeLibrary(
base::FilePath(kEchoPreloadLibrary), false,
base::BindLambdaForTesting([&](LoadStatus status, uint32_t result) {
EXPECT_EQ(LoadStatus::kSuccess, status);
EXPECT_EQ(0u, result);
loop.Quit();
}));
loop.Run();
}
IN_PROC_BROWSER_TEST_F(ServiceProcessHostBrowserTest, PreloadLibraryBadPath) {
std::vector<base::FilePath> preloads;
preloads.push_back(GetDllPath(L"this-is-not-a-library"));
EchoServiceProcessObserver observer;
auto echo_service = ServiceProcessHost::Launch<echo::mojom::EchoService>(
ServiceProcessHost::Options()
.WithSite(GURL(kTestUrl))
.WithPreloadedLibraries(
preloads, ServiceProcessHostPreloadLibraries::GetPassKey())
.Pass());
observer.WaitForLaunch();
observer.WaitForCrash();
}
#endif
}