blob: 089b9e9297780a561f99ce9d59e9a4f8dbb0e870 [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.
#ifndef CHROME_CHROME_CLEANER_ENGINES_TARGET_SANDBOXED_TEST_HELPERS_H_
#define CHROME_CHROME_CLEANER_ENGINES_TARGET_SANDBOXED_TEST_HELPERS_H_
#include <memory>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "chrome/chrome_cleaner/engines/broker/cleaner_engine_requests_impl.h"
#include "chrome/chrome_cleaner/engines/broker/engine_cleanup_results_impl.h"
#include "chrome/chrome_cleaner/engines/broker/engine_file_requests_impl.h"
#include "chrome/chrome_cleaner/engines/broker/engine_requests_impl.h"
#include "chrome/chrome_cleaner/engines/broker/engine_scan_results_impl.h"
#include "chrome/chrome_cleaner/engines/broker/interface_metadata_observer.h"
#include "chrome/chrome_cleaner/engines/common/engine_digest_verifier.h"
#include "chrome/chrome_cleaner/engines/target/cleaner_engine_requests_proxy.h"
#include "chrome/chrome_cleaner/engines/target/engine_commands_impl.h"
#include "chrome/chrome_cleaner/engines/target/engine_file_requests_proxy.h"
#include "chrome/chrome_cleaner/engines/target/engine_requests_proxy.h"
#include "chrome/chrome_cleaner/ipc/ipc_test_util.h"
#include "chrome/chrome_cleaner/os/file_remover.h"
#include "chrome/chrome_cleaner/os/layered_service_provider_wrapper.h"
#include "chrome/chrome_cleaner/pup_data/pup_data.h"
namespace chrome_cleaner {
// |BaseClass| should be ParentProcess or SandboxedParentProcess.
template <typename BaseClass>
class MaybeSandboxedParentProcess : public BaseClass {
public:
enum class CallbacksToSetup {
kFileRequests,
kScanAndCleanupRequests,
kCleanupRequests
};
MaybeSandboxedParentProcess(
scoped_refptr<MojoTaskRunner> mojo_task_runner,
CallbacksToSetup requests_to_setup,
InterfaceMetadataObserver* metadata_observer = nullptr)
: BaseClass(std::move(mojo_task_runner)),
requests_to_setup_(requests_to_setup),
engine_commands_ptr_(std::make_unique<mojom::EngineCommandsPtr>()),
file_requests_impl_(
std::make_unique<EngineFileRequestsImpl>(this->mojo_task_runner(),
metadata_observer)) {
if (requests_to_setup_ == CallbacksToSetup::kScanAndCleanupRequests ||
requests_to_setup_ == CallbacksToSetup::kCleanupRequests) {
scanner_impl_ = std::make_unique<EngineRequestsImpl>(
this->mojo_task_runner(), metadata_observer);
scan_results_impl_ =
std::make_unique<EngineScanResultsImpl>(metadata_observer);
}
if (requests_to_setup_ == CallbacksToSetup::kCleanupRequests) {
scoped_refptr<chrome_cleaner::DigestVerifier> verifier =
GetDigestVerifier();
std::unique_ptr<chrome_cleaner::FileRemoverAPI> file_remover =
std::make_unique<chrome_cleaner::FileRemover>(
verifier, /*archiver=*/nullptr,
chrome_cleaner::LayeredServiceProviderWrapper(),
base::DoNothing::Repeatedly());
cleaner_impl_ = std::make_unique<CleanerEngineRequestsImpl>(
this->mojo_task_runner(), metadata_observer, std::move(file_remover));
cleanup_results_impl_ =
std::make_unique<EngineCleanupResultsImpl>(metadata_observer);
}
}
~MaybeSandboxedParentProcess() override = default;
protected:
void CreateImpl(mojo::ScopedMessagePipeHandle mojo_pipe) override {
engine_commands_ptr_->Bind(
mojom::EngineCommandsPtrInfo(std::move(mojo_pipe), 0));
mojom::EngineFileRequestsAssociatedPtrInfo file_requests_info;
file_requests_impl_->Bind(&file_requests_info);
// Bind to empty callbacks as we don't care about the result.
mojom::EngineRequestsAssociatedPtrInfo scanner_info;
mojom::EngineScanResultsAssociatedPtrInfo scanner_results_info;
if (requests_to_setup_ == CallbacksToSetup::kScanAndCleanupRequests ||
requests_to_setup_ == CallbacksToSetup::kCleanupRequests) {
scanner_impl_->Bind(&scanner_info);
scan_results_impl_->BindToCallbacks(
&scanner_results_info,
base::BindRepeating(
base::DoNothing::Repeatedly<UwSId, const PUPData::PUP&>()),
base::BindOnce(base::DoNothing::Once<uint32_t>()));
}
mojom::CleanerEngineRequestsAssociatedPtrInfo cleaner_info;
mojom::EngineCleanupResultsAssociatedPtrInfo cleaner_results_info;
if (requests_to_setup_ == CallbacksToSetup::kCleanupRequests) {
cleaner_impl_->Bind(&cleaner_info);
cleanup_results_impl_->BindToCallbacks(
&cleaner_results_info,
base::BindOnce(base::DoNothing::Once<uint32_t>()));
}
// Now call the target process to signal that setup is finished.
auto operation_started = base::BindOnce([](uint32_t unused_result_code) {});
if (requests_to_setup_ == CallbacksToSetup::kFileRequests) {
(*engine_commands_ptr_)
->Initialize(std::move(file_requests_info), base::FilePath(),
std::move(operation_started));
} else if (requests_to_setup_ ==
CallbacksToSetup::kScanAndCleanupRequests) {
(*engine_commands_ptr_)
->StartScan(/*enabled_uws=*/std::vector<UwSId>{},
/*enabled_locations=*/std::vector<UwS::TraceLocation>{},
/*include_details=*/false, std::move(file_requests_info),
std::move(scanner_info), std::move(scanner_results_info),
std::move(operation_started));
} else if (requests_to_setup_ == CallbacksToSetup::kCleanupRequests) {
(*engine_commands_ptr_)
->StartCleanup(/*enabled_uws=*/std::vector<UwSId>(),
std::move(file_requests_info), std::move(scanner_info),
std::move(cleaner_info),
std::move(cleaner_results_info),
std::move(operation_started));
}
}
void DestroyImpl() override {
// Reset everything in the reverse order. Reset the associated pointers
// first since they will error if they are closed after
// |engine_commands_ptr|.
cleanup_results_impl_.reset();
cleaner_impl_.reset();
scan_results_impl_.reset();
scanner_impl_.reset();
file_requests_impl_.reset();
engine_commands_ptr_.reset();
}
CallbacksToSetup requests_to_setup_;
std::unique_ptr<mojom::EngineCommandsPtr> engine_commands_ptr_;
std::unique_ptr<EngineFileRequestsImpl> file_requests_impl_;
std::unique_ptr<EngineRequestsImpl> scanner_impl_;
std::unique_ptr<CleanerEngineRequestsImpl> cleaner_impl_;
std::unique_ptr<EngineScanResultsImpl> scan_results_impl_;
std::unique_ptr<EngineCleanupResultsImpl> cleanup_results_impl_;
};
class SandboxChildProcess : public ChildProcess {
public:
explicit SandboxChildProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner);
void BindEngineCommandsRequest(mojom::EngineCommandsRequest request,
base::WaitableEvent* event);
scoped_refptr<EngineFileRequestsProxy> GetFileRequestsProxy();
scoped_refptr<EngineRequestsProxy> GetEngineRequestsProxy();
scoped_refptr<CleanerEngineRequestsProxy> GetCleanerEngineRequestsProxy();
void UnbindRequestsPtrs();
// Exit code value to be used by the child process on connection errors.
static const int kConnectionErrorExitCode;
protected:
~SandboxChildProcess() override;
private:
class FakeEngineDelegate;
scoped_refptr<FakeEngineDelegate> fake_engine_delegate_;
std::unique_ptr<EngineCommandsImpl> engine_commands_impl_;
};
} // namespace chrome_cleaner
#endif // CHROME_CHROME_CLEANER_ENGINES_TARGET_SANDBOXED_TEST_HELPERS_H_