Bug 1476720 - Set MLS notification action. r?sdaswani
Moved notification channels to NotificationHelper and created
new utility methods to retrieve them when needed. Cleaned unused
imports.
MozReview-Commit-ID: L3HnV3nD7Og
--- a/mobile/android/base/java/org/mozilla/gecko/DataReportingNotification.java
+++ b/mobile/android/base/java/org/mozilla/gecko/DataReportingNotification.java
@@ -14,16 +14,17 @@ import android.content.res.Resources;
import android.graphics.Typeface;
import android.support.v4.app.NotificationCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import org.mozilla.gecko.AppConstants.Versions;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.gecko.preferences.GeckoPreferences;
public class DataReportingNotification {
private static final String LOGTAG = "DataReportNotification";
public static final String ALERT_NAME_DATAREPORTING_NOTIFICATION = "datareporting-notification";
@@ -104,17 +105,18 @@ public class DataReportingNotification {
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notificationBigSummary))
.addAction(R.drawable.firefox_settings_alert, notificationAction, contentIntent)
.setTicker(tickerText);
if (!AppConstants.Versions.preO) {
- notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notificationBuilder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = ALERT_NAME_DATAREPORTING_NOTIFICATION.hashCode();
notificationManager.notify(notificationID, notificationBuilder.build());
// Record version and notification time.
SharedPreferences.Editor editor = sharedPrefs.edit();
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -1,20 +1,17 @@
/* 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.Manifest;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
@@ -72,22 +69,16 @@ import java.net.URL;
import java.util.UUID;
public class GeckoApplication extends Application
implements HapticFeedbackDelegate {
private static final String LOG_TAG = "GeckoApplication";
public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG";
private static final String MEDIA_DECODING_PROCESS_CRASH = "MEDIA_DECODING_PROCESS_CRASH";
- private static NotificationChannel defaultNotificationChannel = null;
- /**
- * Mozilla Location Services Notification Channel.
- */
- private static NotificationChannel mlsNotificationChannel = null;
-
private boolean mInBackground;
private boolean mPausedGecko;
private boolean mIsInitialResume;
private LightweightTheme mLightweightTheme;
private RefWatcher mRefWatcher;
@@ -355,21 +346,16 @@ public class GeckoApplication extends Ap
NotificationHelper.getInstance(context).init();
MulticastDNSManager.getInstance(context).init();
GeckoService.register();
IntentHelper.init();
- if (!AppConstants.Versions.preO) {
- createDefaultNotificationChannel();
- createMLSNotificationChannel();
- }
-
EventDispatcher.getInstance().registerGeckoThreadListener(mListener,
"Distribution:GetDirectories",
null);
EventDispatcher.getInstance().registerUiThreadListener(mListener,
"Gecko:Exited",
"RuntimePermissions:Check",
"Snackbar:Show",
"Share:Text",
@@ -433,44 +419,16 @@ public class GeckoApplication extends Ap
final Method onCreate = clazz.getMethod("onCreate", Context.class);
return (Boolean) onCreate.invoke(null, getApplicationContext()); // Method is static.
} catch (Exception e) {
Log.e(LOG_TAG, "Got exception during startup; ignoring.", e);
return false;
}
}
- @TargetApi(26)
- private void createDefaultNotificationChannel() {
- final String DEFAULT_CHANNEL = AppConstants.MOZ_APP_DISPLAYNAME;
- final String DEFAULT_NAME = AppConstants.MOZ_APP_DISPLAYNAME;
- final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_HIGH;
-
- NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- defaultNotificationChannel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL);
- if (defaultNotificationChannel == null) {
- defaultNotificationChannel = new NotificationChannel(DEFAULT_CHANNEL, DEFAULT_NAME, DEFAULT_IMPORTANCE);
- notificationManager.createNotificationChannel(defaultNotificationChannel);
- }
- }
-
- @TargetApi(26)
- private void createMLSNotificationChannel() {
- final String DEFAULT_CHANNEL = AppConstants.MOZ_APP_DISPLAYNAME;
- final String DEFAULT_NAME = AppConstants.MOZ_APP_DISPLAYNAME;
- final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_LOW;
-
- NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mlsNotificationChannel = notificationManager.getNotificationChannel(DEFAULT_CHANNEL);
- if (mlsNotificationChannel == null) {
- mlsNotificationChannel = new NotificationChannel(DEFAULT_CHANNEL, DEFAULT_NAME, DEFAULT_IMPORTANCE);
- notificationManager.createNotificationChannel(mlsNotificationChannel);
- }
- }
-
public void onDelayedStartup() {
if (AppConstants.MOZ_ANDROID_GCM) {
// TODO: only run in main process.
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
initPushService();
}
@@ -656,24 +614,16 @@ public class GeckoApplication extends Ap
// Init push service and redirect the event to it.
if (initPushService()) {
EventDispatcher.getInstance().dispatch(event, message, callback);
}
}
}
}
- public static NotificationChannel getDefaultNotificationChannel() {
- return defaultNotificationChannel;
- }
-
- public static NotificationChannel getMLSNotificationChannel() {
- return mlsNotificationChannel;
- }
-
public boolean isApplicationInBackground() {
return mInBackground;
}
public LightweightTheme getLightweightTheme() {
return mLightweightTheme;
}
--- a/mobile/android/base/java/org/mozilla/gecko/GuestSession.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GuestSession.java
@@ -6,16 +6,18 @@ package org.mozilla.gecko;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.support.v7.app.NotificationCompat;
+import org.mozilla.gecko.notifications.NotificationHelper;
+
// Utility methods for entering/exiting guest mode.
public final class GuestSession {
private static final String LOGTAG = "GeckoGuestSession";
public static final String NOTIFICATION_INTENT = "org.mozilla.gecko.GUEST_SESSION_INPROGRESS";
private static PendingIntent getNotificationIntent(Context context) {
Intent intent = new Intent(NOTIFICATION_INTENT);
@@ -29,17 +31,18 @@ public final class GuestSession {
final Resources res = context.getResources();
builder.setContentTitle(res.getString(R.string.guest_browsing_notification_title))
.setContentText(res.getString(R.string.guest_browsing_notification_text))
.setSmallIcon(R.drawable.alert_guest)
.setOngoing(true)
.setContentIntent(getNotificationIntent(context));
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
final NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(R.id.guestNotification, builder.build());
}
public static void hideNotification(Context context) {
final NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
--- a/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaControlAgent.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/GeckoMediaControlAgent.java
@@ -26,22 +26,22 @@ import android.support.annotation.CheckR
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.IntentHelper;
import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.annotation.RobocopTarget;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import static org.mozilla.gecko.BuildConfig.DEBUG;
public class GeckoMediaControlAgent {
private static final String LOGTAG = "GeckoMediaControlAgent";
@@ -391,17 +391,18 @@ public class GeckoMediaControlAgent {
.setStyle(style)
.addAction(createNotificationAction())
.setOngoing(onGoing)
.setShowWhen(false)
.setWhen(0)
.setVisibility(visibility);
if (!AppConstants.Versions.preO) {
- notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notificationBuilder.setChannelId(NotificationHelper.getInstance(mContext)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
currentNotification = notificationBuilder.build();
}
/* package */ Notification getCurrentNotification() {
return currentNotification;
}
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
@@ -20,19 +20,19 @@ import com.leanplum.LeanplumActivityHelp
import com.leanplum.LeanplumPushNotificationCustomizer;
import com.leanplum.LeanplumPushService;
import com.leanplum.annotations.Parser;
import com.leanplum.callbacks.VariablesChangedCallback;
import com.leanplum.internal.Constants;
import com.leanplum.internal.LeanplumInternal;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.MmaConstants;
import org.mozilla.gecko.firstrun.PanelConfig;
+import org.mozilla.gecko.notifications.NotificationHelper;
import java.lang.ref.WeakReference;
import java.util.Map;
public class MmaLeanplumImp implements MmaInterface {
@@ -87,17 +87,18 @@ public class MmaLeanplumImp implements M
@Override
public void setCustomIcon(@DrawableRes final int iconResId) {
LeanplumPushService.setCustomizer(new LeanplumPushNotificationCustomizer() {
@Override
public void customize(NotificationCompat.Builder builder, Bundle notificationPayload) {
builder.setSmallIcon(iconResId);
builder.setDefaults(Notification.DEFAULT_SOUND);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(builder.mContext)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
}
});
}
@Override
public void start(Context context) {
--- a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java
+++ b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java
@@ -15,17 +15,16 @@ import android.graphics.Bitmap;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoActivityMonitor;
import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.GeckoService;
import org.mozilla.gecko.NotificationListener;
import org.mozilla.gecko.R;
import org.mozilla.gecko.util.BitmapUtils;
import java.util.HashMap;
/**
@@ -151,17 +150,18 @@ public final class NotificationClient im
.setDeleteIntent(deleteIntent)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(alertText)
.setSummaryText(host));
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(mContext)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
// Fetch icon.
if (!imageUrl.isEmpty()) {
final Bitmap image = BitmapUtils.decodeUrl(imageUrl);
builder.setLargeIcon(image);
}
@@ -232,17 +232,18 @@ public final class NotificationClient im
final Notification.Builder notificationBuilder = new Notification.Builder(mContext)
.setContentText(alertText)
.setSmallIcon(notification.icon)
.setWhen(notification.when)
.setContentIntent(notification.contentIntent)
.setProgress((int) progressMax, (int) progress, false);
if (!AppConstants.Versions.preO) {
- notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notificationBuilder.setChannelId(NotificationHelper.getInstance(mContext)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notification = notificationBuilder.build();
add(name, notification);
}
/* package */ synchronized Notification onNotificationClose(final String name) {
mNotificationManager.cancel(name, 0);
--- a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
@@ -1,16 +1,19 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.notifications;
+import android.annotation.TargetApi;
import android.app.Activity;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -18,29 +21,31 @@ import android.os.StrictMode;
import android.support.v4.app.NotificationCompat;
import android.support.v4.util.SimpleArrayMap;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoActivityMonitor;
import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoApplication;
+import org.mozilla.gecko.R;
import org.mozilla.gecko.mozglue.SafeIntent;
import org.mozilla.gecko.util.BitmapUtils;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLConnection;
import java.net.URLDecoder;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public final class NotificationHelper implements BundleEventListener {
public static final String HELPER_BROADCAST_ACTION = AppConstants.ANDROID_PACKAGE_NAME + ".helperBroadcastAction";
public static final String NOTIFICATION_ID = "NotificationHelper_ID";
private static final String LOGTAG = "GeckoNotificationHelper";
private static final String HELPER_NOTIFICATION = "helperNotif";
@@ -73,16 +78,36 @@ public final class NotificationHelper im
private static final String BUTTON_EVENT = "notification-button-clicked";
private static final String CLICK_EVENT = "notification-clicked";
static final String CLEARED_EVENT = "notification-cleared";
static final String ORIGINAL_EXTRA_COMPONENT = "originalComponent";
private final Context mContext;
+
+ public enum Channel {
+ /**
+ * Default notification channel.
+ */
+ DEFAULT,
+ /**
+ * Mozilla Location Services notification channel.
+ */
+ MLS
+ }
+
+ private final Map<Channel, String> mDefinedNotificationChannels = new HashMap<Channel, String>() {{
+ final String DEFAULT_CHANNEL_TAG = "default-notification-channel";
+ put(Channel.DEFAULT, DEFAULT_CHANNEL_TAG);
+
+ final String MLS_CHANNEL_TAG = "mls-notification-channel";
+ put(Channel.MLS, MLS_CHANNEL_TAG);
+ }};
+
// Holds a list of notifications that should be cleared if the Fennec Activity is shut down.
// Will not include ongoing or persistent notifications that are tied to Gecko's lifecycle.
private SimpleArrayMap<String, GeckoBundle> mClearableNotifications;
private boolean mInitialized;
private static NotificationHelper sInstance;
private NotificationHelper(Context context) {
@@ -93,31 +118,74 @@ public final class NotificationHelper im
if (mInitialized) {
return;
}
mClearableNotifications = new SimpleArrayMap<>();
EventDispatcher.getInstance().registerUiThreadListener(this,
"Notification:Show",
"Notification:Hide");
+
+ if (!AppConstants.Versions.preO) {
+ initNotificationChannels();
+ }
+
mInitialized = true;
}
public static NotificationHelper getInstance(Context context) {
// If someone else created this singleton, but didn't initialize it, something has gone wrong.
if (sInstance != null && !sInstance.mInitialized) {
throw new IllegalStateException("NotificationHelper was created by someone else but not initialized");
}
if (sInstance == null) {
sInstance = new NotificationHelper(context.getApplicationContext());
}
return sInstance;
}
+ private void initNotificationChannels() {
+ for (Channel mozChannel : mDefinedNotificationChannels.keySet()) {
+ createChannel(mozChannel);
+ }
+ }
+
+ @TargetApi(26)
+ private void createChannel(Channel definedChannel) {
+ final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ NotificationChannel channel = notificationManager.getNotificationChannel(mDefinedNotificationChannels.get(definedChannel));
+
+ if (channel == null) {
+ switch (definedChannel) {
+ case MLS: {
+ channel = new NotificationChannel(mDefinedNotificationChannels.get(definedChannel),
+ mContext.getString(R.string.mls_notification_channel), NotificationManager.IMPORTANCE_LOW);
+ }
+ break;
+
+ case DEFAULT:
+
+ default: {
+ channel = new NotificationChannel(mDefinedNotificationChannels.get(definedChannel),
+ mContext.getString(R.string.default_notification_channel), NotificationManager.IMPORTANCE_HIGH);
+ }
+ break;
+ }
+
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
+
+ @TargetApi(26)
+ public NotificationChannel getNotificationChannel(Channel definedChannel) {
+ final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ return notificationManager.getNotificationChannel(mDefinedNotificationChannels.get(definedChannel));
+ }
+
@Override // BundleEventListener
public void handleMessage(final String event, final GeckoBundle message,
final EventCallback callback) {
if ("Notification:Show".equals(event)) {
showNotification(message);
} else if ("Notification:Hide".equals(event)) {
hideNotification(message);
}
@@ -247,17 +315,17 @@ public final class NotificationHelper im
builder.setSmallIcon(BitmapUtils.getResource(mContext, imageUri));
final int[] light = message.getIntArray(LIGHT_ATTR);
if (light != null && light.length == 3) {
builder.setLights(light[0], light[1], light[2]);
}
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(getNotificationChannel(Channel.DEFAULT).getId());
}
final boolean ongoing = message.getBoolean(ONGOING_ATTR);
builder.setOngoing(ongoing);
if (message.containsKey(WHEN_ATTR)) {
final long when = (long) message.getDouble(WHEN_ATTR);
builder.setWhen(when);
--- a/mobile/android/base/java/org/mozilla/gecko/notifications/WhatsNewReceiver.java
+++ b/mobile/android/base/java/org/mozilla/gecko/notifications/WhatsNewReceiver.java
@@ -1,26 +1,24 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.notifications;
-import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.switchboard.SwitchBoard;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.Locales;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.preferences.GeckoPreferences;
@@ -66,17 +64,18 @@ public class WhatsNewReceiver extends Br
.setContentTitle(context.getString(R.string.whatsnew_notification_title))
.setContentText(context.getString(R.string.whatsnew_notification_summary))
.setSmallIcon(R.drawable.ic_status_logo)
.setAutoCancel(true)
.setContentIntent(getContentIntent(context))
.setDeleteIntent(getDeleteIntent(context));
if (!AppConstants.Versions.preO) {
- notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notificationBuilder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
final int notificationID = EXTRA_WHATSNEW_NOTIFICATION.hashCode();
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID, notificationBuilder.build());
Telemetry.sendUIEvent(TelemetryContract.Event.SHOW, TelemetryContract.Method.NOTIFICATION, EXTRA_WHATSNEW_NOTIFICATION);
}
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java
@@ -18,20 +18,20 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
import java.util.ArrayList;
import java.util.List;
public class TabQueueHelper {
@@ -250,17 +250,18 @@ public class TabQueueHelper {
.setContentTitle(text)
.setContentText(resources.getString(R.string.tab_queue_notification_title))
.setStyle(inboxStyle)
.setColor(ContextCompat.getColor(context, R.color.fennec_ui_accent))
.setNumber(tabsQueued)
.setContentIntent(pendingIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(TabQueueHelper.TAB_QUEUE_NOTIFICATION_ID, builder.build());
}
public static boolean shouldOpenTabQueueUrls(final Context context) {
ThreadUtils.assertNotOnUiThread();
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
@@ -2,51 +2,49 @@
* 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.tabqueue;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
-import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationManagerCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.mozglue.SafeIntent;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.gecko.preferences.GeckoPreferences;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
@@ -259,17 +257,18 @@ public class TabQueueService extends Ser
.setStyle(style)
.setSmallIcon(R.drawable.ic_status_logo)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(true)
.addAction(R.drawable.ic_action_settings, getString(R.string.tab_queue_prompt_settings_button), pendingIntent);
if (!AppConstants.Versions.preO) {
- notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notificationBuilder.setChannelId(NotificationHelper.getInstance(this)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(R.id.tabQueueSettingsNotification, notificationBuilder.build());
}
private void removeView() {
try {
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabReceivedService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabReceivedService.java
@@ -17,20 +17,20 @@ import android.support.annotation.Nullab
import android.support.annotation.WorkerThread;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.BrowserLocaleManager;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.GeckoSharedPrefs;
import org.mozilla.gecko.R;
import org.mozilla.gecko.db.BrowserContract;
+import org.mozilla.gecko.notifications.NotificationHelper;
/**
* A JobIntentService that displays a notification for a tab sent to this device.
*
* The expected Intent should contain:
* * Data: URI to open in the notification
* * EXTRA_TITLE: Page title of the URI to open
*/
@@ -64,17 +64,18 @@ public class TabReceivedService extends
builder.setSmallIcon(R.drawable.ic_status_logo);
builder.setContentTitle(notificationTitle);
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
builder.setContentText(uri);
builder.setContentIntent(contentIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(this)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
// Trigger "heads-up" notification mode on supported Android versions.
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
final Uri notificationSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (notificationSoundUri != null) {
builder.setSound(notificationSoundUri);
}
--- a/mobile/android/base/java/org/mozilla/gecko/updater/Updater.java
+++ b/mobile/android/base/java/org/mozilla/gecko/updater/Updater.java
@@ -3,17 +3,16 @@
* 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.updater;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
-import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
@@ -26,19 +25,19 @@ import android.support.annotation.String
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v4.net.ConnectivityManagerCompat;
import android.util.Log;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.GeckoUpdateReceiver;
import org.mozilla.gecko.R;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.gecko.permissions.Permissions;
import org.mozilla.gecko.updater.UpdateServiceHelper.AutoDownloadPolicy;
import org.mozilla.gecko.updater.UpdateServiceHelper.CheckUpdateResult;
import org.mozilla.gecko.updater.UpdateServiceHelper.UpdateInfo;
import org.mozilla.gecko.util.IOUtils;
import org.mozilla.gecko.util.ProxySelector;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -230,17 +229,18 @@ public class Updater {
.setContentText(getString(R.string.updater_permission_text))
.setStyle(bigTextStyle)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_status_logo)
.setColor(ContextCompat.getColor(context, R.color.rejection_red))
.setContentIntent(pendingIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
NotificationManagerCompat.from(context)
.notify(R.id.updateServicePermissionNotification, builder.build());
}
@SuppressLint("NewApi")
private void startDownload(UpdateInfo info, int flags) {
@@ -272,17 +272,18 @@ public class Updater {
builder.setSmallIcon(R.drawable.ic_status_logo);
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
builder.setContentTitle(getString(R.string.updater_start_title));
builder.setContentText(getString(R.string.updater_start_select));
builder.setContentIntent(contentIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notificationManager.notify(notificationId, builder.build());
return;
}
File pkg = downloadUpdatePackage(info, hasFlag(flags, FLAG_OVERWRITE_EXISTING));
@@ -313,17 +314,18 @@ public class Updater {
builder.setSmallIcon(R.drawable.ic_status_logo);
builder.setWhen(System.currentTimeMillis());
builder.setAutoCancel(true);
builder.setContentTitle(getString(R.string.updater_apply_title));
builder.setContentText(getString(R.string.updater_apply_select));
builder.setContentIntent(contentIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notificationManager.notify(notificationId, builder.build());
}
}
private File downloadUpdatePackage(UpdateInfo info, boolean overwriteExisting) {
URL url = null;
@@ -467,17 +469,18 @@ public class Updater {
notifBuilder = new NotificationCompat.Builder(context);
notifBuilder.setContentTitle(getString(R.string.updater_downloading_title))
.setContentText(shouldApplyImmediately ? "" : getString(R.string.updater_downloading_select))
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentIntent(contentIntent)
.setDeleteIntent(deleteIntent);
if (!AppConstants.Versions.preO) {
- notifBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ notifBuilder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notifBuilder.setProgress(100, 0, true);
notificationManager.notify(notificationId, notifBuilder.build());
}
@SuppressLint("NewApi")
private void showDownloadFailure() {
@@ -489,17 +492,18 @@ public class Updater {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_status_logo);
builder.setWhen(System.currentTimeMillis());
builder.setContentTitle(getString(R.string.updater_downloading_title_failed));
builder.setContentText(getString(R.string.updater_downloading_retry));
builder.setContentIntent(contentIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notificationManager.notify(notificationId, builder.build());
}
private void applyUpdate(File updateFile) {
shouldApplyImmediately = false;
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -887,8 +887,12 @@ See also https://bug1409261.bmoattachmen
<!ENTITY pwa_onboarding_sumo "You can easily add this website to your Home screen to have instant access and browse faster with an app-like experience.">
<!-- Used by accessibility services to identify the play/pause buttons shown in the
Picture-in-picture mini window -->
<!ENTITY pip_play_button_title "Play">
<!ENTITY pip_play_button_description "Resume playing">
<!ENTITY pip_pause_button_title "Pause">
<!ENTITY pip_pause_button_description "Pause playing">
+
+<!-- Notification channels names -->
+<!ENTITY default_notification_channel "&brandShortName;">
+<!ENTITY mls_notification_channel "&vendorShortName; Location Service">
\ No newline at end of file
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -641,9 +641,12 @@
<string name="pwa_add_to_launcher_badge">&pwa_add_to_launcher_badge2;</string>
<string name="pwa_onboarding_sumo">&pwa_onboarding_sumo;</string>
<string name="pwa_continue_to_website">&pwa_continue_to_website;</string>
<string name="pip_play_button_title">&pip_play_button_title;</string>
<string name="pip_play_button_description">&pip_play_button_description;</string>
<string name="pip_pause_button_title">&pip_pause_button_title;</string>
<string name="pip_pause_button_description">&pip_pause_button_description;</string>
+
+ <string name="default_notification_channel">&default_notification_channel;</string>
+ <string name="mls_notification_channel">&mls_notification_channel;</string>
</resources>
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/sync/FxAccountNotificationManager.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/sync/FxAccountNotificationManager.java
@@ -1,32 +1,31 @@
/* 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.fxa.sync;
-import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.NotificationCompat;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.Locales;
import org.mozilla.gecko.R;
import org.mozilla.gecko.background.common.log.Logger;
import org.mozilla.gecko.background.fxa.FxAccountUtils;
import org.mozilla.gecko.fxa.FxAccountConstants;
import org.mozilla.gecko.fxa.activities.FxAccountWebFlowActivity;
import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
import org.mozilla.gecko.fxa.login.State;
import org.mozilla.gecko.fxa.login.State.Action;
+import org.mozilla.gecko.notifications.NotificationHelper;
/**
* Abstraction that manages notifications shown or hidden for a Firefox Account.
* <p>
* In future, we anticipate this tracking things like:
* <ul>
* <li>new engines to offer to Sync;</li>
* <li>service interruption updates;</li>
@@ -108,14 +107,15 @@ public class FxAccountNotificationManage
builder
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.ic_status_logo)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
if (!AppConstants.Versions.preO) {
- builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ builder.setChannelId(NotificationHelper.getInstance(context)
+ .getNotificationChannel(NotificationHelper.Channel.DEFAULT).getId());
}
notificationManager.notify(notificationId, builder.build());
}
}
--- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java
+++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java
@@ -15,19 +15,19 @@ import android.location.Location;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.IntentHelper;
import org.mozilla.gecko.R;
+import org.mozilla.gecko.notifications.NotificationHelper;
import org.mozilla.mozstumbler.service.AppGlobals;
import org.mozilla.mozstumbler.service.Prefs;
import org.mozilla.mozstumbler.service.stumblerthread.blocklist.WifiBlockListInterface;
import org.mozilla.mozstumbler.service.stumblerthread.datahandling.DataStorageManager;
import org.mozilla.mozstumbler.service.stumblerthread.scanners.ScanManager;
import org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver;
import org.mozilla.mozstumbler.service.utils.PersistentIntentService;
@@ -139,17 +139,19 @@ public class StumblerService extends Per
super.onCreate();
setIntentRedelivery(true);
}
@Override
@SuppressLint("NewApi")
public int onStartCommand(Intent intent, int flags, int startId) {
if (!AppConstants.Versions.preO) {
- final Notification notification = new NotificationCompat.Builder(this, GeckoApplication.getMLSNotificationChannel().getId())
+ final Notification notification = new NotificationCompat.Builder(this,
+ NotificationHelper.getInstance(this)
+ .getNotificationChannel(NotificationHelper.Channel.MLS).getId())
.setSmallIcon(R.drawable.ic_status_logo)
.setContentTitle(getString(R.string.datareporting_stumbler_notification_title))
.setContentIntent(createContentIntent())
.setOngoing(true)
.setShowWhen(false)
.setWhen(0)
.build();