From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../org/mozilla/geckoview/WebPushController.java | 165 +++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java') diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java new file mode 100644 index 0000000000..f5ea153bfe --- /dev/null +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java @@ -0,0 +1,165 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * vim: ts=4 sw=4 expandtab: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.geckoview; + +import android.util.Log; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; +import org.mozilla.gecko.EventDispatcher; +import org.mozilla.gecko.GeckoThread; +import org.mozilla.gecko.util.BundleEventListener; +import org.mozilla.gecko.util.EventCallback; +import org.mozilla.gecko.util.GeckoBundle; +import org.mozilla.gecko.util.ThreadUtils; + +public class WebPushController { + private static final String LOGTAG = "WebPushController"; + + private WebPushDelegate mDelegate; + private BundleEventListener mEventListener; + + /* package */ WebPushController() { + mEventListener = new EventListener(); + EventDispatcher.getInstance() + .registerUiThreadListener( + mEventListener, + "GeckoView:PushSubscribe", + "GeckoView:PushUnsubscribe", + "GeckoView:PushGetSubscription"); + } + + /** + * Sets the {@link WebPushDelegate} for this instance. + * + * @param delegate The {@link WebPushDelegate} instance. + */ + @UiThread + public void setDelegate(final @Nullable WebPushDelegate delegate) { + ThreadUtils.assertOnUiThread(); + mDelegate = delegate; + } + + /** + * Gets the {@link WebPushDelegate} for this instance. + * + * @return delegate The {@link WebPushDelegate} instance. + */ + @UiThread + @Nullable + public WebPushDelegate getDelegate() { + ThreadUtils.assertOnUiThread(); + return mDelegate; + } + + /** + * Send a push event for a given subscription. + * + * @param scope The Service Worker scope associated with this subscription. + */ + @UiThread + public void onPushEvent(final @NonNull String scope) { + ThreadUtils.assertOnUiThread(); + onPushEvent(scope, null); + } + + /** + * Send a push event with a payload for a given subscription. + * + * @param scope The Service Worker scope associated with this subscription. + * @param data The unencrypted payload. + */ + @UiThread + public void onPushEvent(final @NonNull String scope, final @Nullable byte[] data) { + ThreadUtils.assertOnUiThread(); + + GeckoThread.waitForState(GeckoThread.State.JNI_READY) + .accept( + val -> { + final GeckoBundle msg = new GeckoBundle(2); + msg.putString("scope", scope); + msg.putString("data", Base64Utils.encode(data)); + EventDispatcher.getInstance().dispatch("GeckoView:PushEvent", msg); + }, + e -> Log.e(LOGTAG, "Unable to deliver Web Push message", e)); + } + + /** + * Notify that a given subscription has changed. This is normally a signal to the content that it + * needs to re-subscribe. + * + * @param scope The Service Worker scope associated with this subscription. + */ + @UiThread + public void onSubscriptionChanged(final @NonNull String scope) { + ThreadUtils.assertOnUiThread(); + + final GeckoBundle msg = new GeckoBundle(1); + msg.putString("scope", scope); + EventDispatcher.getInstance().dispatch("GeckoView:PushSubscriptionChanged", msg); + } + + private class EventListener implements BundleEventListener { + + @Override + public void handleMessage( + final String event, final GeckoBundle message, final EventCallback callback) { + if (mDelegate == null) { + callback.sendError("Not allowed"); + return; + } + + switch (event) { + case "GeckoView:PushSubscribe": + { + byte[] appServerKey = null; + if (message.containsKey("appServerKey")) { + appServerKey = Base64Utils.decode(message.getString("appServerKey")); + } + + final GeckoResult result = + mDelegate.onSubscribe(message.getString("scope"), appServerKey); + + if (result == null) { + callback.sendSuccess(null); + return; + } + + result.accept( + subscription -> + callback.sendSuccess(subscription != null ? subscription.toBundle() : null), + error -> callback.sendSuccess(null)); + break; + } + case "GeckoView:PushUnsubscribe": + { + final GeckoResult result = mDelegate.onUnsubscribe(message.getString("scope")); + if (result == null) { + callback.sendSuccess(null); + return; + } + + callback.resolveTo(result.map(val -> null)); + break; + } + case "GeckoView:PushGetSubscription": + { + final GeckoResult result = + mDelegate.onGetSubscription(message.getString("scope")); + if (result == null) { + callback.sendSuccess(null); + return; + } + + callback.resolveTo( + result.map(subscription -> subscription != null ? subscription.toBundle() : null)); + break; + } + } + } + } +} -- cgit v1.2.3