/* 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.os.Parcel; import android.os.ParcelFormatException; import android.os.Parcelable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.annotation.WrapForJNI; import org.mozilla.gecko.util.ThreadUtils; /** * This class represents a single Web Notification. These * can be received by connecting a {@link WebNotificationDelegate} to {@link GeckoRuntime} via * {@link GeckoRuntime#setWebNotificationDelegate(WebNotificationDelegate)}. */ public class WebNotification implements Parcelable { /** * Title is shown at the top of the notification window. * * @see Web * Notification - title */ public final @Nullable String title; /** * Tag is the ID of the notification. * * @see Web * Notification - tag */ public final @NonNull String tag; private final @Nullable String mCookie; /** * Text represents the body of the notification. * * @see Web * Notification - text */ public final @Nullable String text; /** * ImageURL contains the URL of an icon to be displayed as part of the notification. * * @see Web * Notification - icon */ public final @Nullable String imageUrl; /** * TextDirection indicates the direction that the language of the text is displayed. Possible * values are: auto: adopts the browser's language setting behaviour (the default.) ltr: left to * right. rtl: right to left. * * @see Web * Notification - dir */ public final @Nullable String textDirection; /** * Lang indicates the notification's language, as specified using a DOMString representing a BCP * 47 language tag. * * @see DOM String * @see BCP 47 * @see Web * Notification - lang */ public final @Nullable String lang; /** * RequireInteraction indicates whether a notification should remain active until the user clicks * or dismisses it, rather than closing automatically. * * @see Web * Notification - requireInteraction */ public final @NonNull boolean requireInteraction; /** * This is the URL of the page or Service Worker that generated the notification. Null if this * notification was not generated by a Web Page (e.g. from an Extension). * *

TODO: make NonNull once we have Bug 1589693 */ public final @Nullable String source; /** * When set, indicates that no sounds or vibrations should be made. * * @see Web * Notification - silent */ public final boolean silent; /** indicates whether the notification came from private browsing mode or not. */ public final boolean privateBrowsing; /** * A vibration pattern to run with the display of the notification. A vibration pattern can be an * array with as few as one member. The values are times in milliseconds where the even indices * (0, 2, 4, etc.) indicate how long to vibrate and the odd indices indicate how long to pause. * For example, [300, 100, 400] would vibrate 300ms, pause 100ms, then vibrate 400ms. * * @see Web * Notification - vibrate */ public final @NonNull int[] vibrate; @WrapForJNI /* package */ WebNotification( @Nullable final String title, @NonNull final String tag, @Nullable final String cookie, @Nullable final String text, @Nullable final String imageUrl, @Nullable final String textDirection, @Nullable final String lang, @NonNull final boolean requireInteraction, @NonNull final String source, final boolean silent, final boolean privateBrowsing, @NonNull final int[] vibrate) { this.tag = tag; this.mCookie = cookie; this.title = title; this.text = text; this.imageUrl = imageUrl; this.textDirection = textDirection; this.lang = lang; this.requireInteraction = requireInteraction; this.source = "".equals(source) ? null : source; this.silent = silent; this.vibrate = vibrate; this.privateBrowsing = privateBrowsing; } /** * This should be called when the user taps or clicks a notification. Note that this does not * automatically dismiss the notification as far as Web Content is concerned. For that, see {@link * #dismiss()}. */ @UiThread public void click() { ThreadUtils.assertOnUiThread(); GeckoAppShell.onNotificationClick(tag, mCookie); } /** * This should be called when the app stops showing the notification. This is important, as there * may be a limit to the number of active notifications each site can display. */ @UiThread public void dismiss() { ThreadUtils.assertOnUiThread(); GeckoAppShell.onNotificationClose(tag, mCookie); } // Increment this value whenever anything changes in the parcelable representation. private static final int VERSION = 1; // To avoid TransactionTooLargeException, we only store small imageUrls private static final int IMAGE_URL_LENGTH_MAX = 150; @Override public int describeContents() { return 0; } @Override public void writeToParcel(final Parcel dest, final int flags) { dest.writeInt(VERSION); dest.writeString(title); dest.writeString(tag); dest.writeString(mCookie); dest.writeString(text); if (imageUrl.length() < IMAGE_URL_LENGTH_MAX) { dest.writeString(imageUrl); } else { dest.writeString(""); } dest.writeString(textDirection); dest.writeString(lang); dest.writeInt(requireInteraction ? 1 : 0); dest.writeString(source); dest.writeInt(silent ? 1 : 0); dest.writeInt(privateBrowsing ? 1 : 0); dest.writeIntArray(vibrate); } private WebNotification(final Parcel in) { title = in.readString(); tag = in.readString(); mCookie = in.readString(); text = in.readString(); imageUrl = in.readString(); textDirection = in.readString(); lang = in.readString(); requireInteraction = in.readInt() == 1; source = in.readString(); silent = in.readInt() == 1; privateBrowsing = in.readInt() == 1; vibrate = in.createIntArray(); } public static final Creator CREATOR = new Creator<>() { @Override public WebNotification createFromParcel(final Parcel in) { final int version = in.readInt(); if (version != VERSION) { throw new ParcelFormatException( "Mismatched version: " + version + " expected: " + VERSION); } return new WebNotification(in); } @Override public WebNotification[] newArray(final int size) { return new WebNotification[size]; } }; }