--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -230,17 +230,16 @@ public class BrowserApp extends GeckoApp
public static final int ACTIVITY_REQUEST_TRIPLE_READERVIEW = 4001;
public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_ADD_BOOKMARK = 4002;
public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_IGNORE = 4003;
public static final String ACTION_VIEW_MULTIPLE = AppConstants.ANDROID_PACKAGE_NAME + ".action.VIEW_MULTIPLE";
@RobocopTarget
public static final String EXTRA_SKIP_STARTPANE = "skipstartpane";
- private static final String EOL_NOTIFIED = "eol_notified";
/**
* Be aware of {@link org.mozilla.gecko.fxa.EnvironmentUtils.GECKO_PREFS_FIRSTRUN_UUID}.
*/
private static final String FIRSTRUN_UUID = "firstrun_uuid";
private BrowserSearch mBrowserSearch;
private View mBrowserSearchContainer;
@@ -1045,55 +1044,16 @@ public class BrowserApp extends GeckoApp
SnackbarBuilder.builder(this)
.message(R.string.updater_permission_text)
.duration(Snackbar.LENGTH_INDEFINITE)
.action(R.string.updater_permission_allow)
.callback(allowCallback)
.buildAndShow();
}
- private void conditionallyNotifyEOL() {
- final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
- try {
- final SharedPreferences prefs = GeckoSharedPrefs.forProfile(this);
- if (!prefs.contains(EOL_NOTIFIED)) {
-
- // Launch main App to load SUMO url on EOL notification.
- final String link = getString(R.string.eol_notification_url,
- AppConstants.MOZ_APP_VERSION,
- AppConstants.OS_TARGET,
- Locales.getLanguageTag(Locale.getDefault()));
-
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
- intent.setData(Uri.parse(link));
- final PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- final Notification notification = new NotificationCompat.Builder(this)
- .setContentTitle(getString(R.string.eol_notification_title))
- .setContentText(getString(R.string.eol_notification_summary))
- .setSmallIcon(R.drawable.ic_status_logo)
- .setAutoCancel(true)
- .setContentIntent(pendingIntent)
- .build();
-
- final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- final int notificationID = EOL_NOTIFIED.hashCode();
- notificationManager.notify(notificationID, notification);
-
- GeckoSharedPrefs.forProfile(this)
- .edit()
- .putBoolean(EOL_NOTIFIED, true)
- .apply();
- }
- } finally {
- StrictMode.setThreadPolicy(savedPolicy);
- }
- }
-
/**
* Code to actually show the first run pager, separated
* for distribution purposes.
*/
@UiThread
private void checkFirstrunInternal() {
showFirstrunPager();
--- a/mobile/android/base/java/org/mozilla/gecko/DataReportingNotification.java
+++ b/mobile/android/base/java/org/mozilla/gecko/DataReportingNotification.java
@@ -1,32 +1,31 @@
/* -*- 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 org.mozilla.gecko.AppConstants.Versions;
-import org.mozilla.gecko.preferences.GeckoPreferences;
-
-import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
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.preferences.GeckoPreferences;
+
public class DataReportingNotification {
private static final String LOGTAG = "DataReportNotification";
public static final String ALERT_NAME_DATAREPORTING_NOTIFICATION = "datareporting-notification";
private static final String PREFS_POLICY_NOTIFIED_TIME = "datareporting.policy.dataSubmissionPolicyNotifiedTime";
private static final String PREFS_POLICY_VERSION = "datareporting.policy.dataSubmissionPolicyVersion";
@@ -61,16 +60,17 @@ public class DataReportingNotification {
}
return;
}
}
/**
* Launch a notification of the data policy, and record notification time and version.
*/
+ @SuppressWarnings("NewApi")
public static void notifyDataPolicy(Context context, SharedPreferences sharedPrefs) {
boolean result = false;
try {
// Launch main App to launch Data choices when notification is clicked.
Intent prefIntent = new Intent(GeckoApp.ACTION_LAUNCH_SETTINGS);
prefIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
GeckoPreferences.setResourceToOpen(prefIntent, "preferences_privacy");
@@ -92,31 +92,34 @@ public class DataReportingNotification {
String notificationBigSummary = resources.getString(R.string.datareporting_notification_summary);
// Make styled ticker text for display in notification bar.
String tickerString = resources.getString(R.string.datareporting_notification_ticker_text);
SpannableString tickerText = new SpannableString(tickerString);
// Bold the notification title of the ticker text, which is the same string as notificationTitle.
tickerText.setSpan(new StyleSpan(Typeface.BOLD), 0, notificationTitle.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- Notification notification = new NotificationCompat.Builder(context)
+ NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setContentTitle(notificationTitle)
.setContentText(notificationSummary)
.setSmallIcon(R.drawable.ic_status_logo)
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(notificationBigSummary))
.addAction(R.drawable.firefox_settings_alert, notificationAction, contentIntent)
- .setTicker(tickerText)
- .build();
+ .setTicker(tickerText);
+
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
int notificationID = ALERT_NAME_DATAREPORTING_NOTIFICATION.hashCode();
- notificationManager.notify(notificationID, notification);
+ notificationManager.notify(notificationID, notificationBuilder.build());
// Record version and notification time.
SharedPreferences.Editor editor = sharedPrefs.edit();
long now = System.currentTimeMillis();
editor.putLong(PREFS_POLICY_NOTIFIED_TIME, now);
editor.putInt(PREFS_POLICY_VERSION, DATA_REPORTING_VERSION);
editor.apply();
result = true;
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -1,17 +1,20 @@
/* 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;
@@ -68,16 +71,18 @@ 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;
+
private boolean mInBackground;
private boolean mPausedGecko;
private boolean mIsInitialResume;
private LightweightTheme mLightweightTheme;
private RefWatcher mRefWatcher;
@@ -344,16 +349,20 @@ public class GeckoApplication extends Ap
NotificationHelper.getInstance(context).init();
MulticastDNSManager.getInstance(context).init();
GeckoService.register();
IntentHelper.init();
+ if (!AppConstants.Versions.preO) {
+ createDefaultNotificationChannel();
+ }
+
EventDispatcher.getInstance().registerGeckoThreadListener(mListener,
"Distribution:GetDirectories",
null);
EventDispatcher.getInstance().registerUiThreadListener(mListener,
"Gecko:Exited",
"RuntimePermissions:Check",
"Snackbar:Show",
"Share:Text",
@@ -401,16 +410,30 @@ 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);
+ }
+ }
+
public void onDelayedStartup() {
if (AppConstants.MOZ_ANDROID_GCM) {
// TODO: only run in main process.
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
initPushService();
}
@@ -596,16 +619,20 @@ 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 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
@@ -1,45 +1,47 @@
/* -*- 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;
-import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.support.v4.app.NotificationCompat;
-import android.view.Window;
-import android.view.WindowManager;
+import android.support.v7.app.NotificationCompat;
// 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);
intent.setClassName(context, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
+ @SuppressWarnings("NewApi")
public static void showNotification(Context context) {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
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());
+ }
+
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);
manager.cancel(R.id.guestNotification);
}
--- a/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/media/MediaControlService.java
@@ -18,19 +18,22 @@ import android.media.session.MediaContro
import android.media.session.MediaSession;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.v4.app.NotificationManagerCompat;
+import android.support.v7.app.NotificationCompat;
import android.util.Log;
+import org.mozilla.gecko.AppConstants;
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.util.ThreadUtils;
public class MediaControlService extends Service {
private static final String LOGTAG = "MediaControlService";
@@ -360,40 +363,46 @@ public class MediaControlService extends
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
public void run() {
updateNotification(tab);
}
});
}
+ @SuppressWarnings("NewApi")
protected void updateNotification(Tab tab) {
ThreadUtils.assertNotOnUiThread();
final Notification.MediaStyle style = new Notification.MediaStyle();
style.setShowActionsInCompactView(0);
final boolean isPlaying = isMediaPlaying();
final int visibility = tab.isPrivate() ?
Notification.VISIBILITY_PRIVATE : Notification.VISIBILITY_PUBLIC;
- final Notification notification = new Notification.Builder(this)
+ final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_status_logo)
.setLargeIcon(generateCoverArt(tab))
.setContentTitle(tab.getTitle())
.setContentText(tab.getURL())
.setContentIntent(createContentIntent(tab))
.setDeleteIntent(createDeleteIntent())
.setStyle(style)
.addAction(createNotificationAction())
.setOngoing(isPlaying)
.setShowWhen(false)
.setWhen(0)
- .setVisibility(visibility)
- .build();
+ .setVisibility(visibility);
+
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
+ final Notification notification = notificationBuilder.build();
if (isPlaying) {
startForeground(R.id.mediaControlNotification, notification);
} else {
stopForeground(false);
NotificationManagerCompat.from(this)
.notify(R.id.mediaControlNotification, notification);
}
--- a/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/mma/MmaLeanplumImp.java
@@ -1,38 +1,37 @@
//#filter substitution
/* -*- 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.mma;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.content.Context;
-import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import com.leanplum.Leanplum;
import com.leanplum.LeanplumActivityHelper;
import com.leanplum.LeanplumPushNotificationCustomizer;
import com.leanplum.LeanplumPushService;
import com.leanplum.internal.Constants;
import com.leanplum.internal.LeanplumInternal;
-import com.leanplum.internal.VarCache;
import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.GeckoApplication;
import org.mozilla.gecko.MmaConstants;
import java.util.Map;
-import java.util.UUID;
public class MmaLeanplumImp implements MmaInterface {
@Override
public void init(final Activity activity, Map<String, ?> attributes) {
if (activity == null) {
@@ -73,25 +72,28 @@ public class MmaLeanplumImp implements M
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
LeanplumActivityHelper.onResume(activity);
}
});
}
+ @SuppressLint("NewApi")
@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());
+ }
}
-
});
}
@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
@@ -1,38 +1,37 @@
/* -*- 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.notifications;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationManagerCompat;
-import android.util.Log;
-
-import java.util.HashMap;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoActivityMonitor;
-import org.mozilla.gecko.GeckoApp;
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;
+
/**
* Client for posting notifications.
*/
public final class NotificationClient implements NotificationListener {
private static final String LOGTAG = "GeckoNotificationClient";
/* package */ static final String CLICK_ACTION = AppConstants.ANDROID_PACKAGE_NAME + ".NOTIFICATION_CLICK";
/* package */ static final String CLOSE_ACTION = AppConstants.ANDROID_PACKAGE_NAME + ".NOTIFICATION_CLOSE";
/* package */ static final String PERSISTENT_INTENT_EXTRA = "persistentIntent";
@@ -134,31 +133,36 @@ public final class NotificationClient im
*
* @param name the unique name of the notification
* @param imageUrl URL of the image to use
* @param alertTitle title of the notification
* @param alertText text of the notification
* @param contentIntent Intent used when the notification is clicked
* @param deleteIntent Intent used when the notification is closed
*/
+ @SuppressLint("NewApi")
private void add(final String name, final String imageUrl, final String host,
final String alertTitle, final String alertText,
final PendingIntent contentIntent, final PendingIntent deleteIntent) {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
.setContentTitle(alertTitle)
.setContentText(alertText)
.setSmallIcon(R.drawable.ic_status_logo)
.setContentIntent(contentIntent)
.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());
+ }
+
// Fetch icon.
if (!imageUrl.isEmpty()) {
final Bitmap image = BitmapUtils.decodeUrl(imageUrl);
builder.setLargeIcon(image);
}
builder.setWhen(System.currentTimeMillis());
final Notification notification = builder.build();
@@ -208,34 +212,39 @@ public final class NotificationClient im
/**
* Updates a notification.
*
* @param name Name of existing notification
* @param progress progress of item being updated
* @param progressMax max progress of item being updated
* @param alertText text of the notification
*/
+ @SuppressLint("NewApi")
public void update(final String name, final long progress,
final long progressMax, final String alertText) {
Notification notification;
synchronized (this) {
notification = mNotifications.get(name);
}
if (notification == null) {
return;
}
- notification = new NotificationCompat.Builder(mContext)
+ 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)
- .build();
+ .setProgress((int) progressMax, (int) progress, false);
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
+ notification = notificationBuilder.build();
add(name, notification);
}
/* package */ synchronized Notification onNotificationClose(final String name) {
mNotificationManager.cancel(name, 0);
final Notification notification = mNotifications.remove(name);
if (notification != null) {
--- a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
@@ -1,47 +1,47 @@
/* -*- 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 java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.net.URLConnection;
-import java.net.URLDecoder;
-import java.util.List;
-
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoActivityMonitor;
-import org.mozilla.gecko.GeckoAppShell;
-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 android.app.Activity;
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;
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.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.List;
+
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";
// Attributes mandatory to be used while sending a notification from js.
@@ -226,16 +226,17 @@ public final class NotificationHelper im
}
final Intent notificationIntent = buildNotificationIntent(message, builder);
PendingIntent res = PendingIntent.getBroadcast(
mContext, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return res;
}
+ @SuppressWarnings("NewApi")
private void showNotification(final GeckoBundle message) {
ThreadUtils.assertOnUiThread();
final NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
// These attributes are required
final String id = message.getString(ID_ATTR);
builder.setContentTitle(message.getString(TITLE_ATTR));
@@ -244,16 +245,20 @@ public final class NotificationHelper im
final Uri imageUri = Uri.parse(message.getString(SMALLICON_ATTR, ""));
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());
+ }
+
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
@@ -10,16 +10,17 @@ 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;
@@ -54,29 +55,33 @@ public class WhatsNewReceiver extends Br
showWhatsNewNotification(context);
}
private boolean isPreferenceEnabled(Context context) {
return GeckoSharedPrefs.forApp(context).getBoolean(GeckoPreferences.PREFS_NOTIFICATIONS_WHATS_NEW, true);
}
+ @SuppressWarnings("NewApi")
private void showWhatsNewNotification(Context context) {
- final Notification notification = new NotificationCompat.Builder(context)
+ final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.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))
- .build();
+ .setDeleteIntent(getDeleteIntent(context));
- final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
final int notificationID = EXTRA_WHATSNEW_NOTIFICATION.hashCode();
- notificationManager.notify(notificationID, notification);
+ 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);
}
private PendingIntent getContentIntent(Context context) {
final String link = context.getString(R.string.whatsnew_notification_url,
AppConstants.MOZ_APP_VERSION,
AppConstants.OS_TARGET,
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java
@@ -1,41 +1,40 @@
/* -*- 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.tabqueue;
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.GeckoSharedPrefs;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.preferences.GeckoPreferences;
-import org.mozilla.gecko.util.GeckoBundle;
-import org.mozilla.gecko.util.ThreadUtils;
-
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
-import android.os.Build;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
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.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 {
private static final String LOGTAG = "Gecko" + TabQueueHelper.class.getSimpleName();
// Disable Tab Queue for API level 10 (GB) - Bug 1206055
@@ -216,16 +215,17 @@ public class TabQueueHelper {
/**
* Displays a notification showing the total number of tabs queue. If there is already a notification displayed, it
* will be replaced.
*
* @param context
* @param tabsQueued
*/
+ @SuppressWarnings("NewApi")
public static void showNotification(final Context context, final int tabsQueued, final List<String> urls) {
ThreadUtils.assertNotOnUiThread();
Intent resultIntent = new Intent();
resultIntent.setClassName(context, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
resultIntent.setAction(TabQueueHelper.LOAD_URLS_ACTION);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_CANCEL_CURRENT);
@@ -249,16 +249,20 @@ public class TabQueueHelper {
.setSmallIcon(R.drawable.ic_status_logo)
.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());
+ }
+
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();
// TODO: Use profile shared prefs when bug 1147925 gets fixed.
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueService.java
@@ -1,25 +1,19 @@
/* -*- 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.tabqueue;
-import org.mozilla.gecko.AppConstants;
-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.preferences.GeckoPreferences;
-
+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;
@@ -34,17 +28,26 @@ 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.preferences.GeckoPreferences;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* On launch this Service displays a View over the currently running process with an action to open the url in Fennec
@@ -228,44 +231,49 @@ public class TabQueueService extends Ser
public void run() {
int queuedTabCount = TabQueueHelper.getTabQueueLength(TabQueueService.this);
Telemetry.addToHistogram("FENNEC_TABQUEUE_QUEUESIZE", queuedTabCount);
}
});
}
+ @SuppressLint("NewApi")
@TargetApi(Build.VERSION_CODES.M)
private void showSettingsNotification() {
if (AppConstants.Versions.preMarshmallow) {
return;
}
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
PendingIntent pendingIntent = PendingIntent.getActivity(this, intent.hashCode(), intent, 0);
final String text = getString(R.string.tab_queue_notification_settings);
final NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle()
.bigText(text);
- final Notification notification = new NotificationCompat.Builder(this)
+ final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.pref_tab_queue_title))
.setContentText(text)
.setCategory(NotificationCompat.CATEGORY_ERROR)
.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)
- .build();
+ .addAction(R.drawable.ic_action_settings, getString(R.string.tab_queue_prompt_settings_button), pendingIntent);
- NotificationManagerCompat.from(this).notify(R.id.tabQueueSettingsNotification, notification);
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
+ NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.notify(R.id.tabQueueSettingsNotification, notificationBuilder.build());
}
private void removeView() {
try {
windowManager.removeView(toastLayout);
} catch (IllegalArgumentException | IllegalStateException e) {
// This can happen if the Service is killed by the system. If this happens the View will have already
// been removed but the runnable will have been kept alive.
--- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabReceivedService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabReceivedService.java
@@ -1,34 +1,35 @@
/* 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 org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.BrowserLocaleManager;
-import org.mozilla.gecko.GeckoSharedPrefs;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.db.BrowserContract;
-
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
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;
+
/**
* An IntentService 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
*/
public class TabReceivedService extends IntentService {
@@ -38,16 +39,17 @@ public class TabReceivedService extends
private static final int MAX_NOTIFICATION_COUNT = 1000;
public TabReceivedService() {
super(LOGTAG);
setIntentRedelivery(true);
}
+ @SuppressWarnings("NewApi")
@Override
protected void onHandleIntent(final Intent intent) {
// IntentServices don't keep the process alive so
// we need to do this every time. Ideally, we wouldn't.
final Resources res = getResources();
BrowserLocaleManager.getInstance().correctLocale(this, res, res.getConfiguration());
final String uri = intent.getDataString();
@@ -64,16 +66,20 @@ public class TabReceivedService extends
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
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());
+ }
+
// 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);
}
final SharedPreferences prefs = GeckoSharedPrefs.forApp(this);
--- a/mobile/android/base/java/org/mozilla/gecko/updater/UpdateService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/updater/UpdateService.java
@@ -1,52 +1,50 @@
/* -*- 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.updater;
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.CrashHandler;
-import org.mozilla.gecko.R;
-
-import org.mozilla.apache.commons.codec.binary.Hex;
-
-import org.mozilla.gecko.permissions.Permissions;
-import org.mozilla.gecko.util.IOUtils;
-import org.mozilla.gecko.util.ProxySelector;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
import android.Manifest;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.Environment;
import android.provider.Settings;
+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.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;
+import org.mozilla.apache.commons.codec.binary.Hex;
+import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.CrashHandler;
+import org.mozilla.gecko.GeckoApplication;
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.permissions.Permissions;
+import org.mozilla.gecko.util.IOUtils;
+import org.mozilla.gecko.util.ProxySelector;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
@@ -79,17 +77,17 @@ public class UpdateService extends Inten
private static final String KEY_LAST_ATTEMPT_DATE = "UpdateService.lastAttemptDate";
private static final String KEY_AUTODOWNLOAD_POLICY = "UpdateService.autoDownloadPolicy";
private static final String KEY_UPDATE_URL = "UpdateService.updateUrl";
private SharedPreferences mPrefs;
private NotificationManagerCompat mNotificationManager;
private ConnectivityManager mConnectivityManager;
- private Builder mBuilder;
+ private NotificationCompat.Builder mBuilder;
private volatile WifiLock mWifiLock;
private boolean mDownloading;
private boolean mCancelDownload;
private boolean mApplyImmediately;
private CrashHandler mCrashHandler;
@@ -300,16 +298,17 @@ public class UpdateService extends Inten
.run(new Runnable() {
@Override
public void run() {
startDownload(info, flags);
}
});
}
+ @SuppressWarnings("NewApi")
private void startDownload(UpdateInfo info, int flags) {
AutoDownloadPolicy policy = getAutoDownloadPolicy();
// We only start a download automatically if one of following criteria are met:
//
// - We have a FORCE_DOWNLOAD flag passed in
// - The preference is set to 'always'
// - The preference is set to 'wifi' and we are using a non-metered network (i.e. the user
@@ -331,16 +330,20 @@ public class UpdateService extends Inten
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
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());
+ }
+
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
return;
}
File pkg = downloadUpdatePackage(info, hasFlag(flags, UpdateServiceHelper.FLAG_OVERWRITE_EXISTING));
if (pkg == null) {
sendCheckUpdateResult(CheckUpdateResult.NOT_AVAILABLE);
@@ -357,25 +360,28 @@ public class UpdateService extends Inten
} else {
// Prompt to apply the update
Intent notificationIntent = new Intent(UpdateServiceHelper.ACTION_APPLY_UPDATE);
notificationIntent.setClass(this, UpdateService.class);
notificationIntent.putExtra(UpdateServiceHelper.EXTRA_PACKAGE_PATH_NAME, pkg.getAbsolutePath());
PendingIntent contentIntent = PendingIntent.getService(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
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());
+ }
+
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
private UpdateInfo findUpdate(boolean force) {
URLConnection conn = null;
try {
URI uri = getUpdateURI(force);
@@ -486,32 +492,40 @@ public class UpdateService extends Inten
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle(getResources().getString(R.string.updater_downloading_title))
.setContentText(mApplyImmediately ? "" : getResources().getString(R.string.updater_downloading_select))
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentIntent(contentIntent)
.setDeleteIntent(deleteIntent);
+ if (!AppConstants.Versions.preO) {
+ mBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
mBuilder.setProgress(100, 0, true);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
private void showDownloadFailure() {
Intent notificationIntent = new Intent(UpdateServiceHelper.ACTION_CHECK_FOR_UPDATE);
notificationIntent.setClass(this, UpdateService.class);
PendingIntent contentIntent = PendingIntent.getService(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
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());
+ }
+
mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}
private boolean deleteUpdatePackage(String path) {
if (path == null) {
return false;
}
@@ -713,28 +727,31 @@ public class UpdateService extends Inten
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle()
.bigText(getString(R.string.updater_permission_text));
- Notification notification = new NotificationCompat.Builder(this)
+ NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.updater_permission_title))
.setContentText(getString(R.string.updater_permission_text))
.setStyle(bigTextStyle)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_status_logo)
.setColor(ContextCompat.getColor(this, R.color.rejection_red))
- .setContentIntent(pendingIntent)
- .build();
+ .setContentIntent(pendingIntent);
+
+ if (!AppConstants.Versions.preO) {
+ notificationBuilder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
NotificationManagerCompat.from(this)
- .notify(R.id.updateServicePermissionNotification, notification);
+ .notify(R.id.updateServicePermissionNotification, notificationBuilder.build());
}
private String getLastBuildID() {
return mPrefs.getString(KEY_LAST_BUILDID, null);
}
private String getLastHashFunction() {
return mPrefs.getString(KEY_LAST_HASH_FUNCTION, null);
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -819,19 +819,16 @@ just addresses the organization to follo
<!-- LOCALIZATION NOTE (unsupported_sdk_version): The user installed a build of this app that does not support
the Android version of this device. the formatS1 is replaced by the CPU ABI (e.g., ARMv7); the formatS2 is
replaced by the Android OS version (e.g., 14)-->
<!ENTITY unsupported_sdk_version "Sorry! This &brandShortName; won\'t work on this device (&formatS1;, &formatS2;). Please download the correct version.">
<!-- LOCALIZATION NOTE(corrupt_apk): This notification is shown if corruption has been detected on startup and the user has to reinstall Firefox -->
<!ENTITY corrupt_apk "Unable to open &brandShortName;. Please reinstall and try again.">
-<!ENTITY eol_notification_title2 "&brandShortName; will no longer update">
-<!ENTITY eol_notification_summary "Tap to learn more">
-
<!-- LOCALIZATION NOTE (whatsnew_notification_title, whatsnew_notification_summary): These strings
are used for a system notification that's shown to users after the app updates. -->
<!ENTITY whatsnew_notification_title "&brandShortName; is up to date">
<!ENTITY whatsnew_notification_summary "Find out what\'s new in this version">
<!ENTITY promotion_add_page_shortcut "Add page shortcut">
<!ENTITY helper_first_offline_bookmark_title "Read offline">
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -594,20 +594,17 @@
<string name="intent_uri_private_browsing_prompt">&intent_uri_private_browsing_prompt;</string>
<string name="intent_uri_private_browsing_multiple_match_title">&intent_uri_private_browsing_multiple_match_title;</string>
<string name="devtools_auth_scan_header">&devtools_auth_scan_header;</string>
<string name="unsupported_sdk_version">&unsupported_sdk_version;</string>
<string name="corrupt_apk">&corrupt_apk;</string>
- <string name="eol_notification_title">&eol_notification_title2;</string>
- <string name="eol_notification_summary">&eol_notification_summary;</string>
<!-- https://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/honeycomb -->
- <string name="eol_notification_url">https://support.mozilla.org/1/mobile/&formatS1;/&formatS2;/&formatS3;/unsupported-version</string>
<string name="whatsnew_notification_title">&whatsnew_notification_title;</string>
<string name="whatsnew_notification_summary">&whatsnew_notification_summary;</string>
<!-- https://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/new-android -->
<string name="whatsnew_notification_url">https://support.mozilla.org/1/mobile/&formatS1;/&formatS2;/&formatS3;/new-android</string>
<string name="promotion_add_page_shortcut">&promotion_add_page_shortcut;</string>
--- 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,20 +1,23 @@
/* 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.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationCompat.Builder;
+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;
@@ -57,16 +60,17 @@ public class FxAccountNotificationManage
* Reflect new Firefox Account state to the notification manager: show or hide
* notifications reflecting the state of a Firefox Account.
*
* @param context
* Android context.
* @param fxAccount
* Firefox Account to reflect to the notification manager.
*/
+ @SuppressWarnings("NewApi")
public void update(Context context, AndroidFxAccount fxAccount) {
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
final State state = fxAccount.getState();
final Action action = state.getNeededAction();
if (action == Action.None) {
Logger.info(LOG_TAG, "State " + state.getStateLabel() + " needs no action; cancelling any existing notification.");
notificationManager.cancel(notificationId);
@@ -95,18 +99,23 @@ public class FxAccountNotificationManage
notificationIntent.putExtra(FxAccountWebFlowActivity.EXTRA_ENDPOINT, FxAccountConstants.ENDPOINT_NOTIFICATION);
Logger.info(LOG_TAG, "State " + state.getStateLabel() + " needs action; offering notification with title: " + title);
FxAccountUtils.pii(LOG_TAG, "And text: " + text);
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
- final Builder builder = new NotificationCompat.Builder(context);
+ final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.ic_status_logo)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
+
+ if (!AppConstants.Versions.preO) {
+ builder.setChannelId(GeckoApplication.getDefaultNotificationChannel().getId());
+ }
+
notificationManager.notify(notificationId, builder.build());
}
}