#ifndef CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
#define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/common/content_export.h"
#include "content/public/browser/document_service.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
#include "ui/base/clipboard/clipboard.h"
class GURL;
namespace ui {
class ScopedClipboardWriter;
}
namespace content {
class ClipboardHostImplTest;
class CONTENT_EXPORT ClipboardHostImpl
: public DocumentService<blink::mojom::ClipboardHost> {
public:
~ClipboardHostImpl() override;
static void Create(
RenderFrameHost* render_frame_host,
mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
using ClipboardPasteData = content::ClipboardPasteData;
protected:
using IsClipboardPasteContentAllowedCallback =
RenderFrameHostImpl::IsClipboardPasteContentAllowedCallback;
using IsClipboardPasteContentAllowedCallbackArgType =
absl::optional<ClipboardPasteData>;
class CONTENT_EXPORT IsPasteContentAllowedRequest {
public:
IsPasteContentAllowedRequest();
~IsPasteContentAllowedRequest();
bool AddCallback(IsClipboardPasteContentAllowedCallback callback);
void Complete(IsClipboardPasteContentAllowedCallbackArgType data);
bool is_complete() const { return data_.has_value(); }
bool IsObsolete(base::Time now);
base::Time completed_time();
private:
void InvokeCallbacks();
base::Time completed_time_;
absl::optional<IsClipboardPasteContentAllowedCallbackArgType> data_;
std::vector<IsClipboardPasteContentAllowedCallback> callbacks_;
};
static const base::TimeDelta kIsPasteContentAllowedRequestTooOld;
explicit ClipboardHostImpl(
RenderFrameHost& render_frame_host,
mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
void PasteIfPolicyAllowed(ui::ClipboardBuffer clipboard_buffer,
const ui::ClipboardFormatType& data_type,
ClipboardPasteData clipboard_paste_data,
IsClipboardPasteContentAllowedCallback callback);
void PerformPasteIfContentAllowed(
const ui::ClipboardSequenceNumberToken& seqno,
const ui::ClipboardFormatType& data_type,
ClipboardPasteData clipboard_paste_data,
IsClipboardPasteContentAllowedCallback callback);
void CleanupObsoleteRequests();
void FinishPasteIfContentAllowed(
const ui::ClipboardSequenceNumberToken& seqno,
absl::optional<ClipboardPasteData> clipboard_paste_data);
const std::map<ui::ClipboardSequenceNumberToken,
IsPasteContentAllowedRequest>&
is_paste_allowed_requests_for_testing() {
return is_allowed_requests_;
}
private:
friend class ClipboardHostImplTest;
friend class ClipboardHostImplScanTest;
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
IsPasteContentAllowedRequest_AddCallback);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
IsPasteContentAllowedRequest_Complete);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
IsPasteContentAllowedRequest_IsObsolete);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
PerformPasteIfContentAllowed_EmptyData);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
PerformPasteIfContentAllowed);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
PerformPasteIfContentAllowed_SameHost_NotStarted);
FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
PerformPasteIfContentAllowed_External_Started);
void GetSequenceNumber(ui::ClipboardBuffer clipboard_buffer,
GetSequenceNumberCallback callback) override;
void IsFormatAvailable(blink::mojom::ClipboardFormat format,
ui::ClipboardBuffer clipboard_buffer,
IsFormatAvailableCallback callback) override;
void ReadAvailableTypes(ui::ClipboardBuffer clipboard_buffer,
ReadAvailableTypesCallback callback) override;
#if defined(OHOS_CLIPBOARD)
void OnClipboardDataGuard(bool status,
OnClipboardDataGuardCallback callback) override;
#endif
void ReadText(ui::ClipboardBuffer clipboard_buffer,
ReadTextCallback callback) override;
void ReadHtml(ui::ClipboardBuffer clipboard_buffer,
ReadHtmlCallback callback) override;
void ReadSvg(ui::ClipboardBuffer clipboard_buffer,
ReadSvgCallback callback) override;
void ReadRtf(ui::ClipboardBuffer clipboard_buffer,
ReadRtfCallback callback) override;
void ReadPng(ui::ClipboardBuffer clipboard_buffer,
ReadPngCallback callback) override;
void ReadFiles(ui::ClipboardBuffer clipboard_buffer,
ReadFilesCallback callback) override;
void ReadCustomData(ui::ClipboardBuffer clipboard_buffer,
const std::u16string& type,
ReadCustomDataCallback callback) override;
void ReadAvailableCustomAndStandardFormats(
ReadAvailableCustomAndStandardFormatsCallback callback) override;
void ReadUnsanitizedCustomFormat(
const std::u16string& format,
ReadUnsanitizedCustomFormatCallback callback) override;
void WriteUnsanitizedCustomFormat(const std::u16string& format,
mojo_base::BigBuffer data
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteText(const std::u16string& text
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteHtml(const std::u16string& markup, const GURL& url
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteSvg(const std::u16string& markup) override;
void WriteSmartPasteMarker(
#if defined(OHOS_CLIPBOARD)
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteCustomData(
const base::flat_map<std::u16string, std::u16string>& data
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteBookmark(const std::string& url,
const std::u16string& title
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void WriteImage(const SkBitmap& unsafe_bitmap
#if defined(OHOS_CLIPBOARD)
,
const blink::mojom::CopyOptionMode copy_option
#endif
) override;
void CommitWrite() override;
#if BUILDFLAG(IS_MAC)
void WriteStringToFindPboard(const std::u16string& text) override;
#endif
bool IsRendererPasteAllowed(ui::ClipboardBuffer clipboard_buffer,
RenderFrameHost& render_frame_host);
bool IsUnsanitizedCustomFormatContentAllowed();
virtual void StartIsPasteContentAllowedRequest(
const ui::ClipboardSequenceNumberToken& seqno,
const ui::ClipboardFormatType& data_type,
ClipboardPasteData clipboard_paste_data);
void PasteIfPolicyAllowedCallback(
ui::ClipboardBuffer clipboard_buffer,
const ui::ClipboardFormatType& data_type,
ClipboardPasteData clipboard_paste_data,
IsClipboardPasteContentAllowedCallback callback,
bool is_allowed);
using CopyAllowedCallback = base::OnceCallback<void()>;
void CopyIfAllowed(size_t data_size_in_bytes, CopyAllowedCallback callback);
void OnReadPng(ui::ClipboardBuffer clipboard_buffer,
ReadPngCallback callback,
const std::vector<uint8_t>& data);
std::unique_ptr<ui::DataTransferEndpoint> CreateDataEndpoint();
std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
std::map<ui::ClipboardSequenceNumberToken, IsPasteContentAllowedRequest>
is_allowed_requests_;
base::WeakPtrFactory<ClipboardHostImpl> weak_ptr_factory_{this};
};
}
#endif