blob: e2dec76934d15871372a96c254f9a3cb8c6e604d [file] [log] [blame]
// Copyright 2018 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 REMOTING_HOST_FILE_TRANSFER_IPC_FILE_OPERATIONS_H_
#define REMOTING_HOST_FILE_TRANSFER_IPC_FILE_OPERATIONS_H_
#include <cstdint>
#include "base/containers/flat_map.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "remoting/host/file_transfer/file_operations.h"
#include "remoting/proto/file_transfer.pb.h"
namespace remoting {
// Implementation of FileOperations that translates the interface into easy-to-
// serialize requests that can be forwarded over an IPC channel.
// IpcFileOperationsRequestHandlerImpl can be used on the remote end to
// perform the requested operations.
class IpcFileOperations : public FileOperations {
public:
// Handles requests generated by IpcFileOperations instances by either
// performing the requested operations directly or forwarding them to another
// process.
class RequestHandler {
public:
virtual ~RequestHandler() = default;
virtual void WriteFile(std::uint64_t file_id,
const base::FilePath& filename) = 0;
virtual void WriteChunk(std::uint64_t file_id, std::string data) = 0;
virtual void Close(std::uint64_t file_id) = 0;
virtual void Cancel(std::uint64_t file_id) = 0;
};
// Handles responses to file operations requests.
class ResultHandler {
public:
virtual ~ResultHandler() = default;
virtual void OnResult(
std::uint64_t file_id,
base::Optional<protocol::FileTransfer_Error> error) = 0;
};
~IpcFileOperations() override;
// FileOperations implementation.
void WriteFile(const base::FilePath& filename,
WriteFileCallback callback) override;
void ReadFile(ReadFileCallback) override;
private:
using ResultCallback =
base::OnceCallback<void(base::Optional<protocol::FileTransfer_Error>)>;
class IpcWriter;
struct SharedState {
public:
explicit SharedState(RequestHandler* request_handler);
~SharedState();
// File ID to use for the next file opened.
std::uint64_t next_file_id = 0;
// Pending callbacks awaiting responses from the desktop process, keyed by
// the file_id of the waiting Reader or Writer.
base::flat_map<std::uint64_t, ResultCallback> result_callbacks;
// The associated RequestHandler.
RequestHandler* request_handler;
base::WeakPtrFactory<SharedState> weak_ptr_factory;
private:
DISALLOW_COPY_AND_ASSIGN(SharedState);
};
explicit IpcFileOperations(base::WeakPtr<SharedState> shared_state);
static void OnWriteFileResult(
std::unique_ptr<IpcWriter> writer,
WriteFileCallback callback,
base::Optional<protocol::FileTransfer_Error> error);
// Contains shared state used by all instances tied to a given
// RequestHandler.
base::WeakPtr<SharedState> shared_state_;
friend class IpcFileOperationsFactory;
DISALLOW_COPY_AND_ASSIGN(IpcFileOperations);
};
// Creates IpcFileOperations instances for a given RequestHandler. All
// IpcFileOperations instances for the RequestHandler must be created through
// the same IpcFileOperationsFactory.
class IpcFileOperationsFactory : public IpcFileOperations::ResultHandler {
public:
// |request_handler| must be valid for the entire lifetime of
// IpcFileOperationsFactory, and must only be used to construct a single
// IpcFileOperationsFactory to avoid file ID conflicts.
IpcFileOperationsFactory(IpcFileOperations::RequestHandler* request_handler);
~IpcFileOperationsFactory() override;
std::unique_ptr<FileOperations> CreateFileOperations();
// ResultHandler implementation.
void OnResult(std::uint64_t file_id,
base::Optional<protocol::FileTransfer_Error> error) override;
private:
IpcFileOperations::SharedState shared_state_;
DISALLOW_COPY_AND_ASSIGN(IpcFileOperationsFactory);
};
} // namespace remoting
#endif // REMOTING_HOST_FILE_TRANSFER_IPC_FILE_OPERATIONS_H_