Bug 1259127 - Content notifications: Add "Read now" action. r=grisha draft
authorSebastian Kaspari <s.kaspari@gmail.com>
Tue, 26 Apr 2016 14:42:51 +0200
changeset 362790 4bfb9b714b42f0a0259770e054701a3d4592aa87
parent 362789 9c6f93aad7f070a847b5f13ff38bbcabef684cf6
child 519880 299b4acb33e25e33acff17109d95825410d55b96
push id17037
push users.kaspari@gmail.com
push dateTue, 03 May 2016 08:01:11 +0000
reviewersgrisha
bugs1259127
milestone49.0a1
Bug 1259127 - Content notifications: Add "Read now" action. r=grisha This patch adds a "Read now" action to content notifications. Clicking the button will behave like clicking the notification. However it will send a different telemetry extra ("content_update_read_now" instead of "content_update"). MozReview-Commit-ID: 4O24xBhjVF4
mobile/android/base/java/org/mozilla/gecko/feeds/ContentNotificationsDelegate.java
mobile/android/base/java/org/mozilla/gecko/feeds/action/CheckForUpdatesAction.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/drawable-hdpi/open_in_browser.png
mobile/android/base/resources/drawable-hdpi/settings_notifications.png
mobile/android/base/resources/drawable-xhdpi/open_in_browser.png
mobile/android/base/resources/drawable-xhdpi/settings_notifications.png
mobile/android/base/strings.xml.in
--- a/mobile/android/base/java/org/mozilla/gecko/feeds/ContentNotificationsDelegate.java
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/ContentNotificationsDelegate.java
@@ -2,35 +2,40 @@
  * 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.feeds;
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationManagerCompat;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.BrowserAppDelegate;
+import org.mozilla.gecko.R;
 import org.mozilla.gecko.Telemetry;
 import org.mozilla.gecko.TelemetryContract;
 
 import java.util.List;
 
 /**
  * BrowserAppDelegate implementation that takes care of handling intents from content notifications.
  */
 public class ContentNotificationsDelegate extends BrowserAppDelegate {
     // The application is opened from a content notification
     public static final String ACTION_CONTENT_NOTIFICATION = AppConstants.ANDROID_PACKAGE_NAME + ".action.CONTENT_NOTIFICATION";
 
+    public static final String EXTRA_READ_BUTTON = "read_button";
     public static final String EXTRA_URLS = "urls";
 
     private static final String TELEMETRY_EXTRA_CONTENT_UPDATE = "content_update";
+    private static final String TELEMETRY_EXTRA_READ_NOW_BUTTON = TELEMETRY_EXTRA_CONTENT_UPDATE + "_read_now";
 
     @Override
     public void onCreate(BrowserApp browserApp, Bundle savedInstanceState) {
         final Intent intent = browserApp.getIntent();
 
         if (savedInstanceState != null) {
             // This activity is getting restored: We do not want to handle the URLs in the Intent again. The browser
             // will take care of restoring the tabs we already created.
@@ -52,14 +57,24 @@ public class ContentNotificationsDelegat
     private void openURLsFromIntent(BrowserApp browserApp, final Intent intent) {
         final List<String> urls = intent.getStringArrayListExtra(EXTRA_URLS);
         if (urls != null) {
             browserApp.openUrls(urls);
         }
 
         Telemetry.startUISession(TelemetryContract.Session.EXPERIMENT, FeedService.getEnabledExperiment(browserApp));
 
-        Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.NOTIFICATION, TELEMETRY_EXTRA_CONTENT_UPDATE);
         Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.INTENT, TELEMETRY_EXTRA_CONTENT_UPDATE);
 
+        if (intent.getBooleanExtra(EXTRA_READ_BUTTON, false)) {
+            // "READ NOW" button in notification was clicked
+            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.NOTIFICATION, TELEMETRY_EXTRA_READ_NOW_BUTTON);
+
+            // Android's "auto cancel" won't remove the notification when an action button is pressed. So we do it ourselves here.
+            NotificationManagerCompat.from(browserApp).cancel(R.id.websiteContentNotification);
+        } else {
+            // Notification was clicked
+            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.NOTIFICATION, TELEMETRY_EXTRA_CONTENT_UPDATE);
+        }
+
         Telemetry.stopUISession(TelemetryContract.Session.EXPERIMENT, FeedService.getEnabledExperiment(browserApp));
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/feeds/action/CheckForUpdatesAction.java
+++ b/mobile/android/base/java/org/mozilla/gecko/feeds/action/CheckForUpdatesAction.java
@@ -174,16 +174,17 @@ public class CheckForUpdatesAction exten
         final Notification notification = new NotificationCompat.Builder(context)
                 .setSmallIcon(R.drawable.ic_status_logo)
                 .setContentTitle(feed.getTitle())
                 .setContentText(feed.getLastItem().getTitle())
                 .setStyle(style)
                 .setColor(ContextCompat.getColor(context, R.color.fennec_ui_orange))
                 .setContentIntent(pendingIntent)
                 .setAutoCancel(true)
