From 7ffb25ebc2aa4fb7283ccaae152b98d1f02bf756 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Thu, 22 Sep 2016 16:38:19 -0400 Subject: [PATCH] Bug 1304145 - 5. Implement NotificationListener in NotificationClient; r=nalexander Provide Fennec's implementation of GeckoAppShell.NotificationListener in NotificationClient. A lot of the code was removed in an earlier patch from GeckoAppShell, so combined with this patch, we're essentially moving code from GeckoAppShell to NotificationClient. --- .../base/java/org/mozilla/gecko/GeckoApp.java | 21 ++--- .../notifications/NotificationClient.java | 77 ++++++++++++++++++- .../java/org/mozilla/gecko/GeckoAppShell.java | 1 - 3 files changed, 83 insertions(+), 16 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index 7b9b032f8d4c..5bf7fe8cc6ff 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -137,6 +137,7 @@ public abstract class GeckoApp private static final String LOGTAG = "GeckoApp"; private static final long ONE_DAY_MS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS); + public static final String ACTION_ALERT_CALLBACK = "org.mozilla.gecko.ALERT_CALLBACK"; public static final String ACTION_HOMESCREEN_SHORTCUT = "org.mozilla.gecko.BOOKMARK"; public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG"; public static final String ACTION_LAUNCH_SETTINGS = "org.mozilla.gecko.SETTINGS"; @@ -1659,7 +1660,7 @@ public abstract class GeckoApp } } - if (GeckoAppShell.ACTION_ALERT_CALLBACK.equals(action)) { + if (ACTION_ALERT_CALLBACK.equals(action)) { processAlertCallback(intent); } } @@ -1956,7 +1957,9 @@ public abstract class GeckoApp if (alertCookie == null) alertCookie = ""; } - handleNotification(GeckoAppShell.ACTION_ALERT_CALLBACK, alertName, alertCookie); + + ((NotificationClient) GeckoAppShell.getNotificationListener()).onNotificationClick( + alertName); } @Override @@ -2001,7 +2004,7 @@ public abstract class GeckoApp mLayerView.loadUri(uri, GeckoView.LOAD_SWITCH_TAB); } else if (Intent.ACTION_SEARCH.equals(action)) { mLayerView.loadUri(uri, GeckoView.LOAD_NEW_TAB); - } else if (GeckoAppShell.ACTION_ALERT_CALLBACK.equals(action)) { + } else if (ACTION_ALERT_CALLBACK.equals(action)) { processAlertCallback(intent); } else if (NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) { NotificationHelper.getInstance(getApplicationContext()).handleNotificationIntent(intent); @@ -2025,7 +2028,7 @@ public abstract class GeckoApp */ protected String getURIFromIntent(SafeIntent intent) { final String action = intent.getAction(); - if (GeckoAppShell.ACTION_ALERT_CALLBACK.equals(action) || + if (ACTION_ALERT_CALLBACK.equals(action) || NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) { return null; } @@ -2388,16 +2391,6 @@ public abstract class GeckoApp }); } - public void handleNotification(String action, String alertName, String alertCookie) { - // If Gecko isn't running yet, we ignore the notification. Note that - // even if Gecko is running but it was restarted since the notification - // was created, the notification won't be handled (bug 849653). - if (GeckoThread.isRunning()) { - ((NotificationClient) GeckoAppShell.getNotificationListener()).onNotificationClick( - alertName); - } - } - private void checkMigrateProfile() { final File profileDir = getProfile().getDir(); diff --git a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java index 1726b3059489..8dc9bb46cbed 100644 --- a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java +++ b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationClient.java @@ -7,22 +7,97 @@ package org.mozilla.gecko.notifications; import android.app.Notification; import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.text.TextUtils; import android.util.Log; import java.util.LinkedList; import java.util.concurrent.ConcurrentHashMap; +import org.mozilla.gecko.AppConstants; +import org.mozilla.gecko.GeckoApp; +import org.mozilla.gecko.GeckoAppShell; +import org.mozilla.gecko.GeckoService; +import org.mozilla.gecko.NotificationListener; + /** * Client for posting notifications through a NotificationHandler. */ -public abstract class NotificationClient { +public abstract class NotificationClient implements NotificationListener { private static final String LOGTAG = "GeckoNotificationClient"; private volatile NotificationHandler mHandler; private boolean mReady; private final LinkedList mTaskQueue = new LinkedList(); + @Override // NotificationListener + public void showNotification(String name, String cookie, String title, + String text, String host, String imageUrl) + { + // The intent to launch when the user clicks the expanded notification + final Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CALLBACK); + notificationIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, + AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS); + notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // Put the strings into the intent as an URI + // "alert:?name=&cookie=" + final Uri.Builder b = new Uri.Builder(); + final Uri dataUri = b.scheme("alert") + .appendQueryParameter("name", name) + .appendQueryParameter("cookie", cookie) + .build(); + notificationIntent.setData(dataUri); + + final PendingIntent clickIntent = PendingIntent.getActivity( + GeckoAppShell.getApplicationContext(), 0, notificationIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + + add(name, imageUrl, host, title, text, clickIntent, /* closeIntent */ null); + GeckoAppShell.onNotificationShow(name); + } + + @Override // NotificationListener + public void showPersistentNotification(String name, String cookie, String title, + String text, String host, String imageUrl, + String data) + { + final Context context = GeckoAppShell.getApplicationContext(); + + final PendingIntent clickIntent = PendingIntent.getService( + context, 0, GeckoService.getIntentToCreateServices( + context, "persistent-notification-click", data), + PendingIntent.FLAG_UPDATE_CURRENT); + + final PendingIntent closeIntent = PendingIntent.getService( + context, 0, GeckoService.getIntentToCreateServices( + context, "persistent-notification-close", data), + PendingIntent.FLAG_UPDATE_CURRENT); + + add(name, imageUrl, host, title, text, clickIntent, closeIntent); + GeckoAppShell.onNotificationShow(name); + } + + @Override + public void closeNotification(String name) + { + remove(name); + GeckoAppShell.onNotificationClose(name); + } + + public void onNotificationClick(String name) { + GeckoAppShell.onNotificationClick(name); + + if (isOngoing(name)) { + // When clicked, keep the notification if it displays progress + return; + } + + closeNotification(name); + } + /** * Adds a notification. * diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java index 554c924d02bc..30c6cce455fc 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java @@ -229,7 +229,6 @@ public class GeckoAppShell static public final int LINK_TYPE_4G = 7; public static final String PREFS_OOM_EXCEPTION = "OOMException"; - public static final String ACTION_ALERT_CALLBACK = "org.mozilla.gecko.ALERT_CALLBACK"; /* The Android-side API: API methods that Android calls */