[VCN][M2] Upstream enrollment dialog

This CL creates a parallel flow for upstream enrollment in which the enrollment info is shown in a dialog instead of an infobar.

The dialog is reused from crrev.com/c/3455322.
This CL follows the new recommended way to implement view/controller JNI interfaces documented here (https://docs.google.com/document/d/1J19BNafBk90mSzQnAjykguROCDK8ZzYiUVi3Uwj_5jg/edit?resourcekey=0-QT0PzlbhCbjNFoAaSe4_qg#heading=h.subvi3olnqaf).
Screen record of the upstream flow: https://drive.google.com/file/d/1oUNacjoNAZOPhX890zEsu5nBUILU5Sao/view?usp=sharing&resourcekey=0-qzoH3eu2-jJoUZvxpBGyQA

Bug: 1281695, 1306021

Change-Id: Ifb860cf891725986dece9c5865773d20b9474f03
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3610789
Reviewed-by: Siyu An <[email protected]>
Reviewed-by: Elizabeth Popova <[email protected]>
Reviewed-by: David Trainor <[email protected]>
Reviewed-by: Evan Stade <[email protected]>
Commit-Queue: Vishwas Uppoor <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1000581}
diff --git a/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.cc b/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.cc
new file mode 100644
index 0000000..eb7e393
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.cc
@@ -0,0 +1,75 @@
+// Copyright 2022 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/android/autofill/virtual_card_enrollment_view_android.h"
+
+#include <jni.h>
+#include "base/android/jni_string.h"
+#include "chrome/android/chrome_jni_headers/VirtualCardEnrollmentDialogViewBridge_jni.h"
+#include "chrome/browser/ui/android/autofill/virtual_card_utils.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/android/view_android.h"
+#include "ui/android/window_android.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace autofill {
+
+VirtualCardEnrollmentViewAndroid::VirtualCardEnrollmentViewAndroid() = default;
+
+VirtualCardEnrollmentViewAndroid::~VirtualCardEnrollmentViewAndroid() = default;
+
+AutofillBubbleBase* VirtualCardEnrollmentViewAndroid::CreateAndShow(
+    content::WebContents* web_contents,
+    VirtualCardEnrollBubbleController* controller) {
+  VirtualCardEnrollmentViewAndroid* view =
+      new VirtualCardEnrollmentViewAndroid();
+  if (view->Show(web_contents, controller)) {
+    return view;
+  }
+  delete view;
+  return nullptr;
+}
+
+void VirtualCardEnrollmentViewAndroid::Hide() {
+  if (java_view_bridge_) {
+    Java_VirtualCardEnrollmentDialogViewBridge_dismiss(
+        base::android::AttachCurrentThread(), java_view_bridge_);
+  }
+}
+
+bool VirtualCardEnrollmentViewAndroid::Show(
+    content::WebContents* web_contents,
+    VirtualCardEnrollBubbleController* controller) {
+  JNIEnv* env = base::android::AttachCurrentThread();
+  if (web_contents->GetNativeView() == nullptr ||
+      web_contents->GetNativeView()->GetWindowAndroid() == nullptr) {
+    return false;  // No window attached (yet or anymore).
+  }
+  VirtualCardEnrollmentFields fields =
+      controller->GetVirtualCardEnrollmentFields();
+  ui::ViewAndroid* view_android = web_contents->GetNativeView();
+  if (java_view_bridge_) {
+    Hide();
+  }
+  java_view_bridge_.Reset(Java_VirtualCardEnrollmentDialogViewBridge_create(
+      env,
+      base::android::ConvertUTF16ToJavaString(
+          env, controller->GetAcceptButtonText()),
+      base::android::ConvertUTF16ToJavaString(
+          env, controller->GetDeclineButtonText()),
+      controller->GetOrCreateJavaDelegate(),
+      autofill::CreateVirtualCardEnrollmentFieldsJavaObject(&fields),
+      view_android->GetWindowAndroid()->GetJavaObject()));
+  if (java_view_bridge_) {
+    Java_VirtualCardEnrollmentDialogViewBridge_showDialog(env,
+                                                          java_view_bridge_);
+    return true;
+  }
+  return false;
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.h b/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.h
new file mode 100644
index 0000000..4ee0282
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/virtual_card_enrollment_view_android.h
@@ -0,0 +1,46 @@
+// Copyright 2022 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_ANDROID_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_VIEW_ANDROID_H_
+#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_VIEW_ANDROID_H_
+
+#include "base/android/scoped_java_ref.h"
+#include "chrome/browser/ui/autofill/autofill_bubble_base.h"
+#include "components/autofill/core/browser/ui/payments/virtual_card_enroll_bubble_controller.h"
+
+namespace content {
+class WebContents;
+}
+
+namespace autofill {
+
+// Implements AutofillBubbleBase for displaying the Android view. This view
+// class is created when the user info is to be shown in the virtual card
+// enrollment flow, and is destroyed when the Android view gets dismissed either
+// by the user or by the native controller.
+class VirtualCardEnrollmentViewAndroid final : public AutofillBubbleBase {
+ public:
+  ~VirtualCardEnrollmentViewAndroid();
+
+  // AutofillBubbleBase:
+  void Hide() override;
+
+  // Factory function for creating and showing the view.
+  static AutofillBubbleBase* CreateAndShow(
+      content::WebContents* web_contents,
+      VirtualCardEnrollBubbleController* controller);
+
+ private:
+  VirtualCardEnrollmentViewAndroid();
+
+  bool Show(content::WebContents* web_contents,
+            VirtualCardEnrollBubbleController* controller);
+
+  // This class's corresponding java object.
+  base::android::ScopedJavaGlobalRef<jobject> java_view_bridge_;
+};
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_ANDROID_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_VIEW_ANDROID_H_
diff --git a/chrome/browser/ui/android/autofill/virtual_card_utils.cc b/chrome/browser/ui/android/autofill/virtual_card_utils.cc
new file mode 100644
index 0000000..7f1b795f
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/virtual_card_utils.cc
@@ -0,0 +1,59 @@
+// Copyright 2022 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/android/autofill/virtual_card_utils.h"
+
+#include "base/android/jni_string.h"
+#include "chrome/android/chrome_jni_headers/VirtualCardEnrollmentFields_jni.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ScopedJavaLocalRef;
+
+namespace autofill {
+
+ScopedJavaLocalRef<jobject> CreateVirtualCardEnrollmentFieldsJavaObject(
+    autofill::VirtualCardEnrollmentFields* virtual_card_enrollment_fields) {
+  JNIEnv* env = AttachCurrentThread();
+  // Create VirtualCardEnrollmentFields java object.
+  ScopedJavaLocalRef<jobject> java_object =
+      Java_VirtualCardEnrollmentFields_create(
+          env,
+          ConvertUTF16ToJavaString(
+              env, virtual_card_enrollment_fields->credit_card
+                       .CardIdentifierStringForAutofillDisplay()),
+          gfx::ConvertToJavaBitmap(
+              *virtual_card_enrollment_fields->card_art_image->bitmap()));
+  // Add Google legal messages.
+  for (const auto& legal_message_line :
+       virtual_card_enrollment_fields->google_legal_message) {
+    Java_VirtualCardEnrollmentFields_addGoogleLegalMessageLine(
+        env, java_object,
+        ConvertUTF16ToJavaString(env, legal_message_line.text()));
+    for (const auto& link : legal_message_line.links()) {
+      Java_VirtualCardEnrollmentFields_addLinkToLastGoogleLegalMessageLine(
+          env, java_object, link.range.start(), link.range.end(),
+          ConvertUTF8ToJavaString(env, link.url.spec()));
+    }
+  }
+  // Add issuer legal messages.
+  for (const auto& legal_message_line :
+       virtual_card_enrollment_fields->issuer_legal_message) {
+    Java_VirtualCardEnrollmentFields_addIssuerLegalMessageLine(
+        env, java_object,
+        ConvertUTF16ToJavaString(env, legal_message_line.text()));
+    for (const auto& link : legal_message_line.links()) {
+      Java_VirtualCardEnrollmentFields_addLinkToLastIssuerLegalMessageLine(
+          env, java_object, link.range.start(), link.range.end(),
+          ConvertUTF8ToJavaString(env, link.url.spec()));
+    }
+  }
+  return java_object;
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/virtual_card_utils.h b/chrome/browser/ui/android/autofill/virtual_card_utils.h
new file mode 100644
index 0000000..f50e146
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/virtual_card_utils.h
@@ -0,0 +1,22 @@
+// Copyright 2022 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_ANDROID_AUTOFILL_VIRTUAL_CARD_UTILS_H_
+#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_VIRTUAL_CARD_UTILS_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+#include "components/autofill/core/browser/payments/virtual_card_enrollment_manager.h"
+
+namespace autofill {
+
+// Converts VirtualCardEnrollmentFields native object to it's Java counterpart.
+base::android::ScopedJavaLocalRef<jobject>
+CreateVirtualCardEnrollmentFieldsJavaObject(
+    autofill::VirtualCardEnrollmentFields* virtual_card_enrollment_fields);
+
+}  // namespace autofill
+
+#endif  // CHROME_BROWSER_UI_ANDROID_AUTOFILL_VIRTUAL_CARD_UTILS_H_