Made the Read File and Copy to Clipboard public

The read file and copy to clipboard method was moved to a public method
so we can utilize this tool in other contexts. We want to implement this
method in the files app so we can copy images in the files app directly
to the system clipboard.

BUG=827333

Change-Id: I11d1429f48b3a087ad7f5251b8ca44dd81c0c75b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2273298
Commit-Queue: Alexander Nohe <[email protected]>
Reviewed-by: James Cook <[email protected]>
Cr-Commit-Position: refs/heads/master@{#789346}
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 377211c47..1fa7a23b 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1808,6 +1808,8 @@
       "ash/chrome_screenshot_grabber_test_observer.h",
       "ash/chrome_shell_delegate.cc",
       "ash/chrome_shell_delegate.h",
+      "ash/clipboard_util.cc",
+      "ash/clipboard_util.h",
       "ash/image_downloader_impl.cc",
       "ash/image_downloader_impl.h",
       "ash/ime_controller_client.cc",
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc
index f34d189..11d03ccd 100644
--- a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc
+++ b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc
@@ -36,6 +36,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/chrome_screenshot_grabber_test_observer.h"
+#include "chrome/browser/ui/ash/clipboard_util.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
@@ -44,8 +45,6 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "services/data_decoder/public/cpp/decode_image.h"
-#include "ui/base/clipboard/clipboard.h"
-#include "ui/base/clipboard/scoped_clipboard_writer.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/paint_vector_icon.h"
@@ -59,9 +58,6 @@
 
 const char kNotificationOriginUrl[] = "chrome://screenshot";
 
-const char kImageClipboardFormatPrefix[] = "<img src='data:image/png;base64,";
-const char kImageClipboardFormatSuffix[] = "'>";
-
 // User is waiting for the screenshot-taken notification, hence USER_VISIBLE.
 constexpr base::TaskTraits kBlockingTaskTraits = {
     base::MayBlock(), base::TaskPriority::USER_VISIBLE,
@@ -69,53 +65,6 @@
 
 ChromeScreenshotGrabber* g_chrome_screenshot_grabber_instance = nullptr;
 
-void CopyScreenshotToClipboard(scoped_refptr<base::RefCountedString> png_data,
-                               const SkBitmap& decoded_image) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  std::string encoded;
-  base::Base64Encode(png_data->data(), &encoded);
-  {
-    ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
-
-    // Send both HTML and and Image formats to clipboard. HTML format is needed
-    // by ARC, while Image is needed by Hangout.
-    std::string html(kImageClipboardFormatPrefix);
-    html += encoded;
-    html += kImageClipboardFormatSuffix;
-    scw.WriteHTML(base::UTF8ToUTF16(html), std::string());
-    scw.WriteImage(decoded_image);
-  }
-  base::RecordAction(base::UserMetricsAction("Screenshot_CopyClipboard"));
-}
-
-void DecodeFileAndCopyToClipboard(
-    scoped_refptr<base::RefCountedString> png_data) {
-  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-
-  // Decode the image in sandboxed process because |png_data| comes from
-  // external storage.
-  data_decoder::DecodeImageIsolated(
-      std::vector<uint8_t>(png_data->data().begin(), png_data->data().end()),
-      data_decoder::mojom::ImageCodec::DEFAULT, false,
-      data_decoder::kDefaultMaxSizeInBytes, gfx::Size(),
-      base::BindOnce(&CopyScreenshotToClipboard, png_data));
-}
-
-void ReadFileAndCopyToClipboardLocal(const base::FilePath& screenshot_path) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::WILL_BLOCK);
-  scoped_refptr<base::RefCountedString> png_data(new base::RefCountedString());
-  if (!base::ReadFileToString(screenshot_path, &(png_data->data()))) {
-    LOG(ERROR) << "Failed to read the screenshot file: "
-               << screenshot_path.value();
-    return;
-  }
-
-  content::GetUIThreadTaskRunner({})->PostTask(
-      FROM_HERE, base::BindOnce(&DecodeFileAndCopyToClipboard, png_data));
-}
-
 // Delegate for a notification. This class has two roles: to implement callback
 // methods for notification, and to provide an identity of the associated
 // notification.
