blob: 0fb673421eb7c1a72845e2af105d8c9e69dc1494 [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2020 The Chromium Authors
[email protected]57118ea2020-07-17 03:17:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/ash/clipboard_util.h"
6
[email protected]026b7c4f2020-10-27 12:05:217#include <stdint.h>
8#include <memory>
Austin Sullivan85ec8772021-10-26 23:16:029#include <vector>
[email protected]026b7c4f2020-10-27 12:05:2110
Alex Newcomer9fd616332021-01-15 23:04:5811#include "ash/public/cpp/clipboard_history_controller.h"
[email protected]57118ea2020-07-17 03:17:1412#include "base/base64.h"
[email protected]57118ea2020-07-17 03:17:1413#include "base/files/file_util.h"
Avi Drissman9269d4ed2023-01-07 01:38:0614#include "base/functional/callback.h"
15#include "base/functional/callback_helpers.h"
[email protected]57118ea2020-07-17 03:17:1416#include "base/memory/ref_counted_memory.h"
[email protected]026b7c4f2020-10-27 12:05:2117#include "base/memory/scoped_refptr.h"
[email protected]57118ea2020-07-17 03:17:1418#include "base/metrics/user_metrics.h"
Lei Zhang2b7c9e02020-09-25 21:30:4719#include "base/strings/strcat.h"
[email protected]57118ea2020-07-17 03:17:1420#include "base/threading/scoped_blocking_call.h"
21#include "content/public/browser/browser_task_traits.h"
22#include "content/public/browser/browser_thread.h"
23#include "services/data_decoder/public/cpp/decode_image.h"
24#include "ui/base/clipboard/clipboard.h"
[email protected]026b7c4f2020-10-27 12:05:2125#include "ui/base/clipboard/clipboard_buffer.h"
26#include "ui/base/clipboard/clipboard_data.h"
27#include "ui/base/clipboard/clipboard_non_backed.h"
[email protected]57118ea2020-07-17 03:17:1428#include "ui/base/clipboard/scoped_clipboard_writer.h"
29
30namespace clipboard_util {
31namespace {
32
[email protected]026b7c4f2020-10-27 12:05:2133/*
[email protected]026b7c4f2020-10-27 12:05:2134 * `clipboard_sequence` is the versioning of the clipboard when we start our
35 * copy operation.
Austin Sullivanec750b62021-10-27 19:07:2236 * `decoded_image` and `html` are different formats of the same image which we
37 * are attempting to copy to the clipboard. */
38void CopyDecodedImageToClipboard(
39 ui::ClipboardSequenceNumberToken clipboard_sequence,
Austin Sullivanec750b62021-10-27 19:07:2240 std::string html,
41 const SkBitmap& decoded_image) {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
43
44 ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kCopyPaste);
45 clipboard_writer.WriteHTML(base::UTF8ToUTF16(html), std::string());
46 clipboard_writer.WriteImage(decoded_image);
[email protected]57118ea2020-07-17 03:17:1447}
48
[email protected]57118ea2020-07-17 03:17:1449} // namespace
50
51void ReadFileAndCopyToClipboardLocal(const base::FilePath& local_file) {
52 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
53 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
54 base::BlockingType::WILL_BLOCK);
François Doray73d3e002021-11-08 18:41:3755 std::string png_data;
56 if (!base::ReadFileToString(local_file, &png_data)) {
[email protected]57118ea2020-07-17 03:17:1457 LOG(ERROR) << "Failed to read the screenshot file: " << local_file.value();
58 return;
59 }
60
61 content::GetUIThreadTaskRunner({})->PostTask(
Austin Sullivanbfe1af72021-07-20 23:14:1462 FROM_HERE,
François Doray73d3e002021-11-08 18:41:3763 base::BindOnce(&DecodeImageFileAndCopyToClipboard,
Austin Sullivanbfe1af72021-07-20 23:14:1464 /*clipboard_sequence=*/ui::ClipboardSequenceNumberToken(),
François Doray73d3e002021-11-08 18:41:3765 std::move(png_data)));
[email protected]2ae4df182020-08-27 16:48:0966}
67
François Doray73d3e002021-11-08 18:41:3768void DecodeImageFileAndCopyToClipboard(
Austin Sullivanbfe1af72021-07-20 23:14:1469 ui::ClipboardSequenceNumberToken clipboard_sequence,
François Doray73d3e002021-11-08 18:41:3770 std::string png_data) {
[email protected]2ae4df182020-08-27 16:48:0971 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
72
Austin Sullivanec750b62021-10-27 19:07:2273 // Send both HTML and and Image formats to clipboard. HTML format is needed
74 // by ARC, while Image is needed by Hangout.
75 static const char kImageClipboardFormatPrefix[] =
76 "<img src='data:image/png;base64,";
77 static const char kImageClipboardFormatSuffix[] = "'>";
78
79 std::string encoded =
François Doray73d3e002021-11-08 18:41:3780 base::Base64Encode(base::as_bytes(base::make_span(png_data)));
Austin Sullivanec750b62021-10-27 19:07:2281 std::string html = base::StrCat(
82 {kImageClipboardFormatPrefix, encoded, kImageClipboardFormatSuffix});
83
François Doray73d3e002021-11-08 18:41:3784 // Decode the image in sandboxed process because |png_data| comes from
85 // external storage.
86 data_decoder::DecodeImageIsolated(
87 base::as_bytes(base::make_span(png_data)),
88 data_decoder::mojom::ImageCodec::kDefault,
89 /*shrink_to_fit=*/false, data_decoder::kDefaultMaxSizeInBytes,
90 gfx::Size(),
91 base::BindOnce(&CopyDecodedImageToClipboard, clipboard_sequence,
92 std::move(html)));
[email protected]57118ea2020-07-17 03:17:1493}
94} // namespace clipboard_util