Bug 1233150 - Add "Mute notifications" button to system notifications.
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
@@ -1301,17 +1301,17 @@ public class GeckoAppShell
if (notificationClient == null) {
notificationClient = client;
} else {
Log.d(LOGTAG, "Notification client already set");
}
}
@WrapForJNI(stubName = "ShowAlertNotificationWrapper")
- public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText, String aAlertCookie, String aAlertName, String aHost) {
+ public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText, String aAlertCookie, String aAlertName, String aHost, String aOrigin) {
// The intent to launch when the user clicks the expanded notification
Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CALLBACK);
notificationIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
int notificationID = aAlertName.hashCode();
// Put the strings into the intent as an URI "alert:?name=<alertName>&app=<appName>&cookie=<cookie>"
@@ -1322,17 +1322,17 @@ public class GeckoAppShell
.build();
notificationIntent.setData(dataUri);
PendingIntent contentIntent = PendingIntent.getActivity(
getContext(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
ALERT_COOKIES.put(aAlertName, aAlertCookie);
callObserver(aAlertName, "alertshow", aAlertCookie);
- notificationClient.add(notificationID, aImageUrl, aHost, aAlertTitle, aAlertText, contentIntent);
+ notificationClient.add(notificationID, aImageUrl, aHost, aAlertTitle, aAlertText, contentIntent, aOrigin);
}
@WrapForJNI
public static void alertsProgressListener_OnProgress(String aAlertName, long aProgress, long aProgressMax, String aAlertText) {
int notificationID = aAlertName.hashCode();
notificationClient.update(notificationID, aProgress, aProgressMax, aAlertText);
}
--- a/mobile/android/base/java/org/mozilla/gecko/NotificationClient.java
+++ b/mobile/android/base/java/org/mozilla/gecko/NotificationClient.java
@@ -70,21 +70,21 @@ public abstract class NotificationClient
};
/**
* Adds a notification.
*
* @see NotificationHandler#add(int, String, String, String, PendingIntent, PendingIntent)
*/
public synchronized void add(final int notificationID, final String aImageUrl, final String aHost,
- final String aAlertTitle, final String aAlertText, final PendingIntent contentIntent) {
+ final String aAlertTitle, final String aAlertText, final PendingIntent contentIntent, final String origin) {
mTaskQueue.add(new Runnable() {
@Override
public void run() {
- mHandler.add(notificationID, aImageUrl, aHost, aAlertTitle, aAlertText, contentIntent);
+ mHandler.add(notificationID, aImageUrl, aHost, aAlertTitle, aAlertText, contentIntent, origin);
}
});
notify();
if (!mReady) {
bind();
}
}
--- a/mobile/android/base/java/org/mozilla/gecko/NotificationHandler.java
+++ b/mobile/android/base/java/org/mozilla/gecko/NotificationHandler.java
@@ -1,15 +1,16 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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.gecko;
+import android.content.Intent;
import android.graphics.Bitmap;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import org.mozilla.gecko.gfx.BitmapUtils;
@@ -46,29 +47,35 @@ public class NotificationHandler {
*
* @param notificationID the unique ID of the notification
* @param aImageUrl URL of the image to use
* @param aAlertTitle title of the notification
* @param aAlertText text of the notification
* @param contentIntent Intent used when the notification is clicked
*/
public void add(final int notificationID, String aImageUrl, String aHost, String aAlertTitle,
- String aAlertText, PendingIntent contentIntent) {
+ String aAlertText, PendingIntent contentIntent, String origin) {
// Remove the old notification with the same ID, if any
remove(notificationID);
+ // TODO: Service intent to clear pref on reopen.
+ Intent prefIntent = new Intent(Intent.ACTION_VIEW);
+ prefIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
+ PendingIntent buttonIntent = PendingIntent.getActivity(mContext, 0, prefIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setContentTitle(aAlertTitle)
.setContentText(aAlertText)
.setSmallIcon(R.drawable.ic_status_logo)
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setStyle(new NotificationCompat.InboxStyle()
- .addLine(aAlertText)
- .setSummaryText(aHost));
+ .addLine(aAlertText)
+ .setSummaryText(aHost))
+ .addAction(R.drawable.find_close, mContext.getResources().getString(R.string.web_notification_mute), buttonIntent);
// Fetch icon.
if (!aImageUrl.isEmpty()) {
final Bitmap image = BitmapUtils.decodeUrl(aImageUrl);
builder.setLargeIcon(image);
}
builder.setWhen(System.currentTimeMillis());
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -331,16 +331,18 @@ size. -->
<!ENTITY pref_search_last_toast "You can\'t remove or disable your last search engine.">
<!ENTITY pref_panels_show "Show">
<!ENTITY pref_panels_hide "Hide">
<!ENTITY pref_panels_reorder "Change order">
<!ENTITY pref_panels_move_up "Move up">
<!ENTITY pref_panels_move_down "Move down">
+<!ENTITY web_notification_mute "Mute notifications">
+
<!ENTITY datareporting_notification_title "&brandShortName; stats & data">
<!ENTITY datareporting_notification_action_long "Choose what information to share">
<!ENTITY datareporting_notification_action "Choose what to share">
<!ENTITY datareporting_notification_summary "To improve your experience, &brandShortName; automatically sends some information to &vendorShortName;.">
<!ENTITY datareporting_notification_summary_short "To improve your experience, &brandShortName;…">
<!ENTITY datareporting_notification_ticker_text "&datareporting_notification_title;: &datareporting_notification_action_long;">
<!-- Localization note (datareporting_fhr_title, datareporting_fhr_summary2,
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -305,16 +305,17 @@
<string name="pref_search_last_toast">&pref_search_last_toast;</string>
<string name="pref_panels_show">&pref_panels_show;</string>
<string name="pref_panels_hide">&pref_panels_hide;</string>
<string name="pref_panels_reorder">&pref_panels_reorder;</string>
<string name="pref_panels_move_up">&pref_panels_move_up;</string>
<string name="pref_panels_move_down">&pref_panels_move_down;</string>
+ <string name="web_notification_mute">&web_notification_mute;</string>
<string name="datareporting_notification_title">&datareporting_notification_title;</string>
<string name="datareporting_notification_action_long">&datareporting_notification_action_long;</string>
<string name="datareporting_notification_action">&datareporting_notification_action;</string>
<string name="datareporting_notification_summary">&datareporting_notification_summary;</string>
<string name="datareporting_notification_summary_short">&datareporting_notification_summary_short;</string>
<string name="datareporting_notification_ticker_text">&datareporting_notification_ticker_text;</string>
<string name="datareporting_telemetry_title">&datareporting_telemetry_title;</string>
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -523,21 +523,24 @@ AndroidBridge::ShowAlertNotification(con
const nsAString& aAlertName,
nsIPrincipal* aPrincipal)
{
if (nsAppShell::gAppShell && aAlertListener) {
// This will remove any observers already registered for this id
nsAppShell::gAppShell->PostEvent(AndroidGeckoEvent::MakeAddObserver(aAlertName, aAlertListener));
}
- nsAutoString host;
- nsAlertsUtils::GetSourceHostPort(aPrincipal, host);
+ nsAutoString pHost;
+ nsAlertsUtils::GetSourceHostPort(aPrincipal, pHost);
+
+ nsAutoCString pOrigin;
+ aPrincipal->GetOrigin(pOrigin);
GeckoAppShell::ShowAlertNotificationWrapper
- (aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName, host);
+ (aImageUrl, aAlertTitle, aAlertText, aAlertCookie, aAlertName, pHost, NS_ConvertUTF8toUTF16(pOrigin));
}
int
AndroidBridge::GetDPI()
{
static int sDPI = 0;
if (sDPI)
return sDPI;
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -652,19 +652,19 @@ constexpr char GeckoAppShell::SetURITitl
auto GeckoAppShell::SetURITitle(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void
{
return mozilla::jni::Method<SetURITitle_t>::Call(nullptr, nullptr, a0, a1);
}
constexpr char GeckoAppShell::ShowAlertNotificationWrapper_t::name[];
constexpr char GeckoAppShell::ShowAlertNotificationWrapper_t::signature[];
-auto GeckoAppShell::ShowAlertNotificationWrapper(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, mozilla::jni::String::Param a3, mozilla::jni::String::Param a4, mozilla::jni::String::Param a5) -> void
+auto GeckoAppShell::ShowAlertNotificationWrapper(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1, mozilla::jni::String::Param a2, mozilla::jni::String::Param a3, mozilla::jni::String::Param a4, mozilla::jni::String::Param a5, mozilla::jni::String::Param a6) -> void
{
- return mozilla::jni::Method<ShowAlertNotificationWrapper_t>::Call(nullptr, nullptr, a0, a1, a2, a3, a4, a5);
+ return mozilla::jni::Method<ShowAlertNotificationWrapper_t>::Call(nullptr, nullptr, a0, a1, a2, a3, a4, a5, a6);
}
constexpr char GeckoAppShell::ShowInputMethodPicker_t::name[];
constexpr char GeckoAppShell::ShowInputMethodPicker_t::signature[];
auto GeckoAppShell::ShowInputMethodPicker() -> void
{
return mozilla::jni::Method<ShowInputMethodPicker_t>::Call(nullptr, nullptr);
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -1567,27 +1567,28 @@ public:
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
mozilla::jni::String::Param,
+ mozilla::jni::String::Param,
mozilla::jni::String::Param> Args;
static constexpr char name[] = "showAlertNotification";
static constexpr char signature[] =
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
static const bool isStatic = true;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
- static auto ShowAlertNotificationWrapper(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
+ static auto ShowAlertNotificationWrapper(mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
public:
struct ShowInputMethodPicker_t {
typedef GeckoAppShell Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "showInputMethodPicker";