blob: eeb4d0100db98b9bc80eb8bc31704cf14ebe4b27 [file] [log] [blame]
danakjc492bf82020-09-09 20:02:441// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
6#define CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_
7
8#include <map>
9#include <memory>
10#include <string>
11#include <vector>
12
Austin Sullivanfc870892021-04-29 18:40:1113#include "base/callback_forward.h"
Daniel Chengd4c3eab2021-08-31 18:39:0114#include "base/gtest_prod_util.h"
danakjc492bf82020-09-09 20:02:4415#include "base/macros.h"
16#include "base/memory/weak_ptr.h"
danakjc492bf82020-09-09 20:02:4417#include "base/time/time.h"
18#include "build/build_config.h"
19#include "content/browser/renderer_host/render_frame_host_impl.h"
20#include "content/common/content_export.h"
Daniel Cheng9fb887ff2021-10-01 20:27:3821#include "content/public/browser/document_service.h"
Austin Sullivanfc870892021-04-29 18:40:1122#include "mojo/public/cpp/base/big_buffer.h"
danakjc492bf82020-09-09 20:02:4423#include "mojo/public/cpp/bindings/receiver.h"
Anton Bikineevf62d1bf2021-05-15 17:56:0724#include "third_party/abseil-cpp/absl/types/optional.h"
danakjc492bf82020-09-09 20:02:4425#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
26#include "ui/base/clipboard/clipboard.h"
27
28class GURL;
29
30namespace ui {
31class ScopedClipboardWriter;
32} // namespace ui
33
34namespace content {
35
36class ClipboardHostImplTest;
37
Alexander Timine3383d02021-06-24 19:57:5938class CONTENT_EXPORT ClipboardHostImpl
Daniel Cheng9fb887ff2021-10-01 20:27:3839 : public DocumentService<blink::mojom::ClipboardHost> {
danakjc492bf82020-09-09 20:02:4440 public:
41 ~ClipboardHostImpl() override;
42
43 static void Create(
44 RenderFrameHost* render_frame_host,
45 mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
46
47 protected:
48 // These types and methods are protected for testing.
49
Darwin Huang6195d042021-02-12 22:36:0050 using ClipboardPasteContentAllowed =
51 RenderFrameHostImpl::ClipboardPasteContentAllowed;
52 using IsClipboardPasteContentAllowedCallback =
53 RenderFrameHostImpl::IsClipboardPasteContentAllowedCallback;
danakjc492bf82020-09-09 20:02:4454
55 // Keeps track of a request to see if some clipboard content, identified by
56 // its sequence number, is allowed to be pasted into the render frame host
57 // that owns this clipboard host.
58 //
59 // A request starts in the state incomplete until Complete() is called with
60 // a value. Callbacks can be added to the request before or after it has
61 // completed.
Darwin Huang6195d042021-02-12 22:36:0062 class CONTENT_EXPORT IsPasteContentAllowedRequest {
danakjc492bf82020-09-09 20:02:4463 public:
Darwin Huang6195d042021-02-12 22:36:0064 IsPasteContentAllowedRequest();
65 ~IsPasteContentAllowedRequest();
danakjc492bf82020-09-09 20:02:4466
67 // Adds |callback| to be notified when the request completes. If the
68 // request is already completed |callback| is invoked immediately. Returns
69 // true if a request should be started after adding this callback.
Darwin Huang6195d042021-02-12 22:36:0070 bool AddCallback(IsClipboardPasteContentAllowedCallback callback);
danakjc492bf82020-09-09 20:02:4471
72 // Mark this request as completed with the specified result.
73 // Invoke all callbacks now.
Darwin Huang6195d042021-02-12 22:36:0074 void Complete(ClipboardPasteContentAllowed allowed);
danakjc492bf82020-09-09 20:02:4475
76 // Returns true if this request is obsolete. An obsolete request
77 // is one that is completed, all registered callbacks have been
78 // called, and is considered old.
79 //
80 // |now| represents the current time. It is an argument to ease testing.
81 bool IsObsolete(base::Time now);
82
83 // Returns the time at which this request was created.
84 base::Time time() { return time_; }
85
86 private:
87 // Calls all the callbacks in |callbacks_| with the current value of
88 // |allowed_|. |allowed_| must not be empty.
89 void InvokeCallbacks();
90
91 base::Time time_{base::Time::Now()};
Anton Bikineevf62d1bf2021-05-15 17:56:0792 absl::optional<ClipboardPasteContentAllowed> allowed_;
Darwin Huang6195d042021-02-12 22:36:0093 std::vector<IsClipboardPasteContentAllowedCallback> callbacks_;
danakjc492bf82020-09-09 20:02:4494 };
95
96 // A paste allowed request is obsolete if it is older than this time.
Darwin Huang6195d042021-02-12 22:36:0097 static const base::TimeDelta kIsPasteContentAllowedRequestTooOld;
danakjc492bf82020-09-09 20:02:4498
Alexander Timine3383d02021-06-24 19:57:5999 explicit ClipboardHostImpl(
100 RenderFrameHost* render_frame_host,
101 mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
danakjc492bf82020-09-09 20:02:44102
Aya ElAttar84e6ef32021-03-02 16:29:19103 // Performs a check to see if pasting `data` is allowed by data transfer
104 // policies and invokes PasteIfPolicyAllowedCallback upon completion.
105 // PerformPasteIfContentAllowed maybe be invoked immediately if the policy
106 // controller doesn't exist.
107 void PasteIfPolicyAllowed(ui::ClipboardBuffer clipboard_buffer,
108 const ui::ClipboardFormatType& data_type,
109 std::string data,
110 IsClipboardPasteContentAllowedCallback callback);
111
danakjc492bf82020-09-09 20:02:44112 // Performs a check to see if pasting |data| is allowed and invokes |callback|
Aya ElAttar84e6ef32021-03-02 16:29:19113 // upon completion. |callback| may be invoked immediately if the data has
114 // already been checked. |data| and |seqno| should corresponds to the same
danakjc492bf82020-09-09 20:02:44115 // clipboard data.
Darwin Huang6195d042021-02-12 22:36:00116 void PerformPasteIfContentAllowed(
Austin Sullivanbfe1af72021-07-20 23:14:14117 const ui::ClipboardSequenceNumberToken& seqno,
Darwin Huang6195d042021-02-12 22:36:00118 const ui::ClipboardFormatType& data_type,
119 std::string data,
120 IsClipboardPasteContentAllowedCallback callback);
danakjc492bf82020-09-09 20:02:44121
122 // Remove obsolete entries from the outstanding requests map.
123 // A request is obsolete if:
124 // - its sequence number is less than |seqno|
125 // - it has no callbacks
126 // - it is too old
127 void CleanupObsoleteRequests();
128
Aya ElAttar84e6ef32021-03-02 16:29:19129 // Completion callback of PerformPasteIfContentAllowed(). Sets the allowed
danakjc492bf82020-09-09 20:02:44130 // status for the clipboard data corresponding to sequence number |seqno|.
Austin Sullivanbfe1af72021-07-20 23:14:14131 void FinishPasteIfContentAllowed(
132 const ui::ClipboardSequenceNumberToken& seqno,
133 ClipboardPasteContentAllowed allowed);
danakjc492bf82020-09-09 20:02:44134
Austin Sullivanbfe1af72021-07-20 23:14:14135 const std::map<ui::ClipboardSequenceNumberToken,
136 IsPasteContentAllowedRequest>&
danakjc492bf82020-09-09 20:02:44137 is_paste_allowed_requests_for_testing() {
138 return is_allowed_requests_;
139 }
140
141 private:
142 friend class ClipboardHostImplTest;
143 friend class ClipboardHostImplScanTest;
144 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00145 IsPasteContentAllowedRequest_AddCallback);
danakjc492bf82020-09-09 20:02:44146 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00147 IsPasteContentAllowedRequest_Complete);
danakjc492bf82020-09-09 20:02:44148 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00149 IsPasteContentAllowedRequest_IsObsolete);
danakjc492bf82020-09-09 20:02:44150 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
Darwin Huang6195d042021-02-12 22:36:00151 PerformPasteIfContentAllowed_EmptyData);
152 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
153 PerformPasteIfContentAllowed);
danakjc492bf82020-09-09 20:02:44154
155 // mojom::ClipboardHost
156 void GetSequenceNumber(ui::ClipboardBuffer clipboard_buffer,
157 GetSequenceNumberCallback callback) override;
158 void IsFormatAvailable(blink::mojom::ClipboardFormat format,
159 ui::ClipboardBuffer clipboard_buffer,
160 IsFormatAvailableCallback callback) override;
161 void ReadAvailableTypes(ui::ClipboardBuffer clipboard_buffer,
162 ReadAvailableTypesCallback callback) override;
163 void ReadText(ui::ClipboardBuffer clipboard_buffer,
164 ReadTextCallback callback) override;
165 void ReadHtml(ui::ClipboardBuffer clipboard_buffer,
166 ReadHtmlCallback callback) override;
167 void ReadSvg(ui::ClipboardBuffer clipboard_buffer,
168 ReadSvgCallback callback) override;
169 void ReadRtf(ui::ClipboardBuffer clipboard_buffer,
170 ReadRtfCallback callback) override;
Austin Sullivanaa060982021-06-25 17:49:30171 void ReadPng(ui::ClipboardBuffer clipboard_buffer,
172 ReadPngCallback callback) override;
danakjc492bf82020-09-09 20:02:44173 void ReadImage(ui::ClipboardBuffer clipboard_buffer,
174 ReadImageCallback callback) override;
Joel Hockey4c0cb8c2021-02-22 02:59:59175 void ReadFiles(ui::ClipboardBuffer clipboard_buffer,
176 ReadFilesCallback callback) override;
danakjc492bf82020-09-09 20:02:44177 void ReadCustomData(ui::ClipboardBuffer clipboard_buffer,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58178 const std::u16string& type,
danakjc492bf82020-09-09 20:02:44179 ReadCustomDataCallback callback) override;
Anupam Snigdha74b68e42021-08-10 23:35:59180 void ReadAvailableCustomAndStandardFormats(
181 ReadAvailableCustomAndStandardFormatsCallback callback) override;
182 void ReadUnsanitizedCustomFormat(
183 const std::u16string& format,
184 ReadUnsanitizedCustomFormatCallback callback) override;
185 void WriteUnsanitizedCustomFormat(const std::u16string& format,
186 mojo_base::BigBuffer data) override;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58187 void WriteText(const std::u16string& text) override;
188 void WriteHtml(const std::u16string& markup, const GURL& url) override;
189 void WriteSvg(const std::u16string& markup) override;
danakjc492bf82020-09-09 20:02:44190 void WriteSmartPasteMarker() override;
191 void WriteCustomData(
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58192 const base::flat_map<std::u16string, std::u16string>& data) override;
danakjc492bf82020-09-09 20:02:44193 void WriteBookmark(const std::string& url,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58194 const std::u16string& title) override;
danakjbdf1e0a2020-11-10 18:27:47195 void WriteImage(const SkBitmap& unsafe_bitmap) override;
danakjc492bf82020-09-09 20:02:44196 void CommitWrite() override;
197#if defined(OS_MAC)
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58198 void WriteStringToFindPboard(const std::u16string& text) override;
danakjc492bf82020-09-09 20:02:44199#endif
200
Anupam Snigdha74b68e42021-08-10 23:35:59201 // Returns true if custom format is allowed to be read/written from/to the
202 // clipboard, else, fails.
203 bool IsUnsanitizedCustomFormatContentAllowed();
204
Darwin Huang6195d042021-02-12 22:36:00205 // Called by PerformPasteIfContentAllowed() when an is allowed request is
206 // needed. Virtual to be overridden in tests.
207 virtual void StartIsPasteContentAllowedRequest(
Austin Sullivanbfe1af72021-07-20 23:14:14208 const ui::ClipboardSequenceNumberToken& seqno,
danakjc492bf82020-09-09 20:02:44209 const ui::ClipboardFormatType& data_type,
210 std::string data);
211
Aya ElAttar84e6ef32021-03-02 16:29:19212 // Completion callback of PasteIfPolicyAllowed. If `is_allowed` is set to
213 // true, PerformPasteIfContentAllowed will be invoked. Otherwise `callback`
214 // will be invoked immediately to cancel the paste.
215 void PasteIfPolicyAllowedCallback(
216 ui::ClipboardBuffer clipboard_buffer,
217 const ui::ClipboardFormatType& data_type,
218 std::string data,
219 IsClipboardPasteContentAllowedCallback callback,
220 bool is_allowed);
221
Austin Sullivanfc870892021-04-29 18:40:11222 void OnReadPng(ui::ClipboardBuffer clipboard_buffer,
223 ReadPngCallback callback,
224 const std::vector<uint8_t>& data);
danakjc492bf82020-09-09 20:02:44225 void OnReadImage(ui::ClipboardBuffer clipboard_buffer,
226 ReadImageCallback callback,
227 const SkBitmap& bitmap);
228
Aya ElAttar5e8cfb082020-10-28 14:33:18229 std::unique_ptr<ui::DataTransferEndpoint> CreateDataEndpoint();
danakjc492bf82020-09-09 20:02:44230
danakjc492bf82020-09-09 20:02:44231 std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
232
233 // Outstanding is allowed requests per clipboard contents. Maps a clipboard
234 // sequence number to an outstanding request.
Austin Sullivanbfe1af72021-07-20 23:14:14235 std::map<ui::ClipboardSequenceNumberToken, IsPasteContentAllowedRequest>
236 is_allowed_requests_;
danakjc492bf82020-09-09 20:02:44237
238 base::WeakPtrFactory<ClipboardHostImpl> weak_ptr_factory_{this};
239};
240
241} // namespace content
242
243#endif // CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_