blob: fd36e6561c06b8fe72722c6373f6b63913dab416 [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
13#include "base/macros.h"
14#include "base/memory/weak_ptr.h"
15#include "base/optional.h"
16#include "base/time/time.h"
17#include "build/build_config.h"
18#include "content/browser/renderer_host/render_frame_host_impl.h"
19#include "content/common/content_export.h"
20#include "mojo/public/cpp/bindings/receiver.h"
21#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
22#include "ui/base/clipboard/clipboard.h"
23
24class GURL;
25
26namespace ui {
27class ScopedClipboardWriter;
28} // namespace ui
29
30namespace content {
31
32class ClipboardHostImplTest;
33
34class CONTENT_EXPORT ClipboardHostImpl : public blink::mojom::ClipboardHost {
35 public:
36 ~ClipboardHostImpl() override;
37
38 static void Create(
39 RenderFrameHost* render_frame_host,
40 mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
41
42 protected:
43 // These types and methods are protected for testing.
44
Darwin Huang6195d042021-02-12 22:36:0045 using ClipboardPasteContentAllowed =
46 RenderFrameHostImpl::ClipboardPasteContentAllowed;
47 using IsClipboardPasteContentAllowedCallback =
48 RenderFrameHostImpl::IsClipboardPasteContentAllowedCallback;
danakjc492bf82020-09-09 20:02:4449
50 // Keeps track of a request to see if some clipboard content, identified by
51 // its sequence number, is allowed to be pasted into the render frame host
52 // that owns this clipboard host.
53 //
54 // A request starts in the state incomplete until Complete() is called with
55 // a value. Callbacks can be added to the request before or after it has
56 // completed.
Darwin Huang6195d042021-02-12 22:36:0057 class CONTENT_EXPORT IsPasteContentAllowedRequest {
danakjc492bf82020-09-09 20:02:4458 public:
Darwin Huang6195d042021-02-12 22:36:0059 IsPasteContentAllowedRequest();
60 ~IsPasteContentAllowedRequest();
danakjc492bf82020-09-09 20:02:4461
62 // Adds |callback| to be notified when the request completes. If the
63 // request is already completed |callback| is invoked immediately. Returns
64 // true if a request should be started after adding this callback.
Darwin Huang6195d042021-02-12 22:36:0065 bool AddCallback(IsClipboardPasteContentAllowedCallback callback);
danakjc492bf82020-09-09 20:02:4466
67 // Mark this request as completed with the specified result.
68 // Invoke all callbacks now.
Darwin Huang6195d042021-02-12 22:36:0069 void Complete(ClipboardPasteContentAllowed allowed);
danakjc492bf82020-09-09 20:02:4470
71 // Returns true if this request is obsolete. An obsolete request
72 // is one that is completed, all registered callbacks have been
73 // called, and is considered old.
74 //
75 // |now| represents the current time. It is an argument to ease testing.
76 bool IsObsolete(base::Time now);
77
78 // Returns the time at which this request was created.
79 base::Time time() { return time_; }
80
81 private:
82 // Calls all the callbacks in |callbacks_| with the current value of
83 // |allowed_|. |allowed_| must not be empty.
84 void InvokeCallbacks();
85
86 base::Time time_{base::Time::Now()};
Darwin Huang6195d042021-02-12 22:36:0087 base::Optional<ClipboardPasteContentAllowed> allowed_;
88 std::vector<IsClipboardPasteContentAllowedCallback> callbacks_;
danakjc492bf82020-09-09 20:02:4489 };
90
91 // A paste allowed request is obsolete if it is older than this time.
Darwin Huang6195d042021-02-12 22:36:0092 static const base::TimeDelta kIsPasteContentAllowedRequestTooOld;
danakjc492bf82020-09-09 20:02:4493
Daniel Cheng6f7e1c22021-02-02 05:47:5494 explicit ClipboardHostImpl(RenderFrameHost* render_frame_host);
danakjc492bf82020-09-09 20:02:4495
Aya ElAttar84e6ef32021-03-02 16:29:1996 // Performs a check to see if pasting `data` is allowed by data transfer
97 // policies and invokes PasteIfPolicyAllowedCallback upon completion.
98 // PerformPasteIfContentAllowed maybe be invoked immediately if the policy
99 // controller doesn't exist.
100 void PasteIfPolicyAllowed(ui::ClipboardBuffer clipboard_buffer,
101 const ui::ClipboardFormatType& data_type,
102 std::string data,
103 IsClipboardPasteContentAllowedCallback callback);
104
danakjc492bf82020-09-09 20:02:44105 // Performs a check to see if pasting |data| is allowed and invokes |callback|
Aya ElAttar84e6ef32021-03-02 16:29:19106 // upon completion. |callback| may be invoked immediately if the data has
107 // already been checked. |data| and |seqno| should corresponds to the same
danakjc492bf82020-09-09 20:02:44108 // clipboard data.
Darwin Huang6195d042021-02-12 22:36:00109 void PerformPasteIfContentAllowed(
110 uint64_t seqno,
111 const ui::ClipboardFormatType& data_type,
112 std::string data,
113 IsClipboardPasteContentAllowedCallback callback);
danakjc492bf82020-09-09 20:02:44114
115 // Remove obsolete entries from the outstanding requests map.
116 // A request is obsolete if:
117 // - its sequence number is less than |seqno|
118 // - it has no callbacks
119 // - it is too old
120 void CleanupObsoleteRequests();
121
Aya ElAttar84e6ef32021-03-02 16:29:19122 // Completion callback of PerformPasteIfContentAllowed(). Sets the allowed
danakjc492bf82020-09-09 20:02:44123 // status for the clipboard data corresponding to sequence number |seqno|.
Darwin Huang6195d042021-02-12 22:36:00124 void FinishPasteIfContentAllowed(uint64_t seqno,
125 ClipboardPasteContentAllowed allowed);
danakjc492bf82020-09-09 20:02:44126
Darwin Huang6195d042021-02-12 22:36:00127 const std::map<uint64_t, IsPasteContentAllowedRequest>&
danakjc492bf82020-09-09 20:02:44128 is_paste_allowed_requests_for_testing() {
129 return is_allowed_requests_;
130 }
131
132 private:
133 friend class ClipboardHostImplTest;
134 friend class ClipboardHostImplScanTest;
135 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00136 IsPasteContentAllowedRequest_AddCallback);
danakjc492bf82020-09-09 20:02:44137 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00138 IsPasteContentAllowedRequest_Complete);
danakjc492bf82020-09-09 20:02:44139 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
Darwin Huang6195d042021-02-12 22:36:00140 IsPasteContentAllowedRequest_IsObsolete);
danakjc492bf82020-09-09 20:02:44141 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
Darwin Huang6195d042021-02-12 22:36:00142 PerformPasteIfContentAllowed_EmptyData);
143 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
144 PerformPasteIfContentAllowed);
danakjc492bf82020-09-09 20:02:44145
146 // mojom::ClipboardHost
147 void GetSequenceNumber(ui::ClipboardBuffer clipboard_buffer,
148 GetSequenceNumberCallback callback) override;
149 void IsFormatAvailable(blink::mojom::ClipboardFormat format,
150 ui::ClipboardBuffer clipboard_buffer,
151 IsFormatAvailableCallback callback) override;
152 void ReadAvailableTypes(ui::ClipboardBuffer clipboard_buffer,
153 ReadAvailableTypesCallback callback) override;
154 void ReadText(ui::ClipboardBuffer clipboard_buffer,
155 ReadTextCallback callback) override;
156 void ReadHtml(ui::ClipboardBuffer clipboard_buffer,
157 ReadHtmlCallback callback) override;
158 void ReadSvg(ui::ClipboardBuffer clipboard_buffer,
159 ReadSvgCallback callback) override;
160 void ReadRtf(ui::ClipboardBuffer clipboard_buffer,
161 ReadRtfCallback callback) override;
162 void ReadImage(ui::ClipboardBuffer clipboard_buffer,
163 ReadImageCallback callback) override;
Joel Hockey4c0cb8c2021-02-22 02:59:59164 void ReadFiles(ui::ClipboardBuffer clipboard_buffer,
165 ReadFilesCallback callback) override;
danakjc492bf82020-09-09 20:02:44166 void ReadCustomData(ui::ClipboardBuffer clipboard_buffer,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58167 const std::u16string& type,
danakjc492bf82020-09-09 20:02:44168 ReadCustomDataCallback callback) override;
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58169 void WriteText(const std::u16string& text) override;
170 void WriteHtml(const std::u16string& markup, const GURL& url) override;
171 void WriteSvg(const std::u16string& markup) override;
danakjc492bf82020-09-09 20:02:44172 void WriteSmartPasteMarker() override;
173 void WriteCustomData(
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58174 const base::flat_map<std::u16string, std::u16string>& data) override;
danakjc492bf82020-09-09 20:02:44175 void WriteBookmark(const std::string& url,
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58176 const std::u16string& title) override;
danakjbdf1e0a2020-11-10 18:27:47177 void WriteImage(const SkBitmap& unsafe_bitmap) override;
danakjc492bf82020-09-09 20:02:44178 void CommitWrite() override;
179#if defined(OS_MAC)
Jan Wilken Dörrieaace0cfef2021-03-11 22:01:58180 void WriteStringToFindPboard(const std::u16string& text) override;
danakjc492bf82020-09-09 20:02:44181#endif
182
Darwin Huang6195d042021-02-12 22:36:00183 // Called by PerformPasteIfContentAllowed() when an is allowed request is
184 // needed. Virtual to be overridden in tests.
185 virtual void StartIsPasteContentAllowedRequest(
danakjc492bf82020-09-09 20:02:44186 uint64_t seqno,
187 const ui::ClipboardFormatType& data_type,
188 std::string data);
189
Aya ElAttar84e6ef32021-03-02 16:29:19190 // Completion callback of PasteIfPolicyAllowed. If `is_allowed` is set to
191 // true, PerformPasteIfContentAllowed will be invoked. Otherwise `callback`
192 // will be invoked immediately to cancel the paste.
193 void PasteIfPolicyAllowedCallback(
194 ui::ClipboardBuffer clipboard_buffer,
195 const ui::ClipboardFormatType& data_type,
196 std::string data,
197 IsClipboardPasteContentAllowedCallback callback,
198 bool is_allowed);
199
danakjc492bf82020-09-09 20:02:44200 void OnReadImage(ui::ClipboardBuffer clipboard_buffer,
201 ReadImageCallback callback,
202 const SkBitmap& bitmap);
203
Aya ElAttar5e8cfb082020-10-28 14:33:18204 std::unique_ptr<ui::DataTransferEndpoint> CreateDataEndpoint();
danakjc492bf82020-09-09 20:02:44205
danakjc492bf82020-09-09 20:02:44206 ui::Clipboard* const clipboard_; // Not owned
Darwin Huang7dadbe812020-10-02 01:06:33207 GlobalFrameRoutingId render_frame_routing_id_;
danakjc492bf82020-09-09 20:02:44208 std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
209
210 // Outstanding is allowed requests per clipboard contents. Maps a clipboard
211 // sequence number to an outstanding request.
Darwin Huang6195d042021-02-12 22:36:00212 std::map<uint64_t, IsPasteContentAllowedRequest> is_allowed_requests_;
danakjc492bf82020-09-09 20:02:44213
214 base::WeakPtrFactory<ClipboardHostImpl> weak_ptr_factory_{this};
215};
216
217} // namespace content
218
219#endif // CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_