+                .addAction(createOpenAction(feed))
                 .addAction(createNotificationSettingsAction())
                 .build();
 
         NotificationManagerCompat.from(context).notify(R.id.websiteContentNotification, notification);
     }
 
     private void showNotificationForMultipleUpdates(List<Feed> feeds) {
         final NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
@@ -197,16 +198,17 @@ public class CheckForUpdatesAction exten
         Notification notification = new NotificationCompat.Builder(context)
                 .setSmallIcon(R.drawable.ic_status_logo)
                 .setContentTitle(context.getString(R.string.content_notification_title_plural, feeds.size()))
                 .setContentText(context.getString(R.string.content_notification_summary))
                 .setStyle(inboxStyle)
                 .setColor(ContextCompat.getColor(context, R.color.fennec_ui_orange))
                 .setContentIntent(pendingIntent)
                 .setAutoCancel(true)
+                .addAction(createOpenAction(feeds))
                 .setNumber(feeds.size())
                 .addAction(createNotificationSettingsAction())
                 .build();
 
         NotificationManagerCompat.from(context).notify(R.id.websiteContentNotification, notification);
     }
 
     private Intent createOpenIntent(Feed feed) {
@@ -224,27 +226,46 @@ public class CheckForUpdatesAction exten
 
         final Intent intent = new Intent(context, BrowserApp.class);
         intent.setAction(ContentNotificationsDelegate.ACTION_CONTENT_NOTIFICATION);
         intent.putStringArrayListExtra(ContentNotificationsDelegate.EXTRA_URLS, urls);
 
         return intent;
     }
 
