blob: d4bee1cf6dd120d27e4cd5c812e3c44315b72604 [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
Georg Neis763539e2024-08-20 05:10:415#include "chrome/browser/ui/ash/clipboard/clipboard_util.h"
[email protected]57118ea2020-07-17 03:17:146
[email protected]026b7c4f2020-10-27 12:05:217#include <stdint.h>
Peter Kastinga4863242024-12-23 00:19:438
[email protected]026b7c4f2020-10-27 12:05:219#include <memory>
Austin Sullivan85ec8772021-10-26 23:16:0210#include <vector>
[email protected]026b7c4f2020-10-27 12:05:2111
Alex Newcomer9fd616332021-01-15 23:04:5812#include "ash/public/cpp/clipboard_history_controller.h"
[email protected]57118ea2020-07-17 03:17:1413#include "base/base64.h"
14#include "base/files/file_util.h"
Avi Drissman9269d4ed2023-01-07 01:38:0615#include "base/functional/callback.h"
16#include "base/functional/callback_helpers.h"
[email protected]57118ea2020-07-17 03:17:1417#include "base/memory/ref_counted_memory.h"
[email protected]026b7c4f2020-10-27 12:05:2118#include "base/memory/scoped_refptr.h"
[email protected]57118ea2020-07-17 03:17:1419#include "base/metrics/user_metrics.h"
Lei Zhang2b7c9e02020-09-25 21:30:4720#include "base/strings/strcat.h"
Joe Masona0ba58b052023-02-22 20:46:2921#include "base/strings/utf_string_conversions.h"
[email protected]57118ea2020-07-17 03:17:1422#include "base/threading/scoped_blocking_call.h"
23#include "content/public/browser/browser_task_traits.h"
24#include "content/public/browser/browser_thread.h"
25#include "services/data_decoder/public/cpp/decode_image.h"
26#include "ui/base/clipboard/clipboard.h"
[email protected]026b7c4f2020-10-27 12:05:2127#include "ui/base/clipboard/clipboard_buffer.h"
28#include "ui/base/clipboard/clipboard_data.h"
29#include "ui/base/clipboard/clipboard_non_backed.h"
[email protected]57118ea2020-07-17 03:17:1430#include "ui/base/clipboard/scoped_clipboard_writer.h"
31
32namespace clipboard_util {
33namespace {
34
[email protected]026b7c4f2020-10-27 12:05:2135/*
[email protected]026b7c4f2020-10-27 12:05:2136 * `clipboard_sequence` is the versioning of the clipboard when we start our
37 * copy operation.
Austin Sullivanec750b62021-10-27 19:07:2238 * `decoded_image` and `html` are different formats of the same image which we
39 * are attempting to copy to the clipboard. */
40void CopyDecodedImageToClipboard(
41 ui::ClipboardSequenceNumberToken clipboard_sequence,
Austin Sullivanec750b62021-10-27 19:07:2242 std::string html,
43 const SkBitmap& decoded_image) {
44 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
45
46 ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kCopyPaste);
Anupam Snigdha18ac05c2024-01-30 21:25:5947 clipboard_writer.WriteHTML(base::UTF8ToUTF16(html), std::string());
Austin Sullivanec750b62021-10-27 19:07:2248 clipboard_writer.WriteImage(decoded_image);
[email protected]57118ea2020-07-17 03:17:1449}
50
[email protected]57118ea2020-07-17 03:17:1451} // namespace
52
53void ReadFileAndCopyToClipboardLocal(const base::FilePath& local_file) {
54 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
55 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
56 base::BlockingType::WILL_BLOCK);
François Doray73d3e002021-11-08 18:41:3757 std::string png_data;
58 if (!base::ReadFileToString(local_file, &png_data)) {
[email protected]57118ea2020-07-17 03:17:1459 LOG(ERROR) << "Failed to read the screenshot file: " << local_file.value();
60 return;
61 }
62
63 content::GetUIThreadTaskRunner({})->PostTask(
Austin Sullivanbfe1af72021-07-20 23:14:1464 FROM_HERE,
François Doray73d3e002021-11-08 18:41:3765 base::BindOnce(&DecodeImageFileAndCopyToClipboard,
Austin Sullivanbfe1af72021-07-20 23:14:1466 /*clipboard_sequence=*/ui::ClipboardSequenceNumberToken(),
François Doray73d3e002021-11-08 18:41:3767 std::move(png_data)));
[email protected]2ae4df182020-08-27 16:48:0968}
69
François Doray73d3e002021-11-08 18:41:3770void DecodeImageFileAndCopyToClipboard(
Austin Sullivanbfe1af72021-07-20 23:14:1471 ui::ClipboardSequenceNumberToken clipboard_sequence,
François Doray73d3e002021-11-08 18:41:3772 std::string png_data) {
[email protected]2ae4df182020-08-27 16:48:0973 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
74
Austin Sullivanec750b62021-10-27 19:07:2275 // Send both HTML and and Image formats to clipboard. HTML format is needed
76 // by ARC, while Image is needed by Hangout.
77 static const char kImageClipboardFormatPrefix[] =
78 "<img src='data:image/png;base64,";
79 static const char kImageClipboardFormatSuffix[] = "'>";
80
Peter Kasting650ea1c2024-12-01 05:51:5581 std::string encoded = base::Base64Encode(base::as_byte_span(png_data));
Austin Sullivanec750b62021-10-27 19:07:2282 std::string html = base::StrCat(
83 {kImageClipboardFormatPrefix, encoded, kImageClipboardFormatSuffix});
84
François Doray73d3e002021-11-08 18:41:3785 // Decode the image in sandboxed process because |png_data| comes from
86 // external storage.
87 data_decoder::DecodeImageIsolated(
Peter Kasting650ea1c2024-12-01 05:51:5588 base::as_byte_span(png_data), data_decoder::mojom::ImageCodec::kDefault,
François Doray73d3e002021-11-08 18:41:3789 /*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