/* 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