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

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: fix parent CL 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
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 21 matching lines...) Expand all
66 "ntp.content_suggestions.notification.cached_action_hide_shutdown"; 67 "ntp.content_suggestions.notification.cached_action_hide_shutdown";
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
77 public static void recordNotificationOptOut(
78 @ContentSuggestionsNotificationOptOutEnum int reason) {
79 nativeRecordNotificationOptOut(reason);
80 }
81 public static void recordNotificationAction(
Michael van Ouwerkerk 2017/04/05 15:47:31 nit: empty line between methods, and docs for publ
dgn 2017/04/05 16:53:54 Done.
82 @ContentSuggestionsNotificationActionEnum int action) {
83 nativeRecordNotificationAction(action);
84 }
85
76 /** 86 /**
77 * Opens the content suggestion when notification is tapped. 87 * Opens the content suggestion when notification is tapped.
78 */ 88 */
79 public static final class OpenUrlReceiver extends BroadcastReceiver { 89 public static final class OpenUrlReceiver extends BroadcastReceiver {
80 @Override 90 @Override
81 public void onReceive(Context context, Intent intent) { 91 public void onReceive(Context context, Intent intent) {
82 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 92 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
83 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 93 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
84 openUrl(intent.getData()); 94 openUrl(intent.getData());
85 recordCachedActionMetric(ContentSuggestionsNotificationAction.CONTEN T_SUGGESTIONS_TAP); 95 recordCachedActionMetric(ContentSuggestionsNotificationAction.TAP);
86 removeActiveNotification(category, idWithinCategory); 96 removeActiveNotification(category, idWithinCategory);
87 } 97 }
88 } 98 }
89 99
90 /** 100 /**
91 * Records dismissal when notification is swiped away. 101 * Records dismissal when notification is swiped away.
92 */ 102 */
93 public static final class DeleteReceiver extends BroadcastReceiver { 103 public static final class DeleteReceiver extends BroadcastReceiver {
94 @Override 104 @Override
95 public void onReceive(Context context, Intent intent) { 105 public void onReceive(Context context, Intent intent) {
96 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 106 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
97 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 107 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
98 recordCachedActionMetric( 108 recordCachedActionMetric(ContentSuggestionsNotificationAction.DISMIS SAL);
99 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DIS MISSAL);
100 removeActiveNotification(category, idWithinCategory); 109 removeActiveNotification(category, idWithinCategory);
101 } 110 }
102 } 111 }
103 112
104 /** 113 /**
105 * Removes the notification after a timeout period. 114 * Removes the notification after a timeout period.
106 */ 115 */
107 public static final class TimeoutReceiver extends BroadcastReceiver { 116 public static final class TimeoutReceiver extends BroadcastReceiver {
108 @Override 117 @Override
109 public void onReceive(Context context, Intent intent) { 118 public void onReceive(Context context, Intent intent) {
110 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1); 119 int category = intent.getIntExtra(NOTIFICATION_CATEGORY_EXTRA, -1);
111 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA); 120 String idWithinCategory = intent.getStringExtra(NOTIFICATION_ID_WITH IN_CATEGORY_EXTRA);
112 if (findActiveNotification(category, idWithinCategory) == null) { 121 if (findActiveNotification(category, idWithinCategory) == null) {
113 return; // tapped or swiped 122 return; // tapped or swiped
114 } 123 }
115 124
116 hideNotification(category, idWithinCategory, 125 hideNotification(
117 ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HID E_DEADLINE); 126 category, idWithinCategory, ContentSuggestionsNotificationAc tion.HIDE_DEADLINE);
118 } 127 }
119 } 128 }
120 129
121 private static void openUrl(Uri uri) { 130 private static void openUrl(Uri uri) {
122 Context context = ContextUtils.getApplicationContext(); 131 Context context = ContextUtils.getApplicationContext();
123 Intent intent = new Intent() 132 Intent intent = new Intent()
124 .setAction(Intent.ACTION_VIEW) 133 .setAction(Intent.ACTION_VIEW)
125 .setData(uri) 134 .setData(uri)
126 .setClass(context, ChromeLauncherActivity.class) 135 .setClass(context, ChromeLauncherActivity.class)
127 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 136 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 .setContentIntent(contentIntent) 175 .setContentIntent(contentIntent)
167 .setDeleteIntent(deleteIntent) 176 .setDeleteIntent(deleteIntent)
168 .setContentTitle(title) 177 .setContentTitle(title)
169 .setContentText(text) 178 .setContentText(text)
170 .setGroup(NOTIFICATION_TAG) 179 .setGroup(NOTIFICATION_TAG)
171 .setPriority(priority) 180 .setPriority(priority)
172 .setLargeIcon(image) 181 .setLargeIcon(image)
173 .setSmallIcon(R.drawable.ic_chrome); 182 .setSmallIcon(R.drawable.ic_chrome);
174 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SE TTINGS)) { 183 if (ChromeFeatureList.isEnabled(ChromeFeatureList.CONTENT_SUGGESTIONS_SE TTINGS)) {
175 PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, 184 PendingIntent settingsIntent = PendingIntent.getActivity(context, 0,
176 PreferencesLauncher.createIntentForSettingsPage( 185 ContentSuggestionsPreferences.createLaunchIntent(
177 context, ContentSuggestionsPreferences.class.getName ()), 186 context, ContentSuggestionsPreferences.LAUNCH_SOURCE _NOTIFICATION),
178 0); 187 0);
179 builder.addAction(R.drawable.settings_cog, context.getString(R.strin g.preferences), 188 builder.addAction(R.drawable.settings_cog, context.getString(R.strin g.preferences),
180 settingsIntent); 189 settingsIntent);
181 } 190 }
182 if (priority >= 0) { 191 if (priority >= 0) {
183 builder.setDefaults(Notification.DEFAULT_ALL); 192 builder.setDefaults(Notification.DEFAULT_ALL);
184 } 193 }
185 manager.notify(NOTIFICATION_TAG, nextId, builder.build()); 194 manager.notify(NOTIFICATION_TAG, nextId, builder.build());
186 NotificationUmaTracker.getInstance().onNotificationShown( 195 NotificationUmaTracker.getInstance().onNotificationShown(
187 NotificationUmaTracker.CONTENT_SUGGESTION); 196 NotificationUmaTracker.CONTENT_SUGGESTION);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 Uri notificationUri = Uri.parse(serialized); 351 Uri notificationUri = Uri.parse(serialized);
343 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri); 352 ActiveNotification activeNotification = ActiveNotification.fromUri(n otificationUri);
344 if ((activeNotification != null) && (activeNotification.mId >= nextI d)) { 353 if ((activeNotification != null) && (activeNotification.mId >= nextI d)) {
345 nextId = activeNotification.mId + 1; 354 nextId = activeNotification.mId + 1;
346 } 355 }
347 } 356 }
348 return nextId; 357 return nextId;
349 } 358 }
350 359
351 private static String cachedMetricNameForAction( 360 private static String cachedMetricNameForAction(
352 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum 361 @ContentSuggestionsNotificationActionEnum int action) {
353 int action) {
354 switch (action) { 362 switch (action) {
355 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_TAP: 363 case ContentSuggestionsNotificationAction.TAP:
356 return PREF_CACHED_ACTION_TAP; 364 return PREF_CACHED_ACTION_TAP;
357 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DISMIS SAL: 365 case ContentSuggestionsNotificationAction.DISMISSAL:
358 return PREF_CACHED_ACTION_DISMISSAL; 366 return PREF_CACHED_ACTION_DISMISSAL;
359 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D EADLINE: 367 case ContentSuggestionsNotificationAction.HIDE_DEADLINE:
360 return PREF_CACHED_ACTION_HIDE_DEADLINE; 368 return PREF_CACHED_ACTION_HIDE_DEADLINE;
361 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_E XPIRY: 369 case ContentSuggestionsNotificationAction.HIDE_EXPIRY:
362 return PREF_CACHED_ACTION_HIDE_EXPIRY; 370 return PREF_CACHED_ACTION_HIDE_EXPIRY;
363 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_F RONTMOST: 371 case ContentSuggestionsNotificationAction.HIDE_FRONTMOST:
364 return PREF_CACHED_ACTION_HIDE_FRONTMOST; 372 return PREF_CACHED_ACTION_HIDE_FRONTMOST;
365 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D ISABLED: 373 case ContentSuggestionsNotificationAction.HIDE_DISABLED:
366 return PREF_CACHED_ACTION_HIDE_DISABLED; 374 return PREF_CACHED_ACTION_HIDE_DISABLED;
367 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_S HUTDOWN: 375 case ContentSuggestionsNotificationAction.HIDE_SHUTDOWN:
368 return PREF_CACHED_ACTION_HIDE_SHUTDOWN; 376 return PREF_CACHED_ACTION_HIDE_SHUTDOWN;
369 } 377 }
370 return ""; 378 return "";
371 } 379 }
372 380
373 /** 381 /**
374 * Records that an action was performed on a notification. 382 * Records that an action was performed on a notification.
375 * 383 *
376 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or 384 * Also tracks the number of consecutively-ignored notifications, resetting it on a tap or
377 * otherwise incrementing it. 385 * otherwise incrementing it.
378 * 386 *
379 * This method may be called when the native library is not loaded. If it is loaded, the metrics 387 * 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 388 * will immediately be sent to C++. If not, it will cache them for a later c all to
381 * flushCachedMetrics(). 389 * flushCachedMetrics().
382 * 390 *
383 * @param action The action to update the pref for. 391 * @param action The action to update the pref for.
384 */ 392 */
385 private static void recordCachedActionMetric( 393 private static void recordCachedActionMetric(
386 @ContentSuggestionsNotificationAction.ContentSuggestionsNotification ActionEnum 394 @ContentSuggestionsNotificationActionEnum int action) {
387 int action) {
388 String prefName = cachedMetricNameForAction(action); 395 String prefName = cachedMetricNameForAction(action);
389 assert !prefName.isEmpty(); 396 assert !prefName.isEmpty();
390 397
391 SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); 398 SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
392 int currentValue = prefs.getInt(prefName, 0); 399 int currentValue = prefs.getInt(prefName, 0);
393 400
394 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 ); 401 int consecutiveIgnored = prefs.getInt(PREF_CACHED_CONSECUTIVE_IGNORED, 0 );
395 switch (action) { 402 switch (action) {
396 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_TAP: 403 case ContentSuggestionsNotificationAction.TAP:
397 consecutiveIgnored = 0; 404 consecutiveIgnored = 0;
398 break; 405 break;
399 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_DISMIS SAL: 406 case ContentSuggestionsNotificationAction.DISMISSAL:
400 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D EADLINE: 407 case ContentSuggestionsNotificationAction.HIDE_DEADLINE:
401 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_E XPIRY: 408 case ContentSuggestionsNotificationAction.HIDE_EXPIRY:
402 ++consecutiveIgnored; 409 ++consecutiveIgnored;
403 break; 410 break;
404 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_F RONTMOST: 411 case ContentSuggestionsNotificationAction.HIDE_FRONTMOST:
405 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_D ISABLED: 412 case ContentSuggestionsNotificationAction.HIDE_DISABLED:
406 case ContentSuggestionsNotificationAction.CONTENT_SUGGESTIONS_HIDE_S HUTDOWN: 413 case ContentSuggestionsNotificationAction.HIDE_SHUTDOWN:
407 break; // no change 414 break; // no change
408 } 415 }
409 416
410 prefs.edit() 417 prefs.edit()
411 .putInt(prefName, currentValue + 1) 418 .putInt(prefName, currentValue + 1)
412 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored) 419 .putInt(PREF_CACHED_CONSECUTIVE_IGNORED, consecutiveIgnored)
413 .apply(); 420 .apply();
414 421
415 if (LibraryLoader.isInitialized()) { 422 if (LibraryLoader.isInitialized()) {
416 flushCachedMetrics(); 423 flushCachedMetrics();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 .remove(PREF_CACHED_ACTION_HIDE_DISABLED) 457 .remove(PREF_CACHED_ACTION_HIDE_DISABLED)
451 .remove(PREF_CACHED_ACTION_HIDE_SHUTDOWN) 458 .remove(PREF_CACHED_ACTION_HIDE_SHUTDOWN)
452 .remove(PREF_CACHED_CONSECUTIVE_IGNORED) 459 .remove(PREF_CACHED_CONSECUTIVE_IGNORED)
453 .apply(); 460 .apply();
454 } 461 }
455 } 462 }
456 463
457 private static native void nativeReceiveFlushedMetrics(int tapCount, int dis missalCount, 464 private static native void nativeReceiveFlushedMetrics(int tapCount, int dis missalCount,
458 int hideDeadlineCount, int hideExpiryCount, int hideFrontmostCount, 465 int hideDeadlineCount, int hideExpiryCount, int hideFrontmostCount,
459 int hideDisabledCount, int hideShutdownCount, int consecutiveIgnored ); 466 int hideDisabledCount, int hideShutdownCount, int consecutiveIgnored );
467 private static native void nativeRecordNotificationOptOut(
468 @ContentSuggestionsNotificationOptOutEnum int reason);
469 private static native void nativeRecordNotificationAction(
470 @ContentSuggestionsNotificationActionEnum int action);
460 } 471 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698