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

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

Issue 2790183002: Add UMA for the content suggestions settings (Closed)
Patch Set: address comments and rebase Created 3 years, 8 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
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.app.AlarmManager; 7 import android.app.AlarmManager;
8 import android.app.Notification; 8 import android.app.Notification;
9 import android.app.NotificationManager; 9 import android.app.NotificationManager;
10 import android.app.PendingIntent; 10 import android.app.PendingIntent;
(...skipping 12 matching lines...) Expand all
23 import org.chromium.chrome.R; 23 import org.chromium.chrome.R;
24 import org.chromium.chrome.browser.ChromeFeatureList; 24 import org.chromium.chrome.browser.ChromeFeatureList;
25 import org.chromium.chrome.browser.IntentHandler; 25 import org.chromium.chrome.browser.IntentHandler;
26 import org.chromium.chrome.browser.ShortcutHelper; 26 import org.chromium.chrome.browser.ShortcutHelper;
27 import org.chromium.chrome.browser.document.ChromeLauncherActivity; 27 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
28 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; 28 import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder;
29 import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; 29 import org.chromium.chrome.browser.notifications.NotificationBuilderFactory;
30 import org.chromium.chrome.browser.notifications.NotificationConstants; 30 import org.chromium.chrome.browser.notifications.NotificationConstants;
31 import org.chromium.chrome.browser.notifications.NotificationUmaTracker; 31 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
32 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsNotificationAc tion; 32 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsNotificationAc tion;
33 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsNotificationAc tion.ContentSuggestionsNotificationActionEnum;
34 import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsNotificationOp tOut.ContentSuggestionsNotificationOptOutEnum;
33 import org.chromium.chrome.browser.preferences.ContentSuggestionsPreferences; 35 import org.chromium.chrome.browser.preferences.ContentSuggestionsPreferences;
34 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
35 36
36 import java.util.Collection; 37 import java.util.Collection;
37 import java.util.Collections; 38 import java.util.Collections;
38 import java.util.HashSet; 39 import java.util.HashSet;
39 import java.util.Set; 40 import java.util.Set;
40 41
41 /** 42 /**
42 * Provides functionality needed for content suggestion notifications. 43 * Provides functionality needed for content suggestion notifications.
43 * 44 *
44 * Exposes helper functions to native C++ code. 45 * Exposes helper functions to native C++ code.
(...skipping 22 matching lines...) Expand all
67 private static final String PREF_CACHED_CONSECUTIVE_IGNORED = 68 private static final String PREF_CACHED_CONSECUTIVE_IGNORED =
68 "ntp.content_suggestions.notification.cached_consecutive_ignored"; 69 "ntp.content_suggestions.notification.cached_consecutive_ignored";
69 70
70 // Tracks which URIs there is an active notification for. 71 // Tracks which URIs there is an active notification for.
71 private static final String PREF_ACTIVE_NOTIFICATIONS = 72 private static final String PREF_ACTIVE_NOTIFICATIONS =
72 "ntp.content_suggestions.notification.active"; 73 "ntp.content_suggestions.notification.active";
73 74
74 private ContentSuggestionsNotificationHelper() {} // Prevent instantiation 75 private ContentSuggestionsNotificationHelper() {} // Prevent instantiation
75 76
76 /** 77 /**
78 * Records the reason why Content Suggestions notifications have been opted out.
79 * @see ContentSuggestionsNotificationOptOutEnum;
80 */
81 public static void recordNotificationOptOut(
82 @ContentSuggestionsNotificationOptOutEnum int reason) {
83 nativeRecordNotificationOptOut(reason);
84 }
85
86 /**
87 * Records an action performed on a Content Suggestions notification.
88 * @see ContentSuggestionsNotificationActionEnum;
89 */
90 public static void recordNotificationAction(
91 @ContentSuggestionsNotificationActionEnum int action) {
92 nativeRecordNotificationAction(action);
93 }
94
95 /**
77 * Opens the content suggestion when notification is tapped. 96 * Opens the content suggestion when notification is tapped.
78 */ 97 */
79 public static final class OpenUrlReceiver extends BroadcastReceiver { 98 public static final class OpenUrlReceiver extends BroadcastReceiver {
80 @Override 99 @Override
81 public void onReceive(Context context, Intent intent) { 100 public void onReceive(Context context, Intent intent) {
82 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 101 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
83 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 102 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
84 openUrl(intent.getData()); 103 openUrl(intent.getData());
85 recordCachedActionMetric(ContentSuggestionsNotificationAction.CONTEN T_SUGGESTIONS_TAP); 104 recordCachedActionMetric(ContentSuggestionsNotificationAction.TAP);
86 removeActiveNotification(category, idWithinCategory); 105 removeActiveNotification(category, idWithinCategory);
87 } 106 }
88 } 107 }
89 108
90 /** 109 /**
91 * Records dismissal when notification is swiped away. 110 * Records dismissal when notification is swiped away.
92 */ 111 */
93 public static final class DeleteReceiver extends BroadcastReceiver { 112 public static final class DeleteReceiver extends BroadcastReceiver {
94 @Override 113 @Override
95 public void onReceive(Context context, Intent intent) { 114 public void onReceive(Context context, Intent intent) {
96 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 115 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
97 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 116 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
98 recordCachedActionMetric( 117 recordCachedActionMetric(ContentSuggestionsNotificationAction.DISMIS SAL);
99 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DIS MISSAL);
100 removeActiveNotification(category, idWithinCategory); 118 removeActiveNotification(category, idWithinCategory);
101 } 119 }
102 } 120 }
103 121
104 /** 122 /**
105 * Removes the notification after a timeout period. 123 * Removes the notification after a timeout period.
106 */ 124 */
107 public static final class TimeoutReceiver extends BroadcastReceiver { 125 public static final class TimeoutReceiver extends BroadcastReceiver {
108 @Override 126 @Override
109 public void onReceive(Context context, Intent intent) { 127 public void onReceive(Context context, Intent intent) {
110 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 128 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
111 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 129 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
112 if (findActiveNotification(category, idWithinCategory) == null) { 130 if (findActiveNotification(category, idWithinCategory) == null) {
113 return; // tapped or swiped 131 return; // tapped or swiped
114 } 132 }
115 133
116 hideNotification(category, idWithinCategory, 134 hideNotification(
117 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HID E_DEADLINE); 135 category, idWithinCategory, ContentSuggestionsNotificationAc tion.HIDE_DEADLINE);
118 } 136 }
119 } 137 }
120 138
121 private static void openUrl(Uri uri) { 139 private static void openUrl(Uri uri) {
122 Context context = ContextUtils.getApplicationContext(); 140 Context context = ContextUtils.getApplicationContext();
123 Intent intent = new Intent() 141 Intent intent = new Intent()
124 .setAction(Intent.ACTION_VIEW) 142 .setAction(Intent.ACTION_VIEW)
125 .setData(uri) 143 .setData(uri)
126 .setClass(context, ChromeLauncherActivity.class) 144 .setClass(context, ChromeLauncherActivity.class)
127 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 145 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 .setContentIntent(contentIntent) 184 .setContentIntent(contentIntent)
167 .setDeleteIntent(deleteIntent) 185 .setDeleteIntent(deleteIntent)
168 .setContentTitle(title) 186 .setContentTitle(title)
169 .setContentText(text) 187 .setContentText(text)
170 .setGroup(NOTIFICATION_TAG) 188 .setGroup(NOTIFICATION_TAG)
171 .setPriority(priority) 189 .setPriority(priority)
172 .setLargeIcon(image) 190 .setLargeIcon(image)
173 .setSmallIcon(R.drawable.ic_chrome); 191 .setSmallIcon(R.drawable.ic_chrome);
174 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SE TTINGS)) { 192 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SE TTINGS)) {
175 PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, 193 PendingIntent settingsIntent = PendingIntent.getActivity(context, 0,
176 PreferencesLauncher.createIntentForSettingsPage( 194 ContentSuggestionsPreferences.createLaunchIntent(
177 context, ContentSuggestionsPreferences.class.getName ()), 195 context, ContentSuggestionsPreferences.LAUNCH_SOURCE _NOTIFICATION),
178 0); 196 0);
179 builder.addAction(R.drawable.settings_cog, context.getString(R.strin g.preferences), 197 builder.addAction(R.drawable.settings_cog, context.getString(R.strin g.preferences),
180 settingsIntent); 198 settingsIntent);
181 } 199 }
182 if (priority >= 0) { 200 if (priority >= 0) {
183 builder.setDefaults(Notification.DEFAULT_ALL); 201 builder.setDefaults(Notification.DEFAULT_ALL);
184 } 202 }
185 manager.notify(NOTIFICATION_TAG, nextId, builder.build()); 203 manager.notify(NOTIFICATION_TAG, nextId, builder.build());
186 NotificationUmaTracker.getInstance().onNotificationShown( 204 NotificationUmaTracker.getInstance().onNotificationShown(
187 NotificationUmaTracker.CONTENT_SUGGESTION); 205 NotificationUmaTracker.CONTENT_SUGGESTION);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 Uri notificationUri = Uri.parse(serialized); 360 Uri notificationUri = Uri.parse(serialized);
343 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri); 361 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri);
344 if ((activeNotification != null) && (activeNotification.mId >= nextI d)) { 362 if ((activeNotification != null) && (activeNotification.mId >= nextI d)) {
345 nextId = activeNotification.mId + 1; 363 nextId = activeNotification.mId + 1;
346 } 364 }
347 } 365 }
348 return nextId; 366 return nextId;
349 } 367 }
350 368
351 private static String cachedMetricNameForAction( 369 private static String cachedMetricNameForAction(
352 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum 370 @ContentSuggestionsNotificationActionEnum int action) {
353 int action) {
354 switch (action) { 371 switch (action) {
355 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_TAP: 372 case ContentSuggestionsNotificationAction.TAP:
356 return PREF_CACHED_ACTION_TAP; 373 return PREF_CACHED_ACTION_TAP;
357 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DISMIS SAL: 374 case ContentSuggestionsNotificationAction.DISMISSAL:
358 return PREF_CACHED_ACTION_DISMISSAL; 375 return PREF_CACHED_ACTION_DISMISSAL;
359 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D EADLINE: 376 case ContentSuggestionsNotificationAction.HIDE_DEADLINE:
360 return PREF_CACHED_ACTION_HIDE_DEADLINE; 377 return PREF_CACHED_ACTION_HIDE_DEADLINE;
361 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_E XPIRY: 378 case ContentSuggestionsNotificationAction.HIDE_EXPIRY:
362 return PREF_CACHED_ACTION_HIDE_EXPIRY; 379 return PREF_CACHED_ACTION_HIDE_EXPIRY;
363 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_F RONTMOST: 380 case ContentSuggestionsNotificationAction.HIDE_FRONTMOST:
364 return PREF_CACHED_ACTION_HIDE_FRONTMOST; 381 return PREF_CACHED_ACTION_HIDE_FRONTMOST;
365 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D ISABLED: 382 case ContentSuggestionsNotificationAction.HIDE_DISABLED:
366 return PREF_CACHED_ACTION_HIDE_DISABLED; 383 return PREF_CACHED_ACTION_HIDE_DISABLED;
367 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_S HUTDOWN: 384 case ContentSuggestionsNotificationAction.HIDE_SHUTDOWN:
368 return PREF_CACHED_ACTION_HIDE_SHUTDOWN; 385 return PREF_CACHED_ACTION_HIDE_SHUTDOWN;
369 } 386 }
370 return ""; 387 return "";
371 } 388 }
372 389
373 /** 390 /**
374 * Records that an action was performed on a notification. 391 * Records that an action was performed on a notification.
375 * 392 *
376 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or 393 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or
377 * otherwise incrementing it. 394 * otherwise incrementing it.
378 * 395 *
379 * This method may be called when the native library is not loaded. If it is loaded, the metrics 396 * This method may be called when the native library is not loaded. If it is loaded, the metrics
380 * will immediately be sent to C++. If not, it will cache them for a later c all to 397 * will immediately be sent to C++. If not, it will cache them for a later c all to
381 * flushCachedMetrics(). 398 * flushCachedMetrics().
382 * 399 *
383 * @param action The action to update the pref for. 400 * @param action The action to update the pref for.
384 */ 401 */
385 private static void recordCachedActionMetric( 402 private static void recordCachedActionMetric(
386 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum 403 @ContentSuggestionsNotificationActionEnum int action) {
387 int action) {
388 String prefName = cachedMetricNameForAction(action); 404 String prefName = cachedMetricNameForAction(action);
389 assert !prefName.isEmpty(); 405 assert !prefName.isEmpty();
390 406
391 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); 407 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
392 int currentValue = prefs.getInt(prefName, 0); 408 int currentValue = prefs.getInt(prefName, 0);
393 409
394 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 ); 410 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 );
395 switch (action) { 411 switch (action) {
396 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_TAP: 412 case ContentSuggestionsNotificationAction.TAP:
397 consecutiveIgnored = 0; 413 consecutiveIgnored = 0;
398 break; 414 break;
399 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DISMIS SAL: 415 case ContentSuggestionsNotificationAction.DISMISSAL:
400 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D EADLINE: 416 case ContentSuggestionsNotificationAction.HIDE_DEADLINE:
401 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_E XPIRY: 417 case ContentSuggestionsNotificationAction.HIDE_EXPIRY:
402 ++consecutiveIgnored; 418 ++consecutiveIgnored;
403 break; 419 break;
404 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_F RONTMOST: 420 case ContentSuggestionsNotificationAction.HIDE_FRONTMOST:
405 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D ISABLED: 421 case ContentSuggestionsNotificationAction.HIDE_DISABLED:
406 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_S HUTDOWN: 422 case ContentSuggestionsNotificationAction.HIDE_SHUTDOWN:
407 break; // no change 423 break; // no change
408 } 424 }
409 425
410 prefs.edit() 426 prefs.edit()
411 .putInt(prefName, currentValue + 1) 427 .putInt(prefName, currentValue + 1)
412 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored) 428 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored)
413 .apply(); 429 .apply();
414 430
415 if (LibraryLoader.isInitialized()) { 431 if (LibraryLoader.isInitialized()) {
416 flushCachedMetrics(); 432 flushCachedMetrics();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 .remove(PREF_CACHED_ACTION_HIDE_DISABLED) 466 .remove(PREF_CACHED_ACTION_HIDE_DISABLED)
451 .remove(PREF_CACHED_ACTION_HIDE_SHUTDOWN) 467 .remove(PREF_CACHED_ACTION_HIDE_SHUTDOWN)
452 .remove(PREF_CACHED_CONSECUTIVE_IGNORED) 468 .remove(PREF_CACHED_CONSECUTIVE_IGNORED)
453 .apply(); 469 .apply();
454 } 470 }
455 } 471 }
456 472
457 private static native void nativeReceiveFlushedMetrics(int tapCount, int dis missalCount, 473 private static native void nativeReceiveFlushedMetrics(int tapCount, int dis missalCount,
458 int hideDeadlineCount, int hideExpiryCount, int hideFrontmostCount, 474 int hideDeadlineCount, int hideExpiryCount, int hideFrontmostCount,
459 int hideDisabledCount, int hideShutdownCount, int consecutiveIgnored ); 475 int hideDisabledCount, int hideShutdownCount, int consecutiveIgnored );
476 private static native void nativeRecordNotificationOptOut(
477 @ContentSuggestionsNotificationOptOutEnum int reason);
478 private static native void nativeRecordNotificationAction(
479 @ContentSuggestionsNotificationActionEnum int action);
460 } 480 }
OLDNEW
« no previous file with comments | « no previous file | chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698