@@ -151,7 +100,9 @@
         // screenshot file and copy it to the clipboard.
         base::ThreadPool::PostTask(
             FROM_HERE, kBlockingTaskTraits,
-            base::BindOnce(&ReadFileAndCopyToClipboardLocal, screenshot_path_));
+            base::BindOnce(&clipboard_util::ReadFileAndCopyToClipboardLocal,
+                           screenshot_path_));
+        base::RecordAction(base::UserMetricsAction("Screenshot_CopyClipboard"));
         break;
       }
       case BUTTON_ANNOTATE: {
diff --git a/chrome/browser/ui/ash/clipboard_util.cc b/chrome/browser/ui/ash/clipboard_util.cc
new file mode 100644
index 0000000..4380434
--- /dev/null
+++ b/chrome/browser/ui/ash/clipboard_util.cc
@@ -0,0 +1,71 @@
+// Copyright 2020 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.
+
+#include "chrome/browser/ui/ash/clipboard_util.h"
+
+#include "base/base64.h"
+#include "base/files/file_util.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/metrics/user_metrics.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "content/public/browser/browser_task_traits.h"
+#include "content/public/browser/browser_thread.h"
+#include "services/data_decoder/public/cpp/decode_image.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
+
+namespace clipboard_util {
+namespace {
+
+const char kImageClipboardFormatPrefix[] = "<img src='data:image/png;base64,";
+const char kImageClipboardFormatSuffix[] = "'>";
+
+void CopyImageToClipboard(scoped_refptr<base::RefCountedString> png_data,
+                          const SkBitmap& decoded_image) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  std::string encoded;
+  base::Base64Encode(png_data->data(), &encoded);
+  {
+    ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
+
+    // Send both HTML and and Image formats to clipboard. HTML format is needed
+    // by ARC, while Image is needed by Hangout.
+    std::string html(kImageClipboardFormatPrefix);
+    html += encoded;
+    html += kImageClipboardFormatSuffix;
+    scw.WriteHTML(base::UTF8ToUTF16(html), std::string());
+    scw.WriteImage(decoded_image);
+  }
+}
+
+void DecodeFileAndCopyToClipboard(
+    scoped_refptr<base::RefCountedString> png_data) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+  // Decode the image in sandboxed process because |png_data| comes from
+  // external storage.
+  data_decoder::DecodeImageIsolated(
+      std::vector<uint8_t>(png_data->data().begin(), png_data->data().end()),
+      data_decoder::mojom::ImageCodec::DEFAULT, false,
+      data_decoder::kDefaultMaxSizeInBytes, gfx::Size(),
+      base::BindOnce(&CopyImageToClipboard, png_data));
+}
+
+}  // namespace
+
+void ReadFileAndCopyToClipboardLocal(const base::FilePath& local_file) {
+  DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::WILL_BLOCK);
+  scoped_refptr<base::RefCountedString> png_data(new base::RefCountedString());
+  if (!base::ReadFileToString(local_file, &(png_data->data()))) {
+    LOG(ERROR) << "Failed to read the screenshot file: " << local_file.value();
+    return;
+  }
+
+  content::GetUIThreadTaskRunner({})->PostTask(
+      FROM_HERE, base::BindOnce(&DecodeFileAndCopyToClipboard, png_data));
+}
+}  // namespace clipboard_util
diff --git a/chrome/browser/ui/ash/clipboard_util.h b/chrome/browser/ui/ash/clipboard_util.h
new file mode 100644
index 0000000..ecaf89e
--- /dev/null
+++ b/chrome/browser/ui/ash/clipboard_util.h
@@ -0,0 +1,20 @@
+// Copyright 2020 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 CHROME_BROWSER_UI_ASH_CLIPBOARD_UTIL_H_
+#define CHROME_BROWSER_UI_ASH_CLIPBOARD_UTIL_H_
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace clipboard_util {
+
+// Reads a local file and then copies that file to the system clipboard. This
+// should not be run on the UI Thread as it performs blocking IO.
+void ReadFileAndCopyToClipboardLocal(const base::FilePath& local_file);
+
+}  // namespace clipboard_util
+
+#endif  // CHROME_BROWSER_UI_ASH_CLIPBOARD_UTIL_H_