summaryrefslogtreecommitdiff
path: root/chromium/ui/base/clipboard/clipboard.h
blob: 11ce126c3d8afae166b6853a486fd5295d3c216c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_H_
#define UI_BASE_CLIPBOARD_CLIPBOARD_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/process/process.h"
#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "mojo/public/cpp/base/big_buffer.h"
#include "ui/base/clipboard/clipboard_buffer.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include "ui/base/clipboard/file_info.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"

class GURL;
class SkBitmap;

namespace ui {
class TestClipboard;
class ScopedClipboardWriter;
class DataTransferEndpoint;

// Clipboard:
// - reads from and writes to the system clipboard.
// - specifies an ordering in which to write types to the clipboard
//   (see PortableFormat).
// - is generalized for all targets/operating systems.
class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) Clipboard
    : public base::ThreadChecker {
 public:
  using ReadAvailableTypesCallback =
      base::OnceCallback<void(std::vector<std::u16string> result)>;
  using ReadAvailablePlatformSpecificFormatNamesCallback =
      base::OnceCallback<void(std::vector<std::u16string> result)>;
  using ReadTextCallback = base::OnceCallback<void(std::u16string result)>;
  using ReadAsciiTextCallback = base::OnceCallback<void(std::string result)>;
  using ReadHtmlCallback = base::OnceCallback<void(std::u16string markup,
                                                   GURL src_url,
                                                   uint32_t fragment_start,
                                                   uint32_t fragment_end)>;
  using ReadSvgCallback = base::OnceCallback<void(std::u16string result)>;
  using ReadRTFCallback = base::OnceCallback<void(std::string result)>;
  using ReadPngCallback =
      base::OnceCallback<void(const std::vector<uint8_t>& result)>;
  using ReadImageCallback = base::OnceCallback<void(const SkBitmap& result)>;
  using ReadCustomDataCallback =
      base::OnceCallback<void(std::u16string result)>;
  using ReadFilenamesCallback =
      base::OnceCallback<void(std::vector<ui::FileInfo> result)>;
  using ReadBookmarkCallback =
      base::OnceCallback<void(std::u16string title, GURL url)>;
  using ReadDataCallback = base::OnceCallback<void(std::string result)>;

  static bool IsSupportedClipboardBuffer(ClipboardBuffer buffer);

  // Sets the list of threads that are allowed to access the clipboard.
  static void SetAllowedThreads(
      const std::vector<base::PlatformThreadId>& allowed_threads);

  // Sets the clipboard for the current thread, and take ownership of
  // |platform_clipboard|.
  // TODO(huangdarwin): In the past, mus allowed >1 clipboard implementation per
  // platform. Now that mus is removed, only 1 clipboard implementation exists
  // per platform. Evaluate whether we can or should remove functions like
  // SetClipboardForCurrentThread, as only one clipboard should exist now.
  static void SetClipboardForCurrentThread(
      std::unique_ptr<Clipboard> platform_clipboard);

  // Returns the clipboard object for the current thread.
  //
  // Most implementations will have at most one clipboard which will live on
  // the main UI thread, but Windows has tricky semantics where there have to
  // be two clipboards: one that lives on the UI thread and one that lives on
  // the IO thread.
  static Clipboard* GetForCurrentThread();

  // Removes and transfers ownership of the current thread's clipboard to the
  // caller. If the clipboard was never initialized, returns nullptr.
  static std::unique_ptr<Clipboard> TakeForCurrentThread();

  // Does any work necessary prior to Chrome shutdown for the current thread.
  // All platforms but Windows have a single clipboard shared accross all
  // threads. This function is a no-op on Windows. On Desktop Linux, if Chrome
  // has ownership of the clipboard selection this function transfers the
  // clipboard selection to the clipboard manager.
  static void OnPreShutdownForCurrentThread();

  // Destroys the clipboard for the current thread. Usually, this will clean up
  // all clipboards, except on Windows. (Previous code leaks the IO thread
  // clipboard, so it shouldn't be a problem.)
  static void DestroyClipboardForCurrentThread();

  virtual void OnPreShutdown() = 0;

  // Gets the source of the current clipboard buffer contents.
  virtual const DataTransferEndpoint* GetSource(
      ClipboardBuffer buffer) const = 0;

  // Returns a sequence number which uniquely identifies clipboard state.
  // This can be used to version the data on the clipboard and determine
  // whether it has changed.
  virtual uint64_t GetSequenceNumber(ClipboardBuffer buffer) const = 0;

  // Tests whether the clipboard contains a certain format.
  virtual bool IsFormatAvailable(
      const ClipboardFormatType& format,
      ClipboardBuffer buffer,
      const DataTransferEndpoint* data_dst) const = 0;

  // Returns whether the clipboard has data that is marked by its originator as
  // confidential. This is available for opt-in checking by the user of this API
  // as confidential information, like passwords, might legitimately need to be
  // manipulated.
  virtual bool IsMarkedByOriginatorAsConfidential() const;

  // Mark the data on the clipboard as being confidential. This isn't
  // implemented for all platforms yet, but this call should be made on every
  // platform so that when it is implemented on other platforms it is picked up.
  virtual void MarkAsConfidential();

  // Clear the clipboard data.
  virtual void Clear(ClipboardBuffer buffer) = 0;

  // TODO(huangdarwin): Rename to ReadAvailablePortableFormatNames().
  // Includes all sanitized types.
  // Also, includes pickled types by splitting them out of the pickled format.
  virtual void ReadAvailableTypes(ClipboardBuffer buffer,
                                  const DataTransferEndpoint* data_dst,
                                  ReadAvailableTypesCallback callback) const;
  // Includes all types, including unsanitized types.
  // Omits formats held within pickles, as they're different from what a native
  // application would see.
  virtual void ReadAvailablePlatformSpecificFormatNames(
      ClipboardBuffer buffer,
      const DataTransferEndpoint* data_dst,
      ReadAvailablePlatformSpecificFormatNamesCallback callback) const;

  // Reads Unicode text from the clipboard, if available.
  virtual void ReadText(ClipboardBuffer buffer,
                        const DataTransferEndpoint* data_dst,
                        ReadTextCallback callback) const;

  // Reads ASCII text from the clipboard, if available.
  virtual void ReadAsciiText(ClipboardBuffer buffer,
                             const DataTransferEndpoint* data_dst,
                             ReadAsciiTextCallback callback) const;

  // Reads HTML from the clipboard, if available. If the HTML fragment requires
  // context to parse, |fragment_start| and |fragment_end| are indexes into
  // markup indicating the beginning and end of the actual fragment. Otherwise,
  // they will contain 0 and markup->size().
  virtual void ReadHTML(ClipboardBuffer buffer,
                        const DataTransferEndpoint* data_dst,
                        ReadHtmlCallback callback) const;

  // Reads an SVG image from the clipboard, if available.
  virtual void ReadSvg(ClipboardBuffer buffer,
                       const DataTransferEndpoint* data_dst,
                       ReadSvgCallback callback) const;

  // Reads RTF from the clipboard, if available. Stores the result as a byte
  // vector.
  virtual void ReadRTF(ClipboardBuffer buffer,
                       const DataTransferEndpoint* data_dst,
                       ReadRTFCallback callback) const;

  // Reads a png from the clipboard, if available.
  virtual void ReadPng(ClipboardBuffer buffer,
                       const DataTransferEndpoint* data_dst,
                       ReadPngCallback callback) const = 0;

  // Reads an image from the clipboard, if available.
  virtual void ReadImage(ClipboardBuffer buffer,
                         const DataTransferEndpoint* data_dst,
                         ReadImageCallback callback) const = 0;

  virtual void ReadCustomData(ClipboardBuffer buffer,
                              const std::u16string& type,
                              const DataTransferEndpoint* data_dst,
                              ReadCustomDataCallback callback) const;

  // Reads filenames from the clipboard, if available.
  virtual void ReadFilenames(ClipboardBuffer buffer,
                             const DataTransferEndpoint* data_dst,
                             ReadFilenamesCallback callback) const;

  // Reads a bookmark from the clipboard, if available.
  // |title| or |url| may be null.
  virtual void ReadBookmark(const DataTransferEndpoint* data_dst,
                            ReadBookmarkCallback callback) const;

  // Reads raw data from the clipboard with the given format type. Stores result
  // as a byte vector.
  virtual void ReadData(const ClipboardFormatType& format,
                        const DataTransferEndpoint* data_dst,
                        ReadDataCallback callback) const;

  // Synchronous reads are deprecated (https://crbug.com/443355). Please use the
  // equivalent functions that take callbacks above.
  virtual void ReadAvailableTypes(ClipboardBuffer buffer,
                                  const DataTransferEndpoint* data_dst,
                                  std::vector<std::u16string>* types) const = 0;
  virtual std::vector<std::u16string> ReadAvailablePlatformSpecificFormatNames(
      ClipboardBuffer buffer,
      const DataTransferEndpoint* data_dst) const = 0;
  virtual void ReadText(ClipboardBuffer buffer,
                        const DataTransferEndpoint* data_dst,
                        std::u16string* result) const = 0;
  virtual void ReadAsciiText(ClipboardBuffer buffer,
                             const DataTransferEndpoint* data_dst,
                             std::string* result) const = 0;
  virtual void ReadHTML(ClipboardBuffer buffer,
                        const DataTransferEndpoint* data_dst,
                        std::u16string* markup,
                        std::string* src_url,
                        uint32_t* fragment_start,
                        uint32_t* fragment_end) const = 0;
  virtual void ReadSvg(ClipboardBuffer buffer,
                       const DataTransferEndpoint* data_dst,
                       std::u16string* result) const = 0;
  virtual void ReadRTF(ClipboardBuffer buffer,
                       const DataTransferEndpoint* data_dst,
                       std::string* result) const = 0;
  virtual void ReadCustomData(ClipboardBuffer buffer,
                              const std::u16string& type,
                              const DataTransferEndpoint* data_dst,
                              std::u16string* result) const = 0;
  virtual void ReadFilenames(ClipboardBuffer buffer,
                             const DataTransferEndpoint* data_dst,
                             std::vector<ui::FileInfo>* result) const = 0;
  virtual void ReadBookmark(const DataTransferEndpoint* data_dst,
                            std::u16string* title,
                            std::string* url) const = 0;
  virtual void ReadData(const ClipboardFormatType& format,
                        const DataTransferEndpoint* data_dst,
                        std::string* result) const = 0;

  // Returns an estimate of the time the clipboard was last updated.  If the
  // time is unknown, returns Time::Time().
  virtual base::Time GetLastModifiedTime() const;

  // Resets the clipboard last modified time to Time::Time().
  virtual void ClearLastModifiedTime();

 protected:
  // PortableFormat designates the type of data to be stored in the clipboard.
  // This designation is shared across all OSes. The system-specific designation
  // is defined by ClipboardFormatType. A single PortableFormat might be
  // represented by several system-specific ClipboardFormatTypes. For example,
  // on Linux the kText PortableFormat maps to "text/plain", "STRING", and
  // several other formats. On windows it maps to CF_UNICODETEXT.
  //
  // The order below is the order in which data will be written to the
  // clipboard, so more specific types must be listed before less specific
  // types. For example, placing an image on the clipboard might cause the
  // clipboard to contain a bitmap, HTML markup representing the image, a URL to
  // the image, and the image's alt text. Having the types follow this order
  // maximizes the amount of data that can be extracted by various programs.
  enum class PortableFormat {
    kBitmap,  // Bitmap from shared memory.
    kHtml,
    kRtf,
    kBookmark,
    kText,
    kWebkit,
    kData,  // Arbitrary block of bytes.
    kSvg,
    kFilenames,
  };

  // TODO (https://crbug.com/994928): Rename ObjectMap-related types.
  // ObjectMap is a map from PortableFormat to associated data.
  // The data is organized differently for each PortableFormat. The following
  // table summarizes what kind of data is stored for each key.
  // * indicates an optional argument.
  //
  // Key        Arguments    Type
  // -------------------------------------
  // kBitmap    bitmap        A pointer to a SkBitmap. The caller must ensure
  //                          the SkBitmap remains live for the duration of
  //                          the WritePortableRepresentations call.
  // kHtml      html          char array
  //            url*          char array
  // kRtf       data          byte array
  // kFilenames text/uri-list char array
  // kBookmark  html          char array
  //            url           char array
  // kText      text          char array
  // kWebkit    none          empty vector
  // kData      format        char array
  //            data          byte array
  using ObjectMapParam = std::vector<char>;
  using ObjectMapParams = std::vector<ObjectMapParam>;
  using ObjectMap = base::flat_map<PortableFormat, ObjectMapParams>;

  // PlatformRepresentation is used for DispatchPlatformRepresentations, and
  // supports writing directly to the system clipboard, without custom type
  // mapping per platform.
  struct PlatformRepresentation {
    std::string format;
    // BigBuffer shared memory is still writable from the renderer when backed
    // by shared memory, so PlatformRepresentation's data.data() must not be
    // branched on, and *data.data() must not be accessed, except to copy it
    // into private memory.
    mojo_base::BigBuffer data;
  };

  static Clipboard* Create();

  Clipboard();
  virtual ~Clipboard();

  // Write a bunch of objects to the system clipboard. Copies are made of the
  // contents of |objects|. Also, adds the source of the data to the clipboard,
  // which can be used when we need to restrict the clipboard data between a set
  // of confidential documents. The data source maybe passed as nullptr.
  virtual void WritePortableRepresentations(
      ClipboardBuffer buffer,
      const ObjectMap& objects,
      std::unique_ptr<DataTransferEndpoint> data_src) = 0;

  // Write |platform_representations|, in the order of their appearance in
  // |platform_representations|. Also, adds the source of the data to the
  // clipboard, which can be used when we need to restrict the clipboard data
  // between a set of confidential documents. The data source maybe passed as
  // nullptr.
  virtual void WritePlatformRepresentations(
      ClipboardBuffer buffer,
      std::vector<Clipboard::PlatformRepresentation> platform_representations,
      std::unique_ptr<DataTransferEndpoint> data_src) = 0;

  void DispatchPortableRepresentation(PortableFormat format,
                                      const ObjectMapParams& params);

  // Write directly to the system clipboard.
  void DispatchPlatformRepresentations(
      std::vector<Clipboard::PlatformRepresentation> platform_representations);

  virtual void WriteText(const char* text_data, size_t text_len) = 0;

  virtual void WriteHTML(const char* markup_data,
                         size_t markup_len,
                         const char* url_data,
                         size_t url_len) = 0;

  virtual void WriteSvg(const char* markup_data, size_t markup_len) = 0;

  virtual void WriteRTF(const char* rtf_data, size_t data_len) = 0;

  virtual void WriteFilenames(std::vector<ui::FileInfo> filenames) = 0;

  virtual void WriteBookmark(const char* title_data,
                             size_t title_len,
                             const char* url_data,
                             size_t url_len) = 0;

  virtual void WriteWebSmartPaste() = 0;

  virtual void WriteBitmap(const SkBitmap& bitmap) = 0;

  // |data_data| is shared memory, and is still writable from the renderer.
  // Therefore, |data_data| must not be branched on, and *|data_data| must not
  // be accessed, except to copy it into private memory.
  virtual void WriteData(const ClipboardFormatType& format,
                         const char* data_data,
                         size_t data_len) = 0;

 private:
  // For access to WritePortableRepresentations().
  friend class ForwardingTestingClipboard;
  friend class ScopedClipboardWriter;
  friend class TestClipboard;
  // For SetClipboardForCurrentThread's argument.
  friend struct std::default_delete<Clipboard>;

  static base::PlatformThreadId GetAndValidateThreadID();

#if defined(USE_OZONE)
  // Returns whether the selection buffer is available.  This is true for some
  // Linux platforms.
  virtual bool IsSelectionBufferAvailable() const = 0;
#endif  // defined(USE_OZONE)

  // A list of allowed threads. By default, this is empty and no thread checking
  // is done (in the unit test case), but a user (like content) can set which
  // threads are allowed to call this method.
  static std::vector<base::PlatformThreadId>& AllowedThreads();

  // Mapping from threads to clipboard objects.
  using ClipboardMap =
      base::flat_map<base::PlatformThreadId, std::unique_ptr<Clipboard>>;
  static ClipboardMap* ClipboardMapPtr();

  // Mutex that controls access to |g_clipboard_map|.
  static base::Lock& ClipboardMapLock();

  DISALLOW_COPY_AND_ASSIGN(Clipboard);
};

}  // namespace ui

#endif  // UI_BASE_CLIPBOARD_CLIPBOARD_H_