1 // 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 UI_BASE_CLIPBOARD_CLIPBOARD_H_
6 #define UI_BASE_CLIPBOARD_CLIPBOARD_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "base/callback.h"
16 #include "base/compiler_specific.h"
17 #include "base/component_export.h"
18 #include "base/containers/flat_map.h"
19 #include "base/macros.h"
20 #include "base/no_destructor.h"
21 #include "base/process/process.h"
22 #include "base/strings/string16.h"
23 #include "base/synchronization/lock.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/threading/thread_checker.h"
26 #include "base/time/time.h"
27 #include "build/build_config.h"
28 #include "mojo/public/cpp/base/big_buffer.h"
29 #include "ui/base/clipboard/clipboard_buffer.h"
30 #include "ui/base/clipboard/clipboard_format_type.h"
31 #include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
32 
33 class SkBitmap;
34 
35 namespace ui {
36 class TestClipboard;
37 class ScopedClipboardWriter;
38 class DataTransferEndpoint;
39 
40 // Clipboard:
41 // - reads from and writes to the system clipboard.
42 // - specifies an ordering in which to write types to the clipboard
43 //   (see PortableFormat).
44 // - is generalized for all targets/operating systems.
45 // TODO(https://crbug.com/443355): Make all functions asynchronous.
46 // Currently, only ReadImage() is asynchronous, but eventually, we would like
47 // all interfaces to be async.
COMPONENT_EXPORT(UI_BASE_CLIPBOARD)48 class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard
49     : public base::ThreadChecker {
50  public:
51   static bool IsSupportedClipboardBuffer(ClipboardBuffer buffer);
52 
53   // Sets the list of threads that are allowed to access the clipboard.
54   static void SetAllowedThreads(
55       const std::vector<base::PlatformThreadId>& allowed_threads);
56 
57   // Sets the clipboard for the current thread, and take ownership of
58   // |platform_clipboard|.
59   // TODO(huangdarwin): In the past, mus allowed >1 clipboard implementation per
60   // platform. Now that mus is removed, only 1 clipboard implementation exists
61   // per platform. Evaluate whether we can or should remove functions like
62   // SetClipboardForCurrentThread, as only one clipboard should exist now.
63   static void SetClipboardForCurrentThread(
64       std::unique_ptr<Clipboard> platform_clipboard);
65 
66   // Returns the clipboard object for the current thread.
67   //
68   // Most implementations will have at most one clipboard which will live on
69   // the main UI thread, but Windows has tricky semantics where there have to
70   // be two clipboards: one that lives on the UI thread and one that lives on
71   // the IO thread.
72   static Clipboard* GetForCurrentThread();
73 
74   // Removes and transfers ownership of the current thread's clipboard to the
75   // caller. If the clipboard was never initialized, returns nullptr.
76   static std::unique_ptr<Clipboard> TakeForCurrentThread();
77 
78   // Does any work necessary prior to Chrome shutdown for the current thread.
79   // All platforms but Windows have a single clipboard shared accross all
80   // threads. This function is a no-op on Windows. On Desktop Linux, if Chrome
81   // has ownership of the clipboard selection this function transfers the
82   // clipboard selection to the clipboard manager.
83   static void OnPreShutdownForCurrentThread();
84 
85   // Destroys the clipboard for the current thread. Usually, this will clean up
86   // all clipboards, except on Windows. (Previous code leaks the IO thread
87   // clipboard, so it shouldn't be a problem.)
88   static void DestroyClipboardForCurrentThread();
89 
90   virtual void OnPreShutdown() = 0;
91 
92   // Returns a sequence number which uniquely identifies clipboard state.
93   // This can be used to version the data on the clipboard and determine
94   // whether it has changed.
95   virtual uint64_t GetSequenceNumber(ClipboardBuffer buffer) const = 0;
96 
97   // Tests whether the clipboard contains a certain format.
98   virtual bool IsFormatAvailable(
99       const ClipboardFormatType& format,
100       ClipboardBuffer buffer,
101       const DataTransferEndpoint* data_dst) const = 0;
102 
103   // Returns whether the clipboard has data that is marked by its originator as
104   // confidential. This is available for opt-in checking by the user of this API
105   // as confidential information, like passwords, might legitimately need to be
106   // manipulated.
107   virtual bool IsMarkedByOriginatorAsConfidential() const;
108 
109   // Mark the data on the clipboard as being confidential. This isn't
110   // implemented for all platforms yet, but this call should be made on every
111   // platform so that when it is implemented on other platforms it is picked up.
112   virtual void MarkAsConfidential();
113 
114   // Clear the clipboard data.
115   virtual void Clear(ClipboardBuffer buffer) = 0;
116 
117   // TODO(huangdarwin): Refactor ReadAvailableTypes to return |types|.
118   // TODO(huangdarwin): Rename to ReadAvailablePortableFormatNames().
119   // Includes all sanitized types.
120   // Also, includes pickled types by splitting them out of the pickled format.
121   virtual void ReadAvailableTypes(ClipboardBuffer buffer,
122                                   const DataTransferEndpoint* data_dst,
123                                   std::vector<base::string16>* types) const = 0;
124   // Includes all types, including unsanitized types.
125   // Omits formats held within pickles, as they're different from what a native
126   // application would see.
127   virtual std::vector<base::string16> ReadAvailablePlatformSpecificFormatNames(
128       ClipboardBuffer buffer,
129       const DataTransferEndpoint* data_dst) const = 0;
130 
131   // Reads Unicode text from the clipboard, if available.
132   virtual void ReadText(ClipboardBuffer buffer,
133                         const DataTransferEndpoint* data_dst,
134                         base::string16* result) const = 0;
135 
136   // Reads ASCII text from the clipboard, if available.
137   virtual void ReadAsciiText(ClipboardBuffer buffer,
138                              const DataTransferEndpoint* data_dst,
139                              std::string* result) const = 0;
140 
141   // Reads HTML from the clipboard, if available. If the HTML fragment requires
142   // context to parse, |fragment_start| and |fragment_end| are indexes into
143   // markup indicating the beginning and end of the actual fragment. Otherwise,
144   // they will contain 0 and markup->size().
145   virtual void ReadHTML(ClipboardBuffer buffer,
146                         const DataTransferEndpoint* data_dst,
147                         base::string16* markup,
148                         std::string* src_url,
149                         uint32_t* fragment_start,
150                         uint32_t* fragment_end) const = 0;
151 
152   // Reads an SVG image from the clipboard, if available.
153   virtual void ReadSvg(ClipboardBuffer buffer,
154                        const DataTransferEndpoint* data_dst,
155                        base::string16* result) const = 0;
156   // Reads RTF from the clipboard, if available. Stores the result as a byte
157   // vector.
158   virtual void ReadRTF(ClipboardBuffer buffer,
159                        const DataTransferEndpoint* data_dst,
160                        std::string* result) const = 0;
161 
162   using ReadImageCallback = base::OnceCallback<void(const SkBitmap&)>;
163 
164   // Reads an image from the clipboard, if available.
165   virtual void ReadImage(ClipboardBuffer buffer,
166                          const DataTransferEndpoint* data_dst,
167                          ReadImageCallback callback) const = 0;
168 
169   virtual void ReadCustomData(ClipboardBuffer buffer,
170                               const base::string16& type,
171                               const DataTransferEndpoint* data_dst,
172                               base::string16* result) const = 0;
173 
174   // Reads a bookmark from the clipboard, if available.
175   // |title| or |url| may be null.
176   virtual void ReadBookmark(const DataTransferEndpoint* data_dst,
177                             base::string16* title,
178                             std::string* url) const = 0;
179 
180   // Reads raw data from the clipboard with the given format type. Stores result
181   // as a byte vector.
182   virtual void ReadData(const ClipboardFormatType& format,
183                         const DataTransferEndpoint* data_dst,
184                         std::string* result) const = 0;
185 
186   // Returns an estimate of the time the clipboard was last updated.  If the
187   // time is unknown, returns Time::Time().
188   virtual base::Time GetLastModifiedTime() const;
189 
190   // Resets the clipboard last modified time to Time::Time().
191   virtual void ClearLastModifiedTime();
192 
193  protected:
194   // PortableFormat designates the type of data to be stored in the clipboard.
195   // This designation is shared across all OSes. The system-specific designation
196   // is defined by ClipboardFormatType. A single PortableFormat might be
197   // represented by several system-specific ClipboardFormatTypes. For example,
198   // on Linux the kText PortableFormat maps to "text/plain", "STRING", and
199   // several other formats. On windows it maps to CF_UNICODETEXT.
200   //
201   // The order below is the order in which data will be written to the
202   // clipboard, so more specific types must be listed before less specific
203   // types. For example, placing an image on the clipboard might cause the
204   // clipboard to contain a bitmap, HTML markup representing the image, a URL to
205   // the image, and the image's alt text. Having the types follow this order
206   // maximizes the amount of data that can be extracted by various programs.
207   enum class PortableFormat {
208     kBitmap,  // Bitmap from shared memory.
209     kHtml,
210     kRtf,
211     kBookmark,
212     kText,
213     kWebkit,
214     kData,  // Arbitrary block of bytes.
215     kSvg,
216   };
217 
218   // TODO (https://crbug.com/994928): Rename ObjectMap-related types.
219   // ObjectMap is a map from PortableFormat to associated data.
220   // The data is organized differently for each PortableFormat. The following
221   // table summarizes what kind of data is stored for each key.
222   // * indicates an optional argument.
223   //
224   // Key        Arguments    Type
225   // -------------------------------------
226   // kBitmap    bitmap       A pointer to a SkBitmap. The caller must ensure
227   //                         the SkBitmap remains live for the duration of
228   //                         the WritePortableRepresentations call.
229   // kHtml      html         char array
230   //            url*         char array
231   // kRtf       data         byte array
232   // kBookmark  html         char array
233   //            url          char array
234   // kText      text         char array
235   // kWebkit    none         empty vector
236   // kData      format       char array
237   //            data         byte array
238   using ObjectMapParam = std::vector<char>;
239   using ObjectMapParams = std::vector<ObjectMapParam>;
240   using ObjectMap = base::flat_map<PortableFormat, ObjectMapParams>;
241 
242   // PlatformRepresentation is used for DispatchPlatformRepresentations, and
243   // supports writing directly to the system clipboard, without custom type
244   // mapping per platform.
245   struct PlatformRepresentation {
246     std::string format;
247     // BigBuffer shared memory is still writable from the renderer when backed
248     // by shared memory, so PlatformRepresentation's data.data() must not be
249     // branched on, and *data.data() must not be accessed, except to copy it
250     // into private memory.
251     mojo_base::BigBuffer data;
252   };
253 
254   static Clipboard* Create();
255 
256   Clipboard();
257   virtual ~Clipboard();
258 
259   // Write a bunch of objects to the system clipboard. Copies are made of the
260   // contents of |objects|. Also, adds the source of the data to the clipboard,
261   // which can be used when we need to restrict the clipboard data between a set
262   // of confidential documents. The data source maybe passed as nullptr.
263   virtual void WritePortableRepresentations(
264       ClipboardBuffer buffer,
265       const ObjectMap& objects,
266       std::unique_ptr<DataTransferEndpoint> data_src) = 0;
267 
268   // Write |platform_representations|, in the order of their appearance in
269   // |platform_representations|. Also, adds the source of the data to the
270   // clipboard, which can be used when we need to restrict the clipboard data
271   // between a set of confidential documents. The data source maybe passed as
272   // nullptr.
273   virtual void WritePlatformRepresentations(
274       ClipboardBuffer buffer,
275       std::vector<Clipboard::PlatformRepresentation> platform_representations,
276       std::unique_ptr<DataTransferEndpoint> data_src) = 0;
277 
278   void DispatchPortableRepresentation(PortableFormat format,
279                                       const ObjectMapParams& params);
280 
281   // Write directly to the system clipboard.
282   void DispatchPlatformRepresentations(
283       std::vector<Clipboard::PlatformRepresentation> platform_representations);
284 
285   virtual void WriteText(const char* text_data, size_t text_len) = 0;
286 
287   virtual void WriteHTML(const char* markup_data,
288                          size_t markup_len,
289                          const char* url_data,
290                          size_t url_len) = 0;
291 
292   virtual void WriteSvg(const char* markup_data, size_t markup_len) = 0;
293 
294   virtual void WriteRTF(const char* rtf_data, size_t data_len) = 0;
295 
296   virtual void WriteBookmark(const char* title_data,
297                              size_t title_len,
298                              const char* url_data,
299                              size_t url_len) = 0;
300 
301   virtual void WriteWebSmartPaste() = 0;
302 
303   virtual void WriteBitmap(const SkBitmap& bitmap) = 0;
304 
305   // |data_data| is shared memory, and is still writable from the renderer.
306   // Therefore, |data_data| must not be branched on, and *|data_data| must not
307   // be accessed, except to copy it into private memory.
308   virtual void WriteData(const ClipboardFormatType& format,
309                          const char* data_data,
310                          size_t data_len) = 0;
311 
312  private:
313   // For access to WritePortableRepresentations().
314   friend class ForwardingTestingClipboard;
315   friend class ScopedClipboardWriter;
316   friend class TestClipboard;
317   // For SetClipboardForCurrentThread's argument.
318   friend struct std::default_delete<Clipboard>;
319 
320   static base::PlatformThreadId GetAndValidateThreadID();
321 
322 #if defined(USE_OZONE)
323   // Returns whether the selection buffer is available.  This is true for some
324   // Linux platforms.
325   virtual bool IsSelectionBufferAvailable() const = 0;
326 #endif  // defined(USE_OZONE)
327 
328   // A list of allowed threads. By default, this is empty and no thread checking
329   // is done (in the unit test case), but a user (like content) can set which
330   // threads are allowed to call this method.
331   static std::vector<base::PlatformThreadId>& AllowedThreads();
332 
333   // Mapping from threads to clipboard objects.
334   using ClipboardMap =
335       base::flat_map<base::PlatformThreadId, std::unique_ptr<Clipboard>>;
336   static ClipboardMap* ClipboardMapPtr();
337 
338   // Mutex that controls access to |g_clipboard_map|.
339   static base::Lock& ClipboardMapLock();
340 
341   DISALLOW_COPY_AND_ASSIGN(Clipboard);
342 };
343 
344 }  // namespace ui
345 
346 #endif  // UI_BASE_CLIPBOARD_CLIPBOARD_H_
347