Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues from web payments branch #142

Draft
wants to merge 8 commits into
base: web-payments
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ void InstallablePaymentAppCrawler::OnPaymentMethodManifestParsed(
url::Origin::Create(web_app_manifest_url))
.status != blink::mojom::PermissionStatus::GRANTED) {
// Do not download the web app manifest if it is blocked.
VLOG(0) << "InstallablePaymentAppCrawler::OnPaymentMethodManifestParsed -- Payment Handler permission denied !";
number_of_web_app_manifest_to_download_--;
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,12 @@ public boolean needToFireBeforeUnloadOrUnloadEvents() {
.needToFireBeforeUnloadOrUnloadEvents(mNativeWebContentsAndroid);
}

@Override
public void notifyOnCreateNewPaymentHandler(WebContents newWebContents) {
checkNotDestroyed();
if (mObserverProxy != null) mObserverProxy.onCreateNewPaymentHandler(newWebContents);
}

public void addTearDownDialogOverlaysHandler(Runnable handler) {
if (mTearDownDialogOverlaysHandlers == null) {
mTearDownDialogOverlaysHandlers = new ObserverList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.chromium.content_public.browser.LifecycleState;
import org.chromium.content_public.browser.LoadCommittedDetails;
import org.chromium.content_public.browser.NavigationHandle;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.mojom.VirtualKeyboardMode;
Expand Down Expand Up @@ -477,6 +478,16 @@ public void onTopLevelNativeWindowChanged(WindowAndroid windowAndroid) {
finishObserverCall();
}

@Override
public void onCreateNewPaymentHandler(WebContents newWebContents) {
handleObserverCall();
Iterator<WebContentsObserver> observersIterator = mObservers.iterator();
for (; observersIterator.hasNext(); ) {
observersIterator.next().onCreateNewPaymentHandler(newWebContents);
}
finishObserverCall();
}

@Override
@CalledByNative
public void destroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -590,4 +590,11 @@ int downloadImage(
* an unload/pagehide/visibilitychange handler.
*/
boolean needToFireBeforeUnloadOrUnloadEvents();

/**
* Notify that the new {@link WebContents} for the payment handler is created.
*
* @param newWebContents The new {@link WebContents} for the payment handler.
*/
void notifyOnCreateNewPaymentHandler(WebContents newWebContents);
}
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ public void onWebContentsLostFocus() {}
/** Called when the top level WindowAndroid changes. */
public void onTopLevelNativeWindowChanged(@Nullable WindowAndroid windowAndroid) {}

/**
* Called when the payment handler's WebContents is created.
* @param newWebContents the new WebContents for the payment handler.
*/
public void onCreateNewPaymentHandler(WebContents newWebContents) {}

/** Stop observing the web contents and clean up associated references. */
public void destroy() {
if (mWebContents == null) return;
Expand Down
25 changes: 25 additions & 0 deletions wolvic/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ shared_library("libcontent_native") {
"browser/metrics/wolvic_enabled_state_provider.h",
"browser/mojo/wolvic_interface_registrar.cc",
"browser/mojo/wolvic_interface_registrar.h",
"browser/payments/service_worker_payment_app_bridge.cc",
"browser/session_settings.cc",
"browser/session_settings.h",
"browser/session_settings_jni.cc",
Expand Down Expand Up @@ -92,6 +93,8 @@ shared_library("libcontent_native") {
"browser/wolvic_contents.h",
"browser/wolvic_web_contents_delegate.cc",
"browser/wolvic_web_contents_delegate.h",
"browser/service_tab_launcher.cc",
"browser/service_tab_launcher.h",
"renderer/browser_exposed_renderer_interfaces.cc",
"renderer/browser_exposed_renderer_interfaces.h",
"renderer/wolvic_content_renderer_client.cc",
Expand All @@ -115,6 +118,8 @@ shared_library("libcontent_native") {
deps = [
":content_native_lib",
":jni_headers",
"//components/page_info/android",
"//components/payments/content/android",
"//components/webdata_services",
"//components/crash/content/browser",
"//components/zoom",
Expand Down Expand Up @@ -317,6 +322,8 @@ generate_jni("jni_headers") {
"java/org/chromium/wolvic/WolvicWebContentsDelegate.java",
"java/org/chromium/wolvic/WolvicWebContentsFactory.java",
"java/org/chromium/wolvic/mojo/WolvicInterfaceRegistrar.java",
"java/org/chromium/wolvic/ServiceTabLauncher.java",
"java/org/chromium/wolvic/payments/ServiceWorkerPaymentAppBridge.java",
]
}

Expand All @@ -342,18 +349,31 @@ android_library("wolvic_java") {
"java/org/chromium/wolvic/WolvicWebContentsFactory.java",
"java/org/chromium/wolvic/installedapp/WolvicInstalledAppProviderFactory.java",
"java/org/chromium/wolvic/mojo/WolvicInterfaceRegistrar.java",
"java/org/chromium/wolvic/ServiceTabLauncher.java",
"java/org/chromium/wolvic/payments/ServiceWorkerPaymentAppBridge.java",
"java/org/chromium/wolvic/payments/WolvicPaymentRequestFactory.java",
"java/org/chromium/wolvic/payments/WolvicPaymentRequestService.java",
"java/org/chromium/wolvic/payments/WolvicPaymentResponseHelper.java",
"java/org/chromium/wolvic/payments/ui/WolvicPaymentUiService.java",
]
srcjar_deps = [ ":jni_headers" ]
deps = [
"//base:base_java",
"//base/version_info/android:version_constants_java",
"//build/android:build_java",
"//components/autofill/android:main_autofill_java",
"//components/embedder_support/android:content_view_java",
"//components/embedder_support/android:view_java",
"//components/embedder_support/android:web_contents_delegate_java",
"//components/installedapp/android:java",
"//components/url_formatter/android:url_formatter_java",
"//content/public/android:content_full_java",
"//content/public/android:content_main_dex_java",
"//content/public/android:content_java",
"//components/autofill/android:payments_autofill_java",
"//components/payments/content/android:java",
"//components/payments/content/android:service_java",
"//components/payments/mojom:mojom_java",
"//mojo/public/java:bindings_java",
"//services/service_manager/public/java:service_manager_java",
"//third_party/androidx:androidx_annotation_annotation_java",
Expand All @@ -363,6 +383,7 @@ android_library("wolvic_java") {
"//third_party/jni_zero:jni_zero_java",
"//ui/android:ui_full_java",
"//ui/android:ui_no_recycler_view_java",
"//ui/base/mojom:mojom_java",
"//url:gurl_java",
]
}
Expand Down Expand Up @@ -402,12 +423,15 @@ dist_aar("content_aar") {
"org/chromium/base/*.class",
"org/chromium/blink/mojom/*.class",
"org/chromium/build/*.class",
"org/chromium/components/autofill/*.class",
"org/chromium/components/browser_ui/media/*.class",
"org/chromium/components/download/*.class",
"org/chromium/components/embedder_support/*.class",
"org/chromium/components/externalauth/*.class",
"org/chromium/components/installedapp/*.class",
"org/chromium/components/metrics/*.class",
"org/chromium/components/page_info/*.class",
"org/chromium/components/payments/*.class",
"org/chromium/components/signin/*.class",
"org/chromium/components/signin/identitymanager/*.class",
"org/chromium/components/url_formatter/*.class",
Expand All @@ -426,6 +450,7 @@ dist_aar("content_aar") {
"org/chromium/mojo/bindings/*.class",
"org/chromium/mojo/system/*.class",
"org/chromium/net/*.class",
"org/chromium/payments/mojom/*.class",
"org/chromium/service_manager/mojom/*.class",
"org/chromium/services/*.class",
"org/chromium/ui/touch_selection/*.class",
Expand Down
133 changes: 133 additions & 0 deletions wolvic/browser/payments/service_worker_payment_app_bridge.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/scoped_java_ref.h"
#include "base/functional/bind.h"
#include "components/payments/content/service_worker_payment_app_finder.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/payment_app_provider.h"
#include "content/public/browser/payment_app_provider_util.h"
#include "wolvic/jni_headers/ServiceWorkerPaymentAppBridge_jni.h"
#include "ui/gfx/android/java_bitmap.h"
#include "url/android/gurl_android.h"

namespace {

using ::base::android::AttachCurrentThread;
using ::base::android::ConvertJavaStringToUTF8;
using ::base::android::ConvertUTF8ToJavaString;
using ::base::android::JavaParamRef;
using ::base::android::JavaRef;
using ::base::android::ScopedJavaGlobalRef;
using ::base::android::ScopedJavaLocalRef;

void OnHasServiceWorkerPaymentAppsResponse(
const JavaRef<jobject>& jcallback,
content::InstalledPaymentAppsFinder::PaymentApps apps) {
JNIEnv* env = AttachCurrentThread();

Java_ServiceWorkerPaymentAppBridge_onHasServiceWorkerPaymentApps(
env, jcallback, apps.size() > 0);
}

void OnGetServiceWorkerPaymentAppsInfo(
const JavaRef<jobject>& jcallback,
content::InstalledPaymentAppsFinder::PaymentApps apps) {
JNIEnv* env = AttachCurrentThread();

base::android::ScopedJavaLocalRef<jobject> jappsInfo =
Java_ServiceWorkerPaymentAppBridge_createPaymentAppsInfo(env);

for (const auto& app_info : apps) {
Java_ServiceWorkerPaymentAppBridge_addPaymentAppInfo(
env, jappsInfo,
ConvertUTF8ToJavaString(env, app_info.second->scope.host()),
ConvertUTF8ToJavaString(env, app_info.second->name),
app_info.second->icon == nullptr
? nullptr
: gfx::ConvertToJavaBitmap(*app_info.second->icon));
}

Java_ServiceWorkerPaymentAppBridge_onGetServiceWorkerPaymentAppsInfo(
env, jcallback, jappsInfo);
}

} // namcespace


static void JNI_ServiceWorkerPaymentAppBridge_HasServiceWorkerPaymentApps(
JNIEnv* env,
const JavaParamRef<jobject>& payment_request_jweb_contents,
const JavaParamRef<jobject>& jcallback) {
// Checks whether there is a installed service worker payment app through
// GetAllPaymentApps.
// TODO(jfernandez): Address properly the depdency on Profile may be a problem.
// BrowserContext* browser_context = ProfileManager::GetActiveUserProfile();
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(payment_request_jweb_contents);
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
content::InstalledPaymentAppsFinder::GetInstance(browser_context)
->GetAllPaymentApps(
base::BindOnce(&OnHasServiceWorkerPaymentAppsResponse,
ScopedJavaGlobalRef<jobject>(env, jcallback)));
}

static void JNI_ServiceWorkerPaymentAppBridge_GetServiceWorkerPaymentAppsInfo(
JNIEnv* env,
const JavaParamRef<jobject>& payment_request_jweb_contents,
const JavaParamRef<jobject>& jcallback) {
// TODO(jfernandez): Address properly the depdency on Profile may be a problem.
// BrowserContext* browser_context = ProfileManager::GetActiveUserProfile();
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(payment_request_jweb_contents);
content::BrowserContext* browser_context = web_contents->GetBrowserContext();
content::InstalledPaymentAppsFinder::GetInstance(browser_context)
->GetAllPaymentApps(
base::BindOnce(&OnGetServiceWorkerPaymentAppsInfo,
ScopedJavaGlobalRef<jobject>(env, jcallback)));
}

static void JNI_ServiceWorkerPaymentAppBridge_OnClosingPaymentAppWindow(
JNIEnv* env,
const JavaParamRef<jobject>& payment_request_jweb_contents,
jint reason) {
content::WebContents* payment_request_web_contents =
content::WebContents::FromJavaWebContents(payment_request_jweb_contents);
DCHECK(payment_request_web_contents); // Verified in Java before invoking
// this function.
content::PaymentAppProvider::GetOrCreateForWebContents(
payment_request_web_contents)
->OnClosingOpenedWindow(
static_cast<payments::mojom::PaymentEventResponseType>(reason));
}

static void JNI_ServiceWorkerPaymentAppBridge_OnOpeningPaymentAppWindow(
JNIEnv* env,
const JavaParamRef<jobject>& payment_request_jweb_contents,
const JavaParamRef<jobject>& payment_handler_jweb_contents) {
content::WebContents* payment_request_web_contents =
content::WebContents::FromJavaWebContents(payment_request_jweb_contents);
content::WebContents* payment_handler_web_contents =
content::WebContents::FromJavaWebContents(payment_handler_jweb_contents);
DCHECK(payment_request_web_contents); // Verified in Java before invoking
// this function.
DCHECK(payment_handler_web_contents); // Verified in Java before invoking
// this function.
content::PaymentAppProvider::GetOrCreateForWebContents(
payment_request_web_contents)
->SetOpenedWindow(payment_handler_web_contents);
}

static jlong
JNI_ServiceWorkerPaymentAppBridge_GetSourceIdForPaymentAppFromScope(
JNIEnv* env,
const JavaParamRef<jobject>& jscope) {
// At this point we know that the payment handler window is open for the
// payment app associated with this scope. Since this getter is called inside
// PaymentApp::getUkmSourceId() function which in turn gets called for the
// invoked app inside
// ChromePaymentRequestService::openPaymentHandlerWindowInternal.
return content::PaymentAppProviderUtil::GetSourceIdForPaymentAppFromScope(
url::GURLAndroid::ToNativeGURL(env, jscope)
.get()
->DeprecatedGetOriginAsURL());
}
72 changes: 72 additions & 0 deletions wolvic/browser/service_tab_launcher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "wolvic/browser/service_tab_launcher.h"

#include "base/android/jni_string.h"
#include "base/functional/callback.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/web_contents.h"
#include "url/android/gurl_android.h"
#include "wolvic/jni_headers/ServiceTabLauncher_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;

// Called by Java when the WebContents instance for a request Id is available.
void JNI_ServiceTabLauncher_OnWebContentsForRequestAvailable(
JNIEnv* env,
jint request_id,
const JavaParamRef<jobject>& android_web_contents) {
ServiceTabLauncher::GetInstance()->OnTabLaunched(
request_id,
content::WebContents::FromJavaWebContents(android_web_contents));
}

// static
ServiceTabLauncher* ServiceTabLauncher::GetInstance() {
return base::Singleton<ServiceTabLauncher>::get();
}

ServiceTabLauncher::ServiceTabLauncher() {}
ServiceTabLauncher::~ServiceTabLauncher() {}

void ServiceTabLauncher::LaunchTab(content::BrowserContext* browser_context,
const content::OpenURLParams& params,
TabLaunchedCallback callback) {
WindowOpenDisposition disposition = params.disposition;
if (disposition != WindowOpenDisposition::NEW_POPUP) {
// ServiceTabLauncher can currently only launch new tabs.
NOTIMPLEMENTED();
return;
}

JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> referrer_url =
ConvertUTF8ToJavaString(env, params.referrer.url.spec());
ScopedJavaLocalRef<jstring> headers = ConvertUTF8ToJavaString(
env, params.extra_headers);

ScopedJavaLocalRef<jobject> post_data;

// IDMap requires a pointer, so we move |callback| into a heap pointer.
int request_id = tab_launched_callbacks_.Add(
std::make_unique<TabLaunchedCallback>(std::move(callback)));
DCHECK_GE(request_id, 1);

Java_ServiceTabLauncher_launchTab(
env, request_id, browser_context->IsOffTheRecord(),
url::GURLAndroid::FromNativeGURL(env, params.url),
static_cast<int>(disposition), referrer_url,
static_cast<int>(params.referrer.policy), headers, post_data);
}

void ServiceTabLauncher::OnTabLaunched(int request_id,
content::WebContents* web_contents) {
TabLaunchedCallback* callback = tab_launched_callbacks_.Lookup(request_id);
// TODO(crbug.com/962873): The Lookup() can fail though we don't expect that
// it should be able to. It would be nice if this was a DCHECK() instead.
if (callback)
std::move(*callback).Run(web_contents);
tab_launched_callbacks_.Remove(request_id);
}
Loading