+    private NotificationCompat.Action createOpenAction(Feed feed) {
+        final List<Feed> feeds = new ArrayList<>();
+        feeds.add(feed);
+
+        return createOpenAction(feeds);
+    }
+
+    private NotificationCompat.Action createOpenAction(List<Feed> feeds) {
+        Intent intent = createOpenIntent(feeds);
+        intent.putExtra(ContentNotificationsDelegate.EXTRA_READ_BUTTON, true);
+
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+        return new NotificationCompat.Action(
+                R.drawable.open_in_browser,
+                context.getString(R.string.content_notification_action_read_now),
+                pendingIntent);
+    }
+
     private NotificationCompat.Action createNotificationSettingsAction() {
         final Intent intent = new Intent(GeckoApp.ACTION_LAUNCH_SETTINGS);
         intent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
         intent.putExtra(EXTRA_CONTENT_NOTIFICATION, true);
 
         GeckoPreferences.setResourceToOpen(intent, "preferences_notifications");
 
         PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
 
         return new NotificationCompat.Action(
-                R.drawable.firefox_settings_alert,
+                R.drawable.settings_notifications,
                 context.getString(R.string.content_notification_action_settings),
                 settingsIntent);
     }
 
     private FeedFetcher.FeedResponse fetchFeed(FeedSubscription subscription) {
         return FeedFetcher.fetchAndParseFeedIfModified(
                 subscription.getFeedUrl(),
                 subscription.getETag(),
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -282,17 +282,22 @@
 <!ENTITY tab_queue_notification_settings "To \&quot;Open multiple links\&quot;, please enable the \'Draw over other apps\' permission for &brandShortName;">
 
 <!ENTITY content_notification_summary "&brandShortName;">
 <!-- Localization note (content_notification_title_plural): &formatD; will be replaced with the number of websites that
      have been updated (new content is available). The number of websites is always more than one (>= 2). For a single
      update the website title is used instead of this string.
      We can't use Android plural forms, sadly. See Bug #753859. -->
 <!ENTITY content_notification_title_plural "&formatD; websites updated">
-<!ENTITY content_notification_action_settings "Notifications Setting">
+<!-- Localization note (content_notification_action_settings2): This label will be shown as an action in a content notification.
+     Clicking the action will jump to the notification settings of the app. -->
+<!ENTITY content_notification_action_settings2 "Settings">
+<!-- Localization note(content_notification_action_read_now): This label will be shown as an action in a content notification.
+     Clicking the action will open all new content in the browser. -->
+<!ENTITY content_notification_action_read_now "Read now">
 <!-- Localization note (content_notification_updated_on): &formatS; will be replaced with a medium sized version of the
      date, depending on locale. For en_US this is for example: Feb 24, 2016. For more details see the Android developer
      documentation for DateFormat.getMediumDateFormat(). -->
 <!ENTITY content_notification_updated_on "Updated on &formatS;">
 
 <!ENTITY pref_char_encoding "Character encoding">
 <!ENTITY pref_char_encoding_on "Show menu">
 <!ENTITY pref_char_encoding_off "Don\'t show menu">
new file mode 100644
index 0000000000000000000000000000000000000000..e78d96665dab927ed3fbff20f7a9fdd76fa23eda
GIT binary patch
literal 194
zc%17D@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8r>Bc!NCo5DD~?=;3<O#q?rgu&
z%<;|ZsPrCYuf5(U&Hk-px^&ZLxyQ;U^}8MRxr%MPw=+3qnb6y_-GbT1x7fI%wPS2e
zCT4z`aAL`4heJ)5?H!ydPt1Ma>f&9k@Nw>@2@%VARB9H)+kE>N&@Q)T^6mvE!mR_$
toVmsMCCk&YBv#q%OyoQDR$zs*{MGX50^2mto(4LK!PC{xWt~$(696AZOQHY(
new file mode 100644
index 0000000000000000000000000000000000000000..d2b23cf74ac46c7b61871a95fa04ee538f83ffc9
GIT binary patch
literal 385
zc$@)&0e=38P)<h;3K|Lk000e1NJLTq001Na001Ni1ONa4O9@aD0003<Nkl<Zcmd_r
zGyK*;0LSrfwr$(CjX4`@uIXv2CEIRmYHDlAw(b6Q)+gR$+^-v-_f4nI>$X!;qb+Ua
zjza((k~d7DN7!qOwz9`GzLP^|$zUMHK-ptI09mw`Bx<mcRE*cGqqgi&m_q=h(^{f5
zCkgeA*<MpAG?OULWx_4<ntDYei7MPC)DMQ)r!oL|Mm>pIJSNmVipT~%F&<G%q5-c6
zHBvU%M!;RFOSB-3V7q05vjn?I6^RaH2d~KnuLyO83KBgjz{rsez7g&m<s=62k-xsn
z2GN|Pw8U7x@W=m$;5a2E#`E1Z1ji^YF`FN*Avj7=iTUm!I6@JL<?bOkOkvp}k=+zh
zVyqysE$$g(t$W5;so3zwr&#b=j!pakV2NBYmmi)!De^G#qNKLS7OOE<D-3;PkK(K*
fk33dWT*>MuiI+DAC?aX%00000NkvXXu0mjfVpgT?
new file mode 100644
index 0000000000000000000000000000000000000000..c03c0207b1ac95684222da59be7ed2a4dce77831
GIT binary patch
literal 212
zc%17D@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0D*`6+rAr*{oulaHvRuFMb3=fWZ
zb~mt2EX?W5pDBDyN`?WoVodMvEPP;IyYS3s8zp1wwX$nmoc1~FJK>fuy^-%s#Fi_K
zvfV+l2B#Pb6t=w8Z(w#(X8h>8n4xf)V8e;YrV6K0I6GFSuy#akVmK1}iq-0#JeS3T
z0|!&L^4Hn#2@_7(Wm~tq(R@9VMn~%v9+hQ(ehV4gdd$Es^Mhf{v5$Ly8ZCbTbS8tR
LtDnm{r-UW|J&#Xv
new file mode 100644
index 0000000000000000000000000000000000000000..3e96f6deb5661fec3f515ef1d54aab551cf05ae1
GIT binary patch
literal 493
zc$@+40TTX+P)<h;3K|Lk000e1NJLTq001xm001xu1ONa4{R=S+0005BNkl<ZcmeIz
z1FT#@6oBE{wr$(C8`N$18q|ntMYS2#-JouR+P3ZX+4kRLGI_a7I`?+M{o*r|^RG9b
zK~NAySVt(KtfPpYz&eoD`CC+-OVoFmhk_L9XMGJm0N<!%J2CJRxCX*!Y8a-?ScTDI
z8h8yfAryr7RF$(e<YIS*rrr`w^AfMABqkMjg_BIC`%OHjyqHwu6V8@;O@txvh%#bQ
zm!CMvWxTgUv%JI|O38O80w*z4@cYHOPH{15Lo7}<ds$z=^paepsF-#o3A=cTs|N;S
zcAmmw-k&t=CaDMZVReE+;$#$=SnW~|+{Z3J0dY2w9Lyf52O@BCfc)Y#gj|gNs0Y$<
zwojhV!zfKX;BK3|u>ynt8G!Zj&IVlpSR-%k)fIpx^6Pj+R{$1@dxbcyD*!Xa&7xe=
z704w-+%3r+JpssJnz&t7R{*l*AC9&FWHDBK{VG&sFkI()fHVf`Tn~^!Z=LG_66y9Y
z0YBpDs5byHw8^IfP51*s1kH6Pu6tV$iczR*;sZ6j1p*iaT%N@>xn3Q$hyf{vS~_0k
jS_B9slz@iy8U_6YxMYF<6Oo$W00000NkvXXu0mjf4>#9b
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -294,17 +294,18 @@
   <string name="tab_queue_toast_action">&tab_queue_toast_action;</string>
   <string name="tab_queue_notification_text_singular">&tab_queue_notification_text_singular2;</string>
   <string name="tab_queue_notification_text_plural">&tab_queue_notification_text_plural2;</string>
   <string name="tab_queue_notification_title">&tab_queue_notification_title;</string>
   <string name="tab_queue_notification_settings">&tab_queue_notification_settings;</string>
 
   <string name="content_notification_summary">&content_notification_summary;</string>
   <string name="content_notification_title_plural">&content_notification_title_plural;</string>
-  <string name="content_notification_action_settings">&content_notification_action_settings;</string>
+  <string name="content_notification_action_settings">&content_notification_action_settings2;</string>
+  <string name="content_notification_action_read_now">&content_notification_action_read_now;</string>
   <string name="content_notification_updated_on">&content_notification_updated_on;</string>
 
   <string name="pref_default_browser">&pref_default_browser;</string>
 
   <string name="pref_about_firefox">&pref_about_firefox;</string>
 
   <string name="pref_vendor_faqs">&pref_vendor_faqs;</string>
   <!-- https://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/faq -->