blob: 2929da4dfb0e2b788060f6794e94e665318cb8cf [file] [log] [blame]
[email protected]57118ea2020-07-17 03:17:141// Copyright 2020 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#include "chrome/browser/ui/ash/clipboard_util.h"
6
7#include "base/base64.h"
8#include "base/files/file_util.h"
9#include "base/memory/ref_counted_memory.h"
10#include "base/metrics/user_metrics.h"
Lei Zhang2b7c9e02020-09-25 21:30:4711#include "base/strings/strcat.h"
[email protected]57118ea2020-07-17 03:17:1412#include "base/threading/scoped_blocking_call.h"
13#include "content/public/browser/browser_task_traits.h"
14#include "content/public/browser/browser_thread.h"
15#include "services/data_decoder/public/cpp/decode_image.h"
16#include "ui/base/clipboard/clipboard.h"
17#include "ui/base/clipboard/scoped_clipboard_writer.h"
18
19namespace clipboard_util {
20namespace {
21
[email protected]57118ea2020-07-17 03:17:1422void CopyImageToClipboard(scoped_refptr<base::RefCountedString> png_data,
23 const SkBitmap& decoded_image) {
24 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
25
Lei Zhang2b7c9e02020-09-25 21:30:4726 ui::ScopedClipboardWriter clipboard_writer(ui::ClipboardBuffer::kCopyPaste);
[email protected]57118ea2020-07-17 03:17:1427
Lei Zhang2b7c9e02020-09-25 21:30:4728 // Send both HTML and and Image formats to clipboard. HTML format is needed
29 // by ARC, while Image is needed by Hangout.
30 static const char kImageClipboardFormatPrefix[] =
31 "<img src='data:image/png;base64,";
32 static const char kImageClipboardFormatSuffix[] = "'>";
33
34 std::string encoded =
35 base::Base64Encode(base::as_bytes(base::make_span(png_data->data())));
36 std::string html = base::StrCat(
37 {kImageClipboardFormatPrefix, encoded, kImageClipboardFormatSuffix});
38 clipboard_writer.WriteHTML(base::UTF8ToUTF16(html), std::string());
39 clipboard_writer.WriteImage(decoded_image);
[email protected]57118ea2020-07-17 03:17:1440}
41
[email protected]57118ea2020-07-17 03:17:1442} // namespace
43
44void ReadFileAndCopyToClipboardLocal(const base::FilePath& local_file) {
45 DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
46 base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
47 base::BlockingType::WILL_BLOCK);
Lei Zhang2b7c9e02020-09-25 21:30:4748 auto png_data = base::MakeRefCounted<base::RefCountedString>();
[email protected]57118ea2020-07-17 03:17:1449 if (!base::ReadFileToString(local_file, &(png_data->data()))) {
50 LOG(ERROR) << "Failed to read the screenshot file: " << local_file.value();
51 return;
52 }
53
54 content::GetUIThreadTaskRunner({})->PostTask(
[email protected]2ae4df182020-08-27 16:48:0955 FROM_HERE, base::BindOnce(&DecodeImageFileAndCopyToClipboard, png_data));
56}
57
58void DecodeImageFileAndCopyToClipboard(
59 scoped_refptr<base::RefCountedString> png_data) {
60 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
61
62 // Decode the image in sandboxed process because |png_data| comes from
63 // external storage.
64 data_decoder::DecodeImageIsolated(
65 std::vector<uint8_t>(png_data->data().begin(), png_data->data().end()),
66 data_decoder::mojom::ImageCodec::DEFAULT, false,
67 data_decoder::kDefaultMaxSizeInBytes, gfx::Size(),
68 base::BindOnce(&CopyImageToClipboard, png_data));
[email protected]57118ea2020-07-17 03:17:1469}
70} // namespace clipboard_util