Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/ntp/ContentSuggestionsNotificationHelper.java

Issue 2639553002: Track active notifications in Java (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.ntp; 5 package org.chromium.chrome.browser.ntp;
6 6
7 import android.annotation.TargetApi;
8 import android.app.AlarmManager; 7 import android.app.AlarmManager;
9 import android.app.NotificationManager; 8 import android.app.NotificationManager;
10 import android.app.PendingIntent; 9 import android.app.PendingIntent;
11 import android.content.BroadcastReceiver; 10 import android.content.BroadcastReceiver;
12 import android.content.Context; 11 import android.content.Context;
13 import android.content.Intent; 12 import android.content.Intent;
14 import android.content.SharedPreferences; 13 import android.content.SharedPreferences;
15 import android.graphics.Bitmap; 14 import android.graphics.Bitmap;
16 import android.net.Uri; 15 import android.net.Uri;
17 import android.os.Build;
18 import android.provider.Browser; 16 import android.provider.Browser;
19 import android.service.notification.StatusBarNotification;
20 import android.support.v4.app.NotificationCompat; 17 import android.support.v4.app.NotificationCompat;
21 18
22 import org.chromium.base.ContextUtils; 19 import org.chromium.base.ContextUtils;
23 import org.chromium.base.annotations.CalledByNative; 20 import org.chromium.base.annotations.CalledByNative;
24 import org.chromium.base.annotations.JNINamespace; 21 import org.chromium.base.annotations.JNINamespace;
25 import org.chromium.base.library_loader.LibraryLoader; 22 import org.chromium.base.library_loader.LibraryLoader;
26 import org.chromium.chrome.R; 23 import org.chromium.chrome.R;
27 import org.chromium.chrome.browser.IntentHandler; 24 import org.chromium.chrome.browser.IntentHandler;
28 import org.chromium.chrome.browser.ShortcutHelper; 25 import org.chromium.chrome.browser.ShortcutHelper;
29 import org.chromium.chrome.browser.document.ChromeLauncherActivity; 26 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
27 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsNotificationAc tion;
28
29 import java.util.HashSet;
30 import java.util.Set;
30 31
31 /** 32 /**
32 * Provides functionality needed for content suggestion notifications. 33 * Provides functionality needed for content suggestion notifications.
33 * 34 *
34 * Exposes helper functions to native C++ code. 35 * Exposes helper functions to native C++ code.
35 */ 36 */
36 @JNINamespace("ntp_snippets") 37 @JNINamespace("ntp_snippets")
37 public class ContentSuggestionsNotificationHelper { 38 public class ContentSuggestionsNotificationHelper {
38 private static final String NOTIFICATION_TAG = "ContentSuggestionsNotificati on"; 39 private static final String NOTIFICATION_TAG = "ContentSuggestionsNotificati on";
39 private static final String NOTIFICATION_ID_EXTRA = "notification_id"; 40 private static final String NOTIFICATION_ID_EXTRA = "notification_id";
41 private static final String NOTIFICATION_CATEGORY_EXTRA = "category";
42 private static final String NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA = "id_with in_category";
40 43
41 private static final String PREF_CACHED_ACTION_TAP = 44 private static final String PREF_CACHED_ACTION_TAP =
42 "ntp.content_suggestions.notification.cached_action_tap"; 45 "ntp.content_suggestions.notification.cached_action_tap";
43 private static final String PREF_CACHED_ACTION_DISMISSAL = 46 private static final String PREF_CACHED_ACTION_DISMISSAL =
44 "ntp.content_suggestions.notification.cached_action_dismissal"; 47 "ntp.content_suggestions.notification.cached_action_dismissal";
45 private static final String PREF_CACHED_ACTION_HIDE_DEADLINE = 48 private static final String PREF_CACHED_ACTION_HIDE_DEADLINE =
46 "ntp.content_suggestions.notification.cached_action_hide_deadline"; 49 "ntp.content_suggestions.notification.cached_action_hide_deadline";
50 private static final String PREF_CACHED_ACTION_HIDE_EXPIRY =
51 "ntp.content_suggestions.notification.cached_action_hide_expiry";
52 private static final String PREF_CACHED_ACTION_HIDE_FRONTMOST =
53 "ntp.content_suggestions.notification.cached_action_hide_frontmost";
54 private static final String PREF_CACHED_ACTION_HIDE_DISABLED =
55 "ntp.content_suggestions.notification.cached_action_hide_disabled";
56 private static final String PREF_CACHED_ACTION_HIDE_SHUTDOWN =
57 "ntp.content_suggestions.notification.cached_action_hide_shutdown";
47 private static final String PREF_CACHED_CONSECUTIVE_IGNORED = 58 private static final String PREF_CACHED_CONSECUTIVE_IGNORED =
48 "ntp.content_suggestions.notification.cached_consecutive_ignored"; 59 "ntp.content_suggestions.notification.cached_consecutive_ignored";
49 60
61 // Tracks which URIs there is an active notification for.
62 private static final String PREF_ACTIVE_NOTIFICATIONS =
63 "ntp.content_suggestions.notification.active";
64
50 private ContentSuggestionsNotificationHelper() {} // Prevent instantiation 65 private ContentSuggestionsNotificationHelper() {} // Prevent instantiation
51 66
52 /** 67 /**
53 * Opens the content suggestion when notification is tapped. 68 * Opens the content suggestion when notification is tapped.
54 */ 69 */
55 public static final class OpenUrlReceiver extends BroadcastReceiver { 70 public static final class OpenUrlReceiver extends BroadcastReceiver {
56 public void onReceive(Context context, Intent intent) { 71 public void onReceive(Context context, Intent intent) {
72 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
73 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
57 openUrl(intent.getData()); 74 openUrl(intent.getData());
58 recordCachedActionMetric(PREF_CACHED_ACTION_TAP); 75 recordCachedActionMetric(ContentSuggestionsNotificationAction.CONTEN T_SUGGESTIONS_TAP);
76 removeActiveNotification(category, idWithinCategory);
59 } 77 }
60 } 78 }
61 79
62 /** 80 /**
63 * Records dismissal when notification is swiped away. 81 * Records dismissal when notification is swiped away.
64 */ 82 */
65 public static final class DeleteReceiver extends BroadcastReceiver { 83 public static final class DeleteReceiver extends BroadcastReceiver {
66 public void onReceive(Context context, Intent intent) { 84 public void onReceive(Context context, Intent intent) {
67 recordCachedActionMetric(PREF_CACHED_ACTION_DISMISSAL); 85 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
86 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
87 recordCachedActionMetric(
88 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DIS MISSAL);
89 removeActiveNotification(category, idWithinCategory);
68 } 90 }
69 } 91 }
70 92
71 /** 93 /**
72 * Removes the notification after a timeout period. 94 * Removes the notification after a timeout period.
73 */ 95 */
74 public static final class TimeoutReceiver extends BroadcastReceiver { 96 public static final class TimeoutReceiver extends BroadcastReceiver {
75 public void onReceive(Context context, Intent intent) { 97 public void onReceive(Context context, Intent intent) {
98 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
99 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
100 if (findActiveNotification(category, idWithinCategory) == null) {
101 return; // tapped or swiped
102 }
103
76 int id = intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1); 104 int id = intent.getIntExtra(NOTIFICATION_ID_EXTRA, -1);
77 if (id < 0) return; 105 hideNotification(category, idWithinCategory,
78 hideNotification(id); 106 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HID E_DEADLINE);
79 recordCachedActionMetric(PREF_CACHED_ACTION_HIDE_DEADLINE);
80 } 107 }
81 } 108 }
82 109
83 private static void openUrl(Uri uri) { 110 private static void openUrl(Uri uri) {
84 Context context = ContextUtils.getApplicationContext(); 111 Context context = ContextUtils.getApplicationContext();
85 Intent intent = new Intent() 112 Intent intent = new Intent()
86 .setAction(Intent.ACTION_VIEW) 113 .setAction(Intent.ACTION_VIEW)
87 .setData(uri) 114 .setData(uri)
88 .setClass(context, ChromeLauncherActivity.class) 115 .setClass(context, ChromeLauncherActivity.class)
89 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 116 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
90 .putExtra(Browser.EXTRA_APPLICATION_ID, context. getPackageName()) 117 .putExtra(Browser.EXTRA_APPLICATION_ID, context. getPackageName())
91 .putExtra(ShortcutHelper.REUSE_URL_MATCHING_TAB_ ELSE_NEW_TAB, true); 118 .putExtra(ShortcutHelper.REUSE_URL_MATCHING_TAB_ ELSE_NEW_TAB, true);
92 IntentHandler.addTrustedIntentExtras(intent); 119 IntentHandler.addTrustedIntentExtras(intent);
93 context.startActivity(intent); 120 context.startActivity(intent);
94 } 121 }
95 122
96 @TargetApi(Build.VERSION_CODES.M)
97 @CalledByNative 123 @CalledByNative
98 private static void showNotification( 124 private static boolean showNotification(int category, String idWithinCategor y, String url,
99 String url, String title, String text, Bitmap image, long timeoutAtM illis) { 125 String title, String text, Bitmap image, long timeoutAtMillis) {
126 if (findActiveNotification(category, idWithinCategory) != null) return f alse;
127
100 // Post notification. 128 // Post notification.
101 Context context = ContextUtils.getApplicationContext(); 129 Context context = ContextUtils.getApplicationContext();
102 NotificationManager manager = 130 NotificationManager manager =
103 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE); 131 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE);
104 132
105 // Find an available notification ID. 133 int nextId = nextNotificationId();
106 int nextId = 0; 134 Uri uri = Uri.parse(url);
107 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 135 Intent contentIntent =
108 for (StatusBarNotification activeNotification : manager.getActiveNot ifications()) { 136 new Intent(context, OpenUrlReceiver.class)
109 if (activeNotification.getTag() != NOTIFICATION_TAG) continue; 137 .setData(uri)
110 if (activeNotification.getId() >= nextId) { 138 .putExtra(NOTIFICATION_CATEGORY_EXTRA, category)
111 nextId = activeNotification.getId() + 1; 139 .putExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA, idWithi nCategory);
112 } 140 Intent deleteIntent =
113 } 141 new Intent(context, DeleteReceiver.class)
114 } 142 .setData(uri)
115 143 .putExtra(NOTIFICATION_CATEGORY_EXTRA, category)
116 Intent contentIntent = new Intent(context, OpenUrlReceiver.class).setDat a(Uri.parse(url)); 144 .putExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA, idWithi nCategory);
117 Intent deleteIntent = new Intent(context, DeleteReceiver.class).setData( Uri.parse(url));
118 NotificationCompat.Builder builder = 145 NotificationCompat.Builder builder =
119 new NotificationCompat.Builder(context) 146 new NotificationCompat.Builder(context)
120 .setAutoCancel(true) 147 .setAutoCancel(true)
121 .setContentIntent(PendingIntent.getBroadcast(context, 0, contentIntent, 0)) 148 .setContentIntent(PendingIntent.getBroadcast(context, 0, contentIntent, 0))
122 .setDeleteIntent(PendingIntent.getBroadcast(context, 0, deleteIntent, 0)) 149 .setDeleteIntent(PendingIntent.getBroadcast(context, 0, deleteIntent, 0))
123 .setContentTitle(title) 150 .setContentTitle(title)
124 .setContentText(text) 151 .setContentText(text)
125 .setGroup(NOTIFICATION_TAG) 152 .setGroup(NOTIFICATION_TAG)
126 .setLargeIcon(image) 153 .setLargeIcon(image)
127 .setSmallIcon(R.drawable.ic_chrome); 154 .setSmallIcon(R.drawable.ic_chrome);
128 manager.notify(NOTIFICATION_TAG, nextId, builder.build()); 155 manager.notify(NOTIFICATION_TAG, nextId, builder.build());
156 addActiveNotification(new ActiveNotification(nextId, category, idWithinC ategory, uri));
129 157
130 // Set timeout. 158 // Set timeout.
131 if (timeoutAtMillis != Long.MAX_VALUE) { 159 if (timeoutAtMillis != Long.MAX_VALUE) {
132 AlarmManager alarmManager = 160 AlarmManager alarmManager =
133 (AlarmManager) context.getSystemService(Context.ALARM_SERVIC E); 161 (AlarmManager) context.getSystemService(Context.ALARM_SERVIC E);
134 Intent timeoutIntent = new Intent(context, TimeoutReceiver.class) 162 Intent timeoutIntent =
135 .setData(Uri.parse(url)) 163 new Intent(context, TimeoutReceiver.class)
136 .putExtra(NOTIFICATION_ID_EXTRA, next Id); 164 .setData(Uri.parse(url))
165 .putExtra(NOTIFICATION_ID_EXTRA, nextId)
166 .putExtra(NOTIFICATION_CATEGORY_EXTRA, category)
167 .putExtra(NOTIFICATION_ID_WITHIN_CATEGORY_EXTRA, idW ithinCategory);
137 alarmManager.set(AlarmManager.RTC, timeoutAtMillis, 168 alarmManager.set(AlarmManager.RTC, timeoutAtMillis,
138 PendingIntent.getBroadcast( 169 PendingIntent.getBroadcast(
139 context, 0, timeoutIntent, PendingIntent.FLAG_UPDATE _CURRENT)); 170 context, 0, timeoutIntent, PendingIntent.FLAG_UPDATE _CURRENT));
140 } 171 }
172 return true;
141 } 173 }
142 174
143 private static void hideNotification(int id) { 175 @CalledByNative
176 private static void hideNotification(int category, String idWithinCategory, int why) {
144 Context context = ContextUtils.getApplicationContext(); 177 Context context = ContextUtils.getApplicationContext();
145 NotificationManager manager = 178 NotificationManager manager =
146 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE); 179 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE);
147 manager.cancel(NOTIFICATION_TAG, id); 180 if (removeActiveNotification(category, idWithinCategory)) {
181 recordCachedActionMetric(why);
182 }
148 } 183 }
149 184
150 @TargetApi(Build.VERSION_CODES.M)
151 @CalledByNative 185 @CalledByNative
152 private static void hideAllNotifications() { 186 private static void hideAllNotifications(int why) {
153 Context context = ContextUtils.getApplicationContext(); 187 Context context = ContextUtils.getApplicationContext();
154 NotificationManager manager = 188 NotificationManager manager =
155 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE); 189 (NotificationManager) context.getSystemService(Context.NOTIFICAT ION_SERVICE);
156 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 190 for (ActiveNotification activeNotification : getActiveNotifications()) {
157 for (StatusBarNotification activeNotification : manager.getActiveNot ifications()) { 191 manager.cancel(NOTIFICATION_TAG, activeNotification.mId);
158 if (activeNotification.getTag() == NOTIFICATION_TAG) { 192 recordCachedActionMetric(why);
159 manager.cancel(NOTIFICATION_TAG, activeNotification.getId()) ;
160 }
161 }
162 } else {
163 manager.cancel(NOTIFICATION_TAG, 0);
164 } 193 }
165 } 194 }
166 195
196 private static class ActiveNotification {
197 int mId;
Bernhard Bauer 2017/01/17 15:56:55 Can you make these final?
sfiera 2017/01/17 17:32:08 Done.
198 int mCategory;
199 String mIdWithinCategory;
200 Uri mUri;
201
202 ActiveNotification(int id, int category, String idWithinCategory, Uri ur i) {
203 mId = id;
204 mCategory = category;
205 mIdWithinCategory = idWithinCategory;
206 mUri = uri;
207 }
208
209 /** Parses the fields out of a chrome://content-suggestions-notification URI */
210 static ActiveNotification fromUri(Uri notificationUri) {
211 if (!notificationUri.getScheme().equals("chrome")) return null;
Bernhard Bauer 2017/01/17 15:56:55 We shouldn't really get a malformed URL here, righ
sfiera 2017/01/17 17:32:08 Sure, done.
Bernhard Bauer 2017/01/17 18:01:06 Integer.parseInt() might choke though, right? Anyw
212 if (!notificationUri.getAuthority().equals("content-suggestions-noti fication")) {
213 return null;
214 }
215 if (notificationUri.getQueryParameter("id") == null) return null;
216 if (notificationUri.getQueryParameter("category") == null) return nu ll;
217 if (notificationUri.getQueryParameter("idWithinCategory") == null) r eturn null;
218 if (notificationUri.getQueryParameter("uri") == null) return null;
219
220 return new ActiveNotification(Integer.parseInt(notificationUri.getQu eryParameter("id")),
221 Integer.parseInt(notificationUri.getQueryParameter("category ")),
222 notificationUri.getQueryParameter("idWithinCategory"),
223 Uri.parse(notificationUri.getQueryParameter("uri")));
224 }
225
226 /** Serializes the fields to a chrome://content-suggestions-notification URI */
227 Uri toUri() {
228 return new Uri.Builder()
229 .scheme("chrome")
230 .authority("content-suggestions-notification")
231 .appendQueryParameter("id", Integer.toString(mId))
232 .appendQueryParameter("category", Integer.toString(mCategory ))
233 .appendQueryParameter("idWithinCategory", mIdWithinCategory)
234 .appendQueryParameter("uri", mUri.toString())
235 .build();
236 }
237 }
238
239 private static void addActiveNotification(ActiveNotification notification) {
240 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
241 Set<String> activeNotifications = prefs.getStringSet(PREF_ACTIVE_NOTIFIC ATIONS, null);
242 if (activeNotifications == null) activeNotifications = new HashSet<Strin g>();
243 activeNotifications.add(notification.toUri().toString());
Bernhard Bauer 2017/01/17 15:56:55 You are not allowed to modify the set returned by
sfiera 2017/01/17 17:32:08 Done.
244 prefs.edit().putStringSet(PREF_ACTIVE_NOTIFICATIONS, activeNotifications ).apply();
245 }
246
247 private static boolean removeActiveNotification(int category, String idWithi nCategory) {
248 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
249 ActiveNotification notification = findActiveNotification(category, idWit hinCategory);
250 if (notification == null) return false;
251
252 Set<String> activeNotifications = prefs.getStringSet(PREF_ACTIVE_NOTIFIC ATIONS, null);
253 if (activeNotifications == null) return false;
254 boolean result = activeNotifications.remove(notification.toUri().toStrin g());
255 prefs.edit().putStringSet(PREF_ACTIVE_NOTIFICATIONS, activeNotifications ).apply();
256 return result;
257 }
258
259 private static Set<ActiveNotification> getActiveNotifications() {
260 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
261 Set<String> activeNotifications = prefs.getStringSet(PREF_ACTIVE_NOTIFIC ATIONS, null);
262 if (activeNotifications == null) return new HashSet<ActiveNotification>( );
263
264 Set<ActiveNotification> result = new HashSet<ActiveNotification>();
265 for (String serialized : activeNotifications) {
266 Uri notificationUri = Uri.parse(serialized);
267 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri);
268 if (activeNotification != null) result.add(activeNotification);
269 }
270 return result;
271 }
272
273 private static ActiveNotification findActiveNotification(
274 int category, String idWithinCategory) {
275 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
276 Set<String> activeNotifications = prefs.getStringSet(PREF_ACTIVE_NOTIFIC ATIONS, null);
277 if (activeNotifications == null) return null;
278
279 for (String serialized : activeNotifications) {
280 Uri notificationUri = Uri.parse(serialized);
281 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri);
282 if ((activeNotification != null) && (activeNotification.mCategory == category)
283 && (activeNotification.mIdWithinCategory.equals(idWithinCate gory))) {
284 return activeNotification;
285 }
286 }
287 return null;
288 }
289
290 private static int nextNotificationId() {
291 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
292 Set<String> activeNotifications = prefs.getStringSet(PREF_ACTIVE_NOTIFIC ATIONS, null);
293 if (activeNotifications == null) return 0;
294
295 int nextId = 0;
296 for (String serialized : activeNotifications) {
297 Uri notificationUri = Uri.parse(serialized);
298 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri);
299 if ((activeNotification != null) && (activeNotification.mId >= nextI d)) {
300 nextId = activeNotification.mId + 1;
301 }
302 }
303 return nextId;
304 }
305
306 public static String cachedMetricNameForAction(
Bernhard Bauer 2017/01/17 15:56:55 Javadoc for public methods please.
sfiera 2017/01/17 17:32:08 Oops, shouldn't have been public.
307 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum
308 int action) {
309 switch (action) {
310 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_TAP:
311 return PREF_CACHED_ACTION_TAP;
312 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DISMIS SAL:
313 return PREF_CACHED_ACTION_DISMISSAL;
314 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D EADLINE:
315 return PREF_CACHED_ACTION_HIDE_DEADLINE;
316 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_E XPIRY:
317 return PREF_CACHED_ACTION_HIDE_EXPIRY;
318 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_F RONTMOST:
319 return PREF_CACHED_ACTION_HIDE_FRONTMOST;
320 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D ISABLED:
321 return PREF_CACHED_ACTION_HIDE_DISABLED;
322 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_S HUTDOWN:
323 return PREF_CACHED_ACTION_HIDE_SHUTDOWN;
324 }
325 return "";
326 }
327
167 /** 328 /**
168 * Records that an action was performed on a notification. 329 * Records that an action was performed on a notification.
169 * 330 *
170 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or 331 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or
171 * otherwise incrementing it. 332 * otherwise incrementing it.
172 * 333 *
173 * This method may be called when the native library is not loaded. If it is loaded, the metrics 334 * This method may be called when the native library is not loaded. If it is loaded, the metrics
174 * will immediately be sent to C++. If not, it will cache them for a later c all to 335 * will immediately be sent to C++. If not, it will cache them for a later c all to
175 * flushCachedMetrics(). 336 * flushCachedMetrics().
176 * 337 *
177 * @param prefName The name of the action metric pref to update (<tt>PREF_CA CHED_ACTION_*</tt>) 338 * @param action The action to update the pref for.
178 */ 339 */
179 private static void recordCachedActionMetric(String prefName) { 340 private static void recordCachedActionMetric(
180 assert prefName.startsWith("ntp.content_suggestions.notification.cached_ action_"); 341 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum
342 int action) {
343 String prefName = cachedMetricNameForAction(action);
344 assert !prefName.isEmpty();
181 345
182 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); 346 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
183 int currentValue = prefs.getInt(prefName, 0); 347 int currentValue = prefs.getInt(prefName, 0);
184 int consecutiveIgnored = 0; 348 int consecutiveIgnored = 0;
185 if (!prefName.equals(PREF_CACHED_ACTION_TAP)) { 349 if (action != ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_T AP) {
186 consecutiveIgnored = 1 + prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORE D, 0); 350 consecutiveIgnored = 1 + prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORE D, 0);
187 } 351 }
188 prefs.edit() 352 prefs.edit()
189 .putInt(prefName, currentValue + 1) 353 .putInt(prefName, currentValue + 1)
190 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored) 354 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored)
191 .apply(); 355 .apply();
192 356
193 if (LibraryLoader.isInitialized()) { 357 if (LibraryLoader.isInitialized()) {
194 flushCachedMetrics(); 358 flushCachedMetrics();
195 } 359 }
196 } 360 }
197 361
198 /** 362 /**
199 * Invokes nativeReceiveFlushedMetrics() with cached metrics and resets them . 363 * Invokes nativeReceiveFlushedMetrics() with cached metrics and resets them .
200 * 364 *
201 * It may be called from either native or Java code, as long as the native l ibray is loaded. 365 * It may be called from either native or Java code, as long as the native l ibray is loaded.
202 */ 366 */
203 @CalledByNative 367 @CalledByNative
204 private static void flushCachedMetrics() { 368 private static void flushCachedMetrics() {
205 assert LibraryLoader.isInitialized(); 369 assert LibraryLoader.isInitialized();
206 370
207 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); 371 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
208 int tapCount = prefs.getInt(PREF_CACHED_ACTION_TAP, 0); 372 int tapCount = prefs.getInt(PREF_CACHED_ACTION_TAP, 0);
209 int dismissalCount = prefs.getInt(PREF_CACHED_ACTION_DISMISSAL, 0); 373 int dismissalCount = prefs.getInt(PREF_CACHED_ACTION_DISMISSAL, 0);
210 int hideDeadlineCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_DEADLINE, 0 ); 374 int hideDeadlineCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_DEADLINE, 0 );
375 int hideExpiryCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_EXPIRY, 0);
376 int hideFrontmostCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_FRONTMOST, 0);
377 int hideDisabledCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_DISABLED, 0 );
378 int hideShutdownCount = prefs.getInt(PREF_CACHED_ACTION_HIDE_SHUTDOWN, 0 );
211 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 ); 379 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 );
212 380
213 if (tapCount > 0 || dismissalCount > 0 || hideDeadlineCount > 0) { 381 if (tapCount > 0 || dismissalCount > 0 || hideDeadlineCount > 0 || hideE xpiryCount > 0
382 || hideFrontmostCount > 0 || hideDisabledCount > 0 || hideShutdo wnCount > 0) {
214 nativeReceiveFlushedMetrics(tapCount, dismissalCount, hideDeadlineCo unt, 383 nativeReceiveFlushedMetrics(tapCount, dismissalCount, hideDeadlineCo unt,
215 consecutiveIgnored); 384 hideExpiryCount, hideFrontmostCount, hideDisabledCount, hide ShutdownCount,
385 consecutiveIgnored);
216 prefs.edit() 386 prefs.edit()
217 .remove(PREF_CACHED_ACTION_TAP) 387 .remove(PREF_CACHED_ACTION_TAP)
218 .remove(PREF_CACHED_ACTION_DISMISSAL) 388 .remove(PREF_CACHED_ACTION_DISMISSAL)
219 .remove(PREF_CACHED_ACTION_HIDE_DEADLINE) 389 .remove(PREF_CACHED_ACTION_HIDE_DEADLINE)
390 .remove(PREF_CACHED_ACTION_HIDE_EXPIRY)
391 .remove(PREF_CACHED_ACTION_HIDE_FRONTMOST)
392 .remove(PREF_CACHED_ACTION_HIDE_DISABLED)
393 .remove(PREF_CACHED_ACTION_HIDE_SHUTDOWN)
220 .remove(PREF_CACHED_CONSECUTIVE_IGNORED) 394 .remove(PREF_CACHED_CONSECUTIVE_IGNORED)
221 .apply(); 395 .apply();
222 } 396 }
223 } 397 }
224 398
225 private static native void nativeReceiveFlushedMetrics( 399 private static native void nativeReceiveFlushedMetrics(int tapCount, int dis missalCount,
226 int tapCount, int dismissalCount, int hideDeadlineCount, int consecu tiveIgnored); 400 int hideDeadlineCount, int hideExpiryCount, int hideFrontmostCount,
401 int hideDisabledCount, int hideShutdownCount, int consecutiveIgnored );
227 } 402 }
OLDNEW
« no previous file with comments | « chrome/android/BUILD.gn ('k') | chrome/browser/android/ntp/content_suggestions_notification_helper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698