blob: df05d9a55636d694c2dc5413c642fe486416d32d [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
45 using ClipboardPasteAllowed = RenderFrameHostImpl::ClipboardPasteAllowed;
46 using IsClipboardPasteAllowedCallback =
47 RenderFrameHostImpl::IsClipboardPasteAllowedCallback;
48
49 // Keeps track of a request to see if some clipboard content, identified by
50 // its sequence number, is allowed to be pasted into the render frame host
51 // that owns this clipboard host.
52 //
53 // A request starts in the state incomplete until Complete() is called with
54 // a value. Callbacks can be added to the request before or after it has
55 // completed.
56 class CONTENT_EXPORT IsPasteAllowedRequest {
57 public:
58 IsPasteAllowedRequest();
59 ~IsPasteAllowedRequest();
60
61 // Adds |callback| to be notified when the request completes. If the
62 // request is already completed |callback| is invoked immediately. Returns
63 // true if a request should be started after adding this callback.
64 bool AddCallback(IsClipboardPasteAllowedCallback callback);
65
66 // Mark this request as completed with the specified result.
67 // Invoke all callbacks now.
68 void Complete(ClipboardPasteAllowed allowed);
69
70 // Returns true if this request is obsolete. An obsolete request
71 // is one that is completed, all registered callbacks have been
72 // called, and is considered old.
73 //
74 // |now| represents the current time. It is an argument to ease testing.
75 bool IsObsolete(base::Time now);
76
77 // Returns the time at which this request was created.
78 base::Time time() { return time_; }
79
80 private:
81 // Calls all the callbacks in |callbacks_| with the current value of
82 // |allowed_|. |allowed_| must not be empty.
83 void InvokeCallbacks();
84
85 base::Time time_{base::Time::Now()};
86 base::Optional<ClipboardPasteAllowed> allowed_;
87 std::vector<IsClipboardPasteAllowedCallback> callbacks_;
88 };
89
90 // A paste allowed request is obsolete if it is older than this time.
91 static const base::TimeDelta kIsPasteAllowedRequestTooOld;
92
93 ClipboardHostImpl(
94 RenderFrameHost* render_frame_host,
95 mojo::PendingReceiver<blink::mojom::ClipboardHost> receiver);
96
97 // Performs a check to see if pasting |data| is allowed and invokes |callback|
98 // upon completion. |callback| maybe be invoked immediately if the data has
99 // already been checked. |data| and |seqno| should corresponds to the same
100 // clipboard data.
101 void PerformPasteIfAllowed(uint64_t seqno,
102 const ui::ClipboardFormatType& data_type,
103 std::string data,
104 IsClipboardPasteAllowedCallback callback);
105
106 // Remove obsolete entries from the outstanding requests map.
107 // A request is obsolete if:
108 // - its sequence number is less than |seqno|
109 // - it has no callbacks
110 // - it is too old
111 void CleanupObsoleteRequests();
112
113 // Completion callback of PerformPasteIfAllowed(). Sets the allowed
114 // status for the clipboard data corresponding to sequence number |seqno|.
115 void FinishPasteIfAllowed(uint64_t seqno, ClipboardPasteAllowed allowed);
116
117 const std::map<uint64_t, IsPasteAllowedRequest>&
118 is_paste_allowed_requests_for_testing() {
119 return is_allowed_requests_;
120 }
121
122 private:
123 friend class ClipboardHostImplTest;
124 friend class ClipboardHostImplScanTest;
125 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
126 IsPasteAllowedRequest_AddCallback);
127 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
128 IsPasteAllowedRequest_Complete);
129 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplTest,
130 IsPasteAllowedRequest_IsObsolete);
131 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest,
132 PerformPasteIfAllowed_EmptyData);
133 FRIEND_TEST_ALL_PREFIXES(ClipboardHostImplScanTest, PerformPasteIfAllowed);
134
135 // mojom::ClipboardHost
136 void GetSequenceNumber(ui::ClipboardBuffer clipboard_buffer,
137 GetSequenceNumberCallback callback) override;
138 void IsFormatAvailable(blink::mojom::ClipboardFormat format,
139 ui::ClipboardBuffer clipboard_buffer,
140 IsFormatAvailableCallback callback) override;
141 void ReadAvailableTypes(ui::ClipboardBuffer clipboard_buffer,
142 ReadAvailableTypesCallback callback) override;
143 void ReadText(ui::ClipboardBuffer clipboard_buffer,
144 ReadTextCallback callback) override;
145 void ReadHtml(ui::ClipboardBuffer clipboard_buffer,
146 ReadHtmlCallback callback) override;
147 void ReadSvg(ui::ClipboardBuffer clipboard_buffer,
148 ReadSvgCallback callback) override;
149 void ReadRtf(ui::ClipboardBuffer clipboard_buffer,
150 ReadRtfCallback callback) override;
151 void ReadImage(ui::ClipboardBuffer clipboard_buffer,
152 ReadImageCallback callback) override;
153 void ReadCustomData(ui::ClipboardBuffer clipboard_buffer,
154 const base::string16& type,
155 ReadCustomDataCallback callback) override;
156 void WriteText(const base::string16& text) override;
157 void WriteHtml(const base::string16& markup, const GURL& url) override;
158 void WriteSvg(const base::string16& markup) override;
159 void WriteSmartPasteMarker() override;
160 void WriteCustomData(
161 const base::flat_map<base::string16, base::string16>& data) override;
162 void WriteBookmark(const std::string& url,
163 const base::string16& title) override;
164 void WriteImage(const SkBitmap& bitmap) override;
165 void CommitWrite() override;
166#if defined(OS_MAC)
167 void WriteStringToFindPboard(const base::string16& text) override;
168#endif
169
170 // Called by PerformPasteIfAllowed() when an is allowed request is needed.
171 // Virtual to be overridden in tests.
172 virtual void StartIsPasteAllowedRequest(
173 uint64_t seqno,
174 const ui::ClipboardFormatType& data_type,
175 std::string data);
176
177 void OnReadImage(ui::ClipboardBuffer clipboard_buffer,
178 ReadImageCallback callback,
179 const SkBitmap& bitmap);
180
181 std::unique_ptr<ui::ClipboardDataEndpoint> CreateDataEndpoint();
182
183 mojo::Receiver<blink::mojom::ClipboardHost> receiver_;
184 ui::Clipboard* const clipboard_; // Not owned
Darwin Huang7dadbe812020-10-02 01:06:33185 GlobalFrameRoutingId render_frame_routing_id_;
danakjc492bf82020-09-09 20:02:44186 std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
187
188 // Outstanding is allowed requests per clipboard contents. Maps a clipboard
189 // sequence number to an outstanding request.
190 std::map<uint64_t, IsPasteAllowedRequest> is_allowed_requests_;
191
192 base::WeakPtrFactory<ClipboardHostImpl> weak_ptr_factory_{this};
193};
194
195} // namespace content
196
197#endif // CONTENT_BROWSER_RENDERER_HOST_CLIPBOARD_HOST_IMPL_H_