Add gif support for image share and copy on Android
This CL add gif support for image share and copy on Android. Android
Context Menu Can request original image data from renderer if image is
PNG, JPEG or GIF, and then share to other apps or save to the system's
clipboard.
Bug: 1057006
Change-Id: I624eeb10d3377857c0867fb73b4b6402b24ef476
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2101933
Commit-Queue: Gang Wu <[email protected]>
Reviewed-by: Mustafa Emre Acer <[email protected]>
Reviewed-by: Theresa <[email protected]>
Reviewed-by: Philip Rogers <[email protected]>
Reviewed-by: Khushal <[email protected]>
Reviewed-by: Sinan Sahin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#755704}
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc
index 5fad1b44..fb018a93 100644
--- a/chrome/browser/ui/android/context_menu_helper.cc
+++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -9,10 +9,12 @@
#include <map>
#include "base/android/callback_android.h"
+#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
+#include "base/strings/string_util.h"
#include "chrome/android/chrome_jni_headers/ContextMenuHelper_jni.h"
#include "chrome/browser/download/android/download_controller_base.h"
#include "chrome/browser/image_decoder/image_decoder.h"
@@ -39,6 +41,22 @@
namespace {
+chrome::mojom::ImageFormat ToChromeMojomImageFormat(int image_format) {
+ ContextMenuImageFormat format =
+ static_cast<ContextMenuImageFormat>(image_format);
+ switch (format) {
+ case ContextMenuImageFormat::JPEG:
+ return chrome::mojom::ImageFormat::JPEG;
+ case ContextMenuImageFormat::PNG:
+ return chrome::mojom::ImageFormat::PNG;
+ case ContextMenuImageFormat::ORIGINAL:
+ return chrome::mojom::ImageFormat::ORIGINAL;
+ }
+
+ NOTREACHED();
+ return chrome::mojom::ImageFormat::JPEG;
+}
+
class ContextMenuHelperImageRequest : public ImageDecoder::ImageRequest {
public:
static void Start(const base::android::JavaRef<jobject>& jcallback,
@@ -76,8 +94,16 @@
chrome_render_frame,
const base::android::JavaRef<jobject>& jcallback,
const std::vector<uint8_t>& thumbnail_data,
- const gfx::Size& original_size) {
- base::android::RunByteArrayCallbackAndroid(jcallback, thumbnail_data);
+ const gfx::Size& original_size,
+ const std::string& image_extension) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ base::android::ScopedJavaLocalRef<jbyteArray> j_data =
+ base::android::ToJavaByteArray(env, thumbnail_data);
+ base::android::ScopedJavaLocalRef<jstring> j_extension =
+ base::android::ConvertUTF8ToJavaString(env, image_extension);
+ base::android::RunObjectCallbackAndroid(
+ jcallback, Java_ContextMenuHelper_createImageCallbackResult(env, j_data,
+ j_extension));
}
void OnRetrieveImageForContextMenu(
@@ -85,7 +111,8 @@
chrome_render_frame,
const base::android::JavaRef<jobject>& jcallback,
const std::vector<uint8_t>& thumbnail_data,
- const gfx::Size& original_size) {
+ const gfx::Size& original_size,
+ const std::string& filename_extension) {
ContextMenuHelperImageRequest::Start(jcallback, thumbnail_data);
}
@@ -178,9 +205,11 @@
const JavaParamRef<jobject>& obj,
const JavaParamRef<jobject>& jcallback,
jint max_width_px,
- jint max_height_px) {
+ jint max_height_px,
+ jint j_image_format) {
RetrieveImageInternal(env, base::Bind(&OnRetrieveImageForShare), jcallback,
- max_width_px, max_height_px);
+ max_width_px, max_height_px,
+ ToChromeMojomImageFormat(j_image_format));
}
void ContextMenuHelper::RetrieveImageForContextMenu(
@@ -189,8 +218,10 @@
const JavaParamRef<jobject>& jcallback,
jint max_width_px,
jint max_height_px) {
+ // For context menu, Image needs to be PNG for receiving transparency pixels.
RetrieveImageInternal(env, base::Bind(&OnRetrieveImageForContextMenu),
- jcallback, max_width_px, max_height_px);
+ jcallback, max_width_px, max_height_px,
+ chrome::mojom::ImageFormat::PNG);
}
void ContextMenuHelper::RetrieveImageInternal(
@@ -198,23 +229,25 @@
const ImageRetrieveCallback& retrieve_callback,
const JavaParamRef<jobject>& jcallback,
jint max_width_px,
- jint max_height_px) {
+ jint max_height_px,
+ chrome::mojom::ImageFormat image_format) {
content::RenderFrameHost* render_frame_host =
content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
if (!render_frame_host)
return;
-
mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> chrome_render_frame;
render_frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
&chrome_render_frame);
+
// Bind the InterfacePtr into the callback so that it's kept alive
// until there's either a connection error or a response.
auto* thumbnail_capturer_proxy = chrome_render_frame.get();
- thumbnail_capturer_proxy->RequestThumbnailForContextNode(
- 0, gfx::Size(max_width_px, max_height_px),
- chrome::mojom::ImageFormat::PNG,
- base::Bind(retrieve_callback, base::Passed(&chrome_render_frame),
- base::android::ScopedJavaGlobalRef<jobject>(env, jcallback)));
+ thumbnail_capturer_proxy->RequestImageForContextNode(
+ max_width_px * max_height_px, gfx::Size(max_width_px, max_height_px),
+ image_format,
+ base::BindOnce(
+ retrieve_callback, base::Passed(&chrome_render_frame),
+ base::android::ScopedJavaGlobalRef<jobject>(env, jcallback)));
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(ContextMenuHelper)
diff --git a/chrome/browser/ui/android/context_menu_helper.h b/chrome/browser/ui/android/context_menu_helper.h
index 71d645b..a9c86d52 100644
--- a/chrome/browser/ui/android/context_menu_helper.h
+++ b/chrome/browser/ui/android/context_menu_helper.h
@@ -24,6 +24,13 @@
class WebContents;
}
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.contextmenu
+enum ContextMenuImageFormat {
+ JPEG = 0,
+ PNG = 1,
+ ORIGINAL = 2,
+};
+
class ContextMenuHelper
: public content::WebContentsUserData<ContextMenuHelper> {
protected:
@@ -32,7 +39,8 @@
chrome_render_frame_ptr,
const base::android::JavaRef<jobject>& jcallback,
const std::vector<uint8_t>& thumbnail_data,
- const gfx::Size& max_dimen_px)>;
+ const gfx::Size& max_dimen_px,
+ const std::string& image_extension)>;
public:
~ContextMenuHelper() override;
@@ -53,30 +61,36 @@
const base::android::JavaParamRef<jobject>& obj,
jboolean jis_link,
jboolean jis_data_reduction_proxy_enabled);
+ void SearchForImage(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
void RetrieveImageForShare(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jobject>& jcallback,
jint max_width_px,
- jint max_height_px);
+ jint max_height_px,
+ jint j_image_type);
void RetrieveImageForContextMenu(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jobject>& jcallback,
jint max_width_px,
jint max_height_px);
+
+ private:
+ explicit ContextMenuHelper(content::WebContents* web_contents);
+ friend class content::WebContentsUserData<ContextMenuHelper>;
+
void RetrieveImageInternal(
JNIEnv* env,
const ImageRetrieveCallback& retrieve_callback,
const base::android::JavaParamRef<jobject>& jcallback,
jint max_width_px,
- jint max_height_px);
- void SearchForImage(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj);
+ jint max_height_px,
+ chrome::mojom::ImageFormat image_format);
- private:
- explicit ContextMenuHelper(content::WebContents* web_contents);
- friend class content::WebContentsUserData<ContextMenuHelper>;
+ mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame>
+ GetChromeRenderFrame() const;
base::android::ScopedJavaGlobalRef<jobject> java_obj_;
content::WebContents* web_contents_;