Commit 3691630d authored by Travis Skare's avatar Travis Skare Committed by Commit Bot

[QRCode Mobile] Generate QR bitmap via native service.

Change-Id: Ib13ad2a8d2300cf8de7d6cd0f2bb991d7c4f91e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132594
Commit-Queue: Travis Skare <skare@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768995}
parent fe6ae715
...@@ -6,6 +6,14 @@ source_set("share") { ...@@ -6,6 +6,14 @@ source_set("share") {
sources = [ sources = [
"features.cc", "features.cc",
"features.h", "features.h",
"qr_code_generation_request.cc",
"qr_code_generation_request.h",
]
deps = [
"//base",
"//chrome/browser/share/android:jni_headers",
"//chrome/services/qrcode_generator/public/cpp",
"//chrome/services/qrcode_generator/public/mojom",
"//skia",
] ]
deps = [ "//base" ]
} }
...@@ -9,6 +9,7 @@ include_rules = [ ...@@ -9,6 +9,7 @@ include_rules = [
"+chrome/android/java/src/org/chromium/chrome/browser/modules/ModuleInstallUi.java", "+chrome/android/java/src/org/chromium/chrome/browser/modules/ModuleInstallUi.java",
"+chrome/android/java/src/org/chromium/chrome/browser/screenshot/EditorScreenshotTask.java", "+chrome/android/java/src/org/chromium/chrome/browser/screenshot/EditorScreenshotTask.java",
"+chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java", "+chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java",
"+chrome/services/qrcode_generator",
"+content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java", "+content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java",
"+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java", "+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java",
"+chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java", "+chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java",
......
...@@ -20,3 +20,7 @@ android_resources("java_resources") { ...@@ -20,3 +20,7 @@ android_resources("java_resources") {
] ]
custom_package = "org.chromium.chrome.browser.share" custom_package = "org.chromium.chrome.browser.share"
} }
generate_jni("jni_headers") {
sources = [ "java/src/org/chromium/chrome/browser/share/qrcode/QRCodeGenerationRequest.java" ]
}
// 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.
package org.chromium.chrome.browser.share.qrcode;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
/**
* A Java API for calling the native QR Code Generator service.
*
* An instance of this class must be created, used, and destroyed on the same thread.
* Once created, this object will internally ensure that it stays alive until the QR code
* generation request succeeds/fails.
*/
public class QRCodeGenerationRequest {
// Pointer to the native request object.
private long mNativeQRCodeGenerationRequest;
// Stores the callback that will be invoked on request completion.
private QRCodeServiceCallback mCallback;
/**
* Callback for use with this class.
*/
public interface QRCodeServiceCallback {
/**
* Called when the QR Code is generated.
*
* @param bitmap The image, or null if none is available.
*/
void onQRCodeAvailable(@Nullable Bitmap bitmap);
}
/**
* Initializes the C++ side of this class and sends the request.
*
* @param data String of data for which to generate a code. If a URL, the caller should
* validate.
* @param callback The callback to run when a new code is available, or on error.
*/
public QRCodeGenerationRequest(String data, QRCodeServiceCallback callback) {
mCallback = callback;
mNativeQRCodeGenerationRequest =
QRCodeGenerationRequestJni.get().init(QRCodeGenerationRequest.this, data);
}
@CalledByNative
private void onQRCodeAvailable(@Nullable Bitmap bitmap) {
if (mCallback != null) {
mCallback.onQRCodeAvailable(bitmap);
mCallback = null;
}
if (mNativeQRCodeGenerationRequest != 0) {
QRCodeGenerationRequestJni.get().destroy(mNativeQRCodeGenerationRequest);
mNativeQRCodeGenerationRequest = 0;
}
}
@NativeMethods
interface Natives {
long init(QRCodeGenerationRequest caller, String data);
void destroy(long nativeQRCodeGenerationRequest);
}
}
...@@ -12,10 +12,13 @@ import android.view.View; ...@@ -12,10 +12,13 @@ import android.view.View;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.share.SaveImageNotificationManager; import org.chromium.chrome.browser.share.SaveImageNotificationManager;
import org.chromium.chrome.browser.share.ShareImageFileUtils; import org.chromium.chrome.browser.share.ShareImageFileUtils;
import org.chromium.chrome.browser.share.qrcode.QRCodeGenerationRequest;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.widget.Toast; import org.chromium.ui.widget.Toast;
import org.chromium.url.GURL;
/** /**
* QrCodeShareMediator is in charge of calculating and setting values for QrCodeShareViewProperties. * QrCodeShareMediator is in charge of calculating and setting values for QrCodeShareViewProperties.
...@@ -29,6 +32,7 @@ class QrCodeShareMediator implements ShareImageFileUtils.OnImageSaveListener { ...@@ -29,6 +32,7 @@ class QrCodeShareMediator implements ShareImageFileUtils.OnImageSaveListener {
private long mDownloadStartTime; private long mDownloadStartTime;
private boolean mIsDownloadInProgress; private boolean mIsDownloadInProgress;
/** /**
* The QrCodeScanMediator constructor. * The QrCodeScanMediator constructor.
* @param context The context to use. * @param context The context to use.
...@@ -38,8 +42,28 @@ class QrCodeShareMediator implements ShareImageFileUtils.OnImageSaveListener { ...@@ -38,8 +42,28 @@ class QrCodeShareMediator implements ShareImageFileUtils.OnImageSaveListener {
mContext = context; mContext = context;
mPropertyModel = propertyModel; mPropertyModel = propertyModel;
// TODO(gayane): Request generated QR code bitmap with a callback that sets QRCODE_BITMAP if (context instanceof ChromeActivity) {
// property. GURL url = ((ChromeActivity) context).getActivityTabProvider().get().getUrl();
refreshQrCode(url.getSpec());
}
}
/**
* Refreshes the QR Code bitmap for given data.
* @param data The data to encode.
*/
protected void refreshQrCode(String data) {
QRCodeGenerationRequest.QRCodeServiceCallback callback =
new QRCodeGenerationRequest.QRCodeServiceCallback() {
@Override
public void onQRCodeAvailable(Bitmap bitmap) {
// TODO(skare): If bitmap is null, surface an error.
if (bitmap != null) {
mPropertyModel.set(QrCodeShareViewProperties.QRCODE_BITMAP, bitmap);
}
}
};
new QRCodeGenerationRequest(data, callback);
} }
/** Triggers download for the generated QR code bitmap if available. */ /** Triggers download for the generated QR code bitmap if available. */
......
...@@ -8,6 +8,7 @@ share_java_sources = [ ...@@ -8,6 +8,7 @@ share_java_sources = [
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/SaveImageNotificationManager.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ShareImageFileUtils.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ShareImageFileUtils.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/clipboard/ClipboardImageFileProvider.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/clipboard/ClipboardImageFileProvider.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QRCodeGenerationRequest.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeDialog.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeDialog.java",
"//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeDialogTab.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeDialogTab.java",
......
// 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/share/qr_code_generation_request.h"
#include <jni.h>
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/share/android/jni_headers/QRCodeGenerationRequest_jni.h"
#include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/android/java_bitmap.h"
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaGlobalRef;
using base::android::ScopedJavaLocalRef;
QRCodeGenerationRequest::QRCodeGenerationRequest(
JNIEnv* env,
const JavaParamRef<jobject>& j_caller,
const JavaParamRef<jstring>& j_data_string)
: java_qr_code_generation_request_(j_caller) {
std::string url_string(ConvertJavaStringToUTF8(env, j_data_string));
qrcode_generator::mojom::GenerateQRCodeRequestPtr request =
qrcode_generator::mojom::GenerateQRCodeRequest::New();
request->data = url_string;
request->should_render = true;
request->render_dino = true;
request->render_module_style = qrcode_generator::mojom::ModuleStyle::CIRCLES;
request->render_locator_style =
qrcode_generator::mojom::LocatorStyle::ROUNDED;
remote_ = qrcode_generator::LaunchQRCodeGeneratorService();
// On RPC error, we will still run the handler with a null bitmap.
// The handler will call destroy() on this native object to clean up.
// base::Unretained(this) is safe here because the callback won't be invoked
// after |remote_| is destroyed, and |remote_| will be destroyed if this
// object is destroyed.
// TODO(skare): Reenable this handler.
/*
remote_.set_disconnect_handler(
base::BindOnce(&QRCodeGenerationRequest::OnGenerateCodeResponse,
base::Unretained(this), nullptr));
*/
auto callback = base::BindOnce(
&QRCodeGenerationRequest::OnGenerateCodeResponse, base::Unretained(this));
remote_.get()->GenerateQRCode(std::move(request), std::move(callback));
}
QRCodeGenerationRequest::~QRCodeGenerationRequest() {}
void QRCodeGenerationRequest::Destroy(JNIEnv* env) {
delete this;
}
void QRCodeGenerationRequest::OnGenerateCodeResponse(
const qrcode_generator::mojom::GenerateQRCodeResponsePtr service_response) {
JNIEnv* env = base::android::AttachCurrentThread();
if (service_response->error_code !=
qrcode_generator::mojom::QRCodeGeneratorError::NONE) {
Java_QRCodeGenerationRequest_onQRCodeAvailable(
env, java_qr_code_generation_request_, nullptr);
return;
}
// Convert the result to a Java Bitmap.
ScopedJavaLocalRef<jobject> java_bitmap =
gfx::ConvertToJavaBitmap(&service_response->bitmap);
Java_QRCodeGenerationRequest_onQRCodeAvailable(
env, java_qr_code_generation_request_, java_bitmap);
}
static jlong JNI_QRCodeGenerationRequest_Init(
JNIEnv* env,
const JavaParamRef<jobject>& j_caller,
const JavaParamRef<jstring>& j_data_string) {
return reinterpret_cast<intptr_t>(
new QRCodeGenerationRequest(env, j_caller, j_data_string));
}
// 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_SHARE_QR_CODE_GENERATION_REQUEST_H_
#define CHROME_BROWSER_SHARE_QR_CODE_GENERATION_REQUEST_H_
#include <jni.h>
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
#include "chrome/services/qrcode_generator/public/cpp/qrcode_generator_service.h"
#include "ui/gfx/android/java_bitmap.h"
// A wrapper class exposing the QR Code Mojo service to Java.
class QRCodeGenerationRequest {
public:
QRCodeGenerationRequest(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_caller,
const base::android::JavaParamRef<jstring>& j_data_string);
void Destroy(JNIEnv* env);
private:
virtual ~QRCodeGenerationRequest();
void OnGenerateCodeResponse(
const qrcode_generator::mojom::GenerateQRCodeResponsePtr
service_response);
// Reference to Java QRCodeGenerationRequest containing a callback method.
base::android::ScopedJavaGlobalRef<jobject> java_qr_code_generation_request_;
mojo::Remote<qrcode_generator::mojom::QRCodeGeneratorService> remote_;
DISALLOW_COPY_AND_ASSIGN(QRCodeGenerationRequest);
};
#endif // CHROME_BROWSER_SHARE_QR_CODE_GENERATION_REQUEST_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment