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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java

Issue 1919183003: Rename NotificationUIManager to NotificationPlatformBridge (1/2) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
deleted file mode 100644
index 7d61b3b69cf65cb46bd96448a5bd4c5979594622..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationUIManager.java
+++ /dev/null
@@ -1,695 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.notifications;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.StrictMode;
-import android.os.SystemClock;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.text.style.StyleSpan;
-import android.util.Log;
-
-import org.chromium.base.CommandLine;
-import org.chromium.base.VisibleForTesting;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.library_loader.ProcessInitException;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.base.metrics.RecordUserAction;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.ChromeSwitches;
-import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
-import org.chromium.chrome.browser.preferences.Preferences;
-import org.chromium.chrome.browser.preferences.PreferencesLauncher;
-import org.chromium.chrome.browser.preferences.website.SingleCategoryPreferences;
-import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
-import org.chromium.chrome.browser.preferences.website.SiteSettingsCategory;
-import org.chromium.chrome.browser.util.UrlUtilities;
-import org.chromium.chrome.browser.widget.RoundedIconGenerator;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-/**
- * Provides the ability for the NotificationUIManagerAndroid to talk to the Android platform
- * notification manager.
- *
- * This class should only be used on the UI thread.
- */
-public class NotificationUIManager {
- private static final String TAG = NotificationUIManager.class.getSimpleName();
-
- // We always use the same integer id when showing and closing notifications. The notification
- // tag is always set, which is a safe and sufficient way of identifying a notification, so the
- // integer id is not needed anymore except it must not vary in an uncontrolled way.
- @VisibleForTesting static final int PLATFORM_ID = -1;
-
- // Prefix for platform tags generated by this class. This allows us to verify when reading a tag
- // that it was set by us.
- private static final String PLATFORM_TAG_PREFIX = NotificationUIManager.class.getSimpleName();
-
- private static final int NOTIFICATION_ICON_BG_COLOR = 0xFF969696;
- private static final int NOTIFICATION_TEXT_SIZE_DP = 28;
-
- // We always use the same request code for pending intents. We use other ways to force
- // uniqueness of pending intents when necessary.
- private static final int PENDING_INTENT_REQUEST_CODE = 0;
-
- private static NotificationUIManager sInstance;
- private static NotificationManagerProxy sNotificationManagerOverride;
-
- private final long mNativeNotificationManager;
-
- private final Context mAppContext;
- private final NotificationManagerProxy mNotificationManager;
-
- @VisibleForTesting public RoundedIconGenerator mIconGenerator;
- private final int mLargeIconWidthPx;
- private final int mLargeIconHeightPx;
- private final float mDensity;
-
- private long mLastNotificationClickMs = 0L;
-
- /**
- * Creates a new instance of the NotificationUIManager.
- *
- * @param nativeNotificationManager Instance of the NotificationUIManagerAndroid class.
- * @param context Application context for this instance of Chrome.
- */
- @CalledByNative
- private static NotificationUIManager create(long nativeNotificationManager, Context context) {
- if (sInstance != null) {
- throw new IllegalStateException(
- "There must only be a single NotificationPlatformBridge.");
- }
-
- sInstance = new NotificationUIManager(nativeNotificationManager, context);
- return sInstance;
- }
-
- /**
- * Returns the current instance of the NotificationUIManager.
- *
- * @return The instance of the NotificationUIManager, if any.
- */
- @Nullable
- @VisibleForTesting
- static NotificationUIManager getInstanceForTests() {
- return sInstance;
- }
-
- /**
- * Overrides the notification manager which is to be used for displaying Notifications on the
- * Android framework. Should only be used for testing. Tests are expected to clean up after
- * themselves by setting this to NULL again.
- *
- * @param proxy The notification manager instance to use instead of the system's.
- */
- @VisibleForTesting
- public static void overrideNotificationManagerForTesting(
- NotificationManagerProxy notificationManager) {
- sNotificationManagerOverride = notificationManager;
- }
-
- private NotificationUIManager(long nativeNotificationManager, Context context) {
- mNativeNotificationManager = nativeNotificationManager;
- mAppContext = context.getApplicationContext();
-
- if (sNotificationManagerOverride != null) {
- mNotificationManager = sNotificationManagerOverride;
- } else {
- mNotificationManager = new NotificationManagerProxyImpl(
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
- }
-
- Resources resources = mAppContext.getResources();
-
- mLargeIconWidthPx =
- resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
- mLargeIconHeightPx =
- resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
- mDensity = resources.getDisplayMetrics().density;
- }
-
- /**
- * Marks the current instance as being freed, allowing for a new NotificationUIManager
- * object to be initialized.
- */
- @CalledByNative
- private void destroy() {
- assert sInstance == this;
- sInstance = null;
- }
-
- /**
- * Invoked by the NotificationService when a Notification intent has been received. There may
- * not be an active instance of the NotificationUIManager at this time, so inform the native
- * side through a static method, initializing the manager if needed.
- *
- * @param intent The intent as received by the Notification service.
- * @return Whether the event could be handled by the native Notification manager.
- */
- public static boolean dispatchNotificationEvent(Intent intent) {
- if (sInstance == null) {
- nativeInitializeNotificationUIManager();
- if (sInstance == null) {
- Log.e(TAG, "Unable to initialize the native NotificationUIManager.");
- return false;
- }
- }
-
- long persistentNotificationId =
- intent.getLongExtra(NotificationConstants.EXTRA_PERSISTENT_NOTIFICATION_ID, -1);
- String origin = intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ORIGIN);
- String profileId =
- intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID);
- boolean incognito = intent.getBooleanExtra(
- NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_INCOGNITO, false);
- String tag = intent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_TAG);
-
- Log.i(TAG, "Dispatching notification event to native: " + persistentNotificationId);
-
- if (NotificationConstants.ACTION_CLICK_NOTIFICATION.equals(intent.getAction())) {
- int actionIndex = intent.getIntExtra(
- NotificationConstants.EXTRA_NOTIFICATION_INFO_ACTION_INDEX, -1);
- sInstance.onNotificationClicked(
- persistentNotificationId, origin, profileId, incognito, tag, actionIndex);
- return true;
- } else if (NotificationConstants.ACTION_CLOSE_NOTIFICATION.equals(intent.getAction())) {
- // Notification deleteIntent is executed only "when the notification is explicitly
- // dismissed by the user, either with the 'Clear All' button or by swiping it away
- // individually" (though a third-party NotificationListenerService may also trigger it).
- sInstance.onNotificationClosed(
- persistentNotificationId, origin, profileId, incognito, tag, true /* byUser */);
- return true;
- }
-
- Log.e(TAG, "Unrecognized Notification action: " + intent.getAction());
- return false;
- }
-
- /**
- * Launches the notifications preferences screen. If the received intent indicates it came
- * from the gear button on a flipped notification, this launches the site specific preferences
- * screen.
- *
- * @param context The context that received the intent.
- * @param incomingIntent The received intent.
- */
- public static void launchNotificationPreferences(Context context, Intent incomingIntent) {
- // This method handles an intent fired by the Android system. There is no guarantee that the
- // native library is loaded at this point. The native library is needed for the preferences
- // activity, and it loads the library, but there are some native calls even before that
- // activity is started: from RecordUserAction.record and (indirectly) from
- // UrlUtilities.formatUrlForSecurityDisplay.
- try {
- ChromeBrowserInitializer.getInstance(context).handleSynchronousStartup();
- } catch (ProcessInitException e) {
- Log.e(TAG, "Failed to start browser process.", e);
- // The library failed to initialize and nothing in the application can work, so kill
- // the whole application.
- System.exit(-1);
- return;
- }
-
- // Use the application context because it lives longer. When using the given context, it
- // may be stopped before the preferences intent is handled.
- Context applicationContext = context.getApplicationContext();
-
- // If we can read an origin from the intent, use it to open the settings screen for that
- // origin.
- String origin = getOriginFromTag(
- incomingIntent.getStringExtra(NotificationConstants.EXTRA_NOTIFICATION_TAG));
- boolean launchSingleWebsitePreferences = origin != null;
-
- String fragmentName = launchSingleWebsitePreferences
- ? SingleWebsitePreferences.class.getName()
- : SingleCategoryPreferences.class.getName();
- Intent preferencesIntent =
- PreferencesLauncher.createIntentForSettingsPage(applicationContext, fragmentName);
-
- Bundle fragmentArguments;
- if (launchSingleWebsitePreferences) {
- // Record that the user has clicked on the [Site Settings] button.
- RecordUserAction.record("Notifications.ShowSiteSettings");
-
- // All preferences for a specific origin.
- fragmentArguments = SingleWebsitePreferences.createFragmentArgsForSite(origin);
- } else {
- // Notification preferences for all origins.
- fragmentArguments = new Bundle();
- fragmentArguments.putString(SingleCategoryPreferences.EXTRA_CATEGORY,
- SiteSettingsCategory.CATEGORY_NOTIFICATIONS);
- fragmentArguments.putString(SingleCategoryPreferences.EXTRA_TITLE,
- applicationContext.getResources().getString(
- R.string.push_notifications_permission_title));
- }
- preferencesIntent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArguments);
-
- // We need to ensure that no existing preference tasks are being re-used in order for the
- // new activity to appear on top.
- preferencesIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-
- applicationContext.startActivity(preferencesIntent);
- }
-
- /**
- * Returns a bogus Uri used to make each intent unique according to Intent#filterEquals.
- * Without this, the pending intents derived from the intent may be reused, because extras are
- * not taken into account for the filterEquals comparison.
- *
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin to whom the notification belongs.
- * @param actionIndex The zero-based index of the action button, or -1 if not applicable.
- */
- private Uri makeIntentData(long persistentNotificationId, String origin, int actionIndex) {
- return Uri.parse(origin).buildUpon().fragment(
- persistentNotificationId + "," + actionIndex).build();
- }
-
- /**
- * Returns the PendingIntent for completing |action| on the notification identified by the data
- * in the other parameters.
- *
- * @param action The action this pending intent will represent.
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin to whom the notification belongs.
- * @param tag The tag of the notification. May be NULL.
- * @param actionIndex The zero-based index of the action button, or -1 if not applicable.
- */
- private PendingIntent makePendingIntent(String action, long persistentNotificationId,
- String origin, String profileId, boolean incognito, @Nullable String tag,
- int actionIndex) {
- Uri intentData = makeIntentData(persistentNotificationId, origin, actionIndex);
- Intent intent = new Intent(action, intentData);
- intent.setClass(mAppContext, NotificationService.Receiver.class);
-
- intent.putExtra(NotificationConstants.EXTRA_PERSISTENT_NOTIFICATION_ID,
- persistentNotificationId);
- intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ORIGIN, origin);
- intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_ID, profileId);
- intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_PROFILE_INCOGNITO, incognito);
- intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_TAG, tag);
- intent.putExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ACTION_INDEX, actionIndex);
-
- return PendingIntent.getBroadcast(mAppContext, PENDING_INTENT_REQUEST_CODE, intent,
- PendingIntent.FLAG_UPDATE_CURRENT);
- }
-
- /**
- * Generates the tag to be passed to the notification manager.
- *
- * If the generated tag is the same as that of a previous notification, a new notification shown
- * with this tag will replace it.
- *
- * If the input tag is not empty the output is: PREFIX + SEPARATOR + ORIGIN + SEPARATOR + TAG.
- * This output will be the same for notifications from the same origin that have the same input
- * tag.
- *
- * If the input tag is empty the output is PREFIX + SEPARATOR + ORIGIN + SEPARATOR +
- * NOTIFICATION_ID.
- *
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin for which the notification is shown.
- * @param tag A string identifier for this notification.
- * @return The generated platform tag.
- */
- @VisibleForTesting
- static String makePlatformTag(
- long persistentNotificationId, String origin, @Nullable String tag) {
- // The given tag may contain the separator character, so add it last to make reading the
- // preceding origin token reliable. If no tag was specified (it is the default empty
- // string), make the platform tag unique by appending the notification id.
- StringBuilder builder = new StringBuilder();
- builder.append(PLATFORM_TAG_PREFIX)
- .append(NotificationConstants.NOTIFICATION_TAG_SEPARATOR)
- .append(origin)
- .append(NotificationConstants.NOTIFICATION_TAG_SEPARATOR);
-
- if (TextUtils.isEmpty(tag)) {
- builder.append(persistentNotificationId);
- } else {
- builder.append(tag);
- }
-
- return builder.toString();
- }
-
- /**
- * Attempts to extract an origin from the tag extra in the given intent.
- *
- * See {@link #makePlatformTag} for details about the format of the tag.
- *
- * @param tag The tag from the intent extra. May be null.
- * @return The origin string. Returns null if there was no tag extra in the given intent, or if
- * the tag value did not match the expected format.
- */
- @Nullable
- @VisibleForTesting
- static String getOriginFromTag(@Nullable String tag) {
- // If the user touched the settings cog on a flipped notification originating from this
- // class, there will be a notification tag extra in a specific format. From the tag we can
- // read the origin of the notification.
- if (tag == null || !tag.startsWith(PLATFORM_TAG_PREFIX)) return null;
-
- String[] parts = tag.split(NotificationConstants.NOTIFICATION_TAG_SEPARATOR);
- assert parts.length >= 3;
- try {
- URI uri = new URI(parts[1]);
- if (uri.getHost() != null) return parts[1];
- } catch (URISyntaxException e) {
- Log.e(TAG, "Expected to find a valid url in the notification tag extra.", e);
- return null;
- }
- return null;
- }
-
- /**
- * Generates the notfiication defaults from vibrationPattern's size and silent.
- *
- * Use the system's default ringtone, vibration and indicator lights unless the notification
- * has been marked as being silent.
- * If a vibration pattern is set, the notification should use the provided pattern
- * rather than the defaulting to system settings.
- *
- * @param vibrationPatternLength Vibration pattern's size for the Notification.
- * @param silent Whether the default sound, vibration and lights should be suppressed.
- * @return The generated notification's default value.
- */
- @VisibleForTesting
- static int makeDefaults(int vibrationPatternLength, boolean silent) {
- assert !silent || vibrationPatternLength == 0;
-
- if (silent) return 0;
-
- int defaults = Notification.DEFAULT_ALL;
- if (vibrationPatternLength > 0) {
- defaults &= ~Notification.DEFAULT_VIBRATE;
- }
- return defaults;
- }
-
- /**
- * Generates the vibration pattern used in Android notification.
- *
- * Android takes a long array where the first entry indicates the number of milliseconds to wait
- * prior to starting the vibration, whereas Chrome follows the syntax of the Web Vibration API.
- *
- * @param vibrationPattern Vibration pattern following the Web Vibration API syntax.
- * @return Vibration pattern following the Android syntax.
- */
- @VisibleForTesting
- static long[] makeVibrationPattern(int[] vibrationPattern) {
- long[] pattern = new long[vibrationPattern.length + 1];
- for (int i = 0; i < vibrationPattern.length; ++i) {
- pattern[i + 1] = vibrationPattern[i];
- }
- return pattern;
- }
-
- /**
- * Displays a notification with the given details.
- *
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin Full text of the origin, including the protocol, owning this notification.
- * @param profileId Id of the profile that showed the notification.
- * @param incognito if the session of the profile is an off the record one.
- * @param tag A string identifier for this notification. If the tag is not empty, the new
- * notification will replace the previous notification with the same tag and origin,
- * if present. If no matching previous notification is present, the new one will just
- * be added.
- * @param title Title to be displayed in the notification.
- * @param body Message to be displayed in the notification. Will be trimmed to one line of
- * text by the Android notification system.
- * @param icon Icon to be displayed in the notification. Valid Bitmap icons will be scaled to
- * the platforms, whereas a default icon will be generated for invalid Bitmaps.
- * @param badge An image to represent the notification in the status bar. It is also displayed
- * inside the notification.
- * @param vibrationPattern Vibration pattern following the Web Vibration syntax.
- * @param timestamp The timestamp of the event for which the notification is being shown.
- * @param renotify Whether the sound, vibration, and lights should be replayed if the
- * notification is replacing another notification.
- * @param silent Whether the default sound, vibration and lights should be suppressed.
- * @param actionTitles Titles of actions to display alongside the notification.
- * @param actionIcons Icons of actions to display alongside the notification.
- * @see https://developer.android.com/reference/android/app/Notification.html
- */
- @CalledByNative
- private void displayNotification(long persistentNotificationId, String origin, String profileId,
- boolean incognito, String tag, String title, String body, Bitmap icon, Bitmap badge,
- int[] vibrationPattern, long timestamp, boolean renotify, boolean silent,
- String[] actionTitles, Bitmap[] actionIcons) {
- if (actionTitles.length != actionIcons.length) {
- throw new IllegalArgumentException("The number of action titles and icons must match.");
- }
-
- Resources res = mAppContext.getResources();
-
- // Record whether it's known whether notifications can be shown to the user at all.
- RecordHistogram.recordEnumeratedHistogram(
- "Notifications.AppNotificationStatus",
- NotificationSystemStatusUtil.determineAppNotificationStatus(mAppContext),
- NotificationSystemStatusUtil.APP_NOTIFICATIONS_STATUS_BOUNDARY);
-
- // Set up a pending intent for going to the settings screen for |origin|.
- Intent settingsIntent = PreferencesLauncher.createIntentForSettingsPage(
- mAppContext, SingleWebsitePreferences.class.getName());
- settingsIntent.setData(
- makeIntentData(persistentNotificationId, origin, -1 /* actionIndex */));
- settingsIntent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS,
- SingleWebsitePreferences.createFragmentArgsForSite(origin));
-
- PendingIntent pendingSettingsIntent = PendingIntent.getActivity(mAppContext,
- PENDING_INTENT_REQUEST_CODE, settingsIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- PendingIntent clickIntent = makePendingIntent(
- NotificationConstants.ACTION_CLICK_NOTIFICATION, persistentNotificationId, origin,
- profileId, incognito, tag, -1 /* actionIndex */);
- PendingIntent closeIntent = makePendingIntent(
- NotificationConstants.ACTION_CLOSE_NOTIFICATION, persistentNotificationId, origin,
- profileId, incognito, tag, -1 /* actionIndex */);
-
- NotificationBuilderBase notificationBuilder =
- createNotificationBuilder()
- .setTitle(title)
- .setBody(body)
- .setLargeIcon(ensureNormalizedIcon(icon, origin))
- .setSmallIcon(R.drawable.ic_chrome)
- .setSmallIcon(badge)
- .setContentIntent(clickIntent)
- .setDeleteIntent(closeIntent)
- .setTicker(createTickerText(title, body))
- .setTimestamp(timestamp)
- .setRenotify(renotify)
- .setOrigin(UrlUtilities.formatUrlForSecurityDisplay(
- origin, false /* showScheme */));
-
- for (int actionIndex = 0; actionIndex < actionTitles.length; actionIndex++) {
- notificationBuilder.addAction(actionIcons[actionIndex], actionTitles[actionIndex],
- makePendingIntent(NotificationConstants.ACTION_CLICK_NOTIFICATION,
- persistentNotificationId, origin, profileId,
- incognito, tag, actionIndex));
- }
-
- // If action buttons are displayed, there isn't room for the full Site Settings button
- // label and icon, so abbreviate it. This has the unfortunate side-effect of unnecessarily
- // abbreviating it on Android Wear also (crbug.com/576656). If custom layouts are enabled,
- // the label and icon provided here only affect Android Wear, so don't abbreviate them.
- boolean abbreviateSiteSettings = actionTitles.length > 0 && !useCustomLayouts();
- int settingsIconId = abbreviateSiteSettings ? 0 : R.drawable.settings_cog;
- CharSequence settingsTitle = abbreviateSiteSettings
- ? res.getString(R.string.notification_site_settings_button)
- : res.getString(R.string.page_info_site_settings_button);
- // If the settings button is displayed together with the other buttons it has to be the last
- // one, so add it after the other actions.
- notificationBuilder.addSettingsAction(settingsIconId, settingsTitle, pendingSettingsIntent);
-
- notificationBuilder.setDefaults(makeDefaults(vibrationPattern.length, silent));
- if (vibrationPattern.length > 0) {
- notificationBuilder.setVibrate(makeVibrationPattern(vibrationPattern));
- }
-
- String platformTag = makePlatformTag(persistentNotificationId, origin, tag);
- // Temporarily allowing disk access. TODO: Fix. See http://crbug.com/577185
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- StrictMode.allowThreadDiskWrites();
- try {
- long time = SystemClock.elapsedRealtime();
- mNotificationManager.notify(platformTag, PLATFORM_ID, notificationBuilder.build());
- RecordHistogram.recordTimesHistogram("Android.StrictMode.NotificationUIBuildTime",
- SystemClock.elapsedRealtime() - time, TimeUnit.MILLISECONDS);
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
- }
-
- private NotificationBuilderBase createNotificationBuilder() {
- if (useCustomLayouts()) {
- return new CustomNotificationBuilder(mAppContext);
- }
- return new StandardNotificationBuilder(mAppContext);
- }
-
- /**
- * Creates the ticker text for a notification having |title| and |body|. The notification's
- * title will be printed in bold, followed by the text of the body.
- *
- * @param title Title of the notification.
- * @param body Textual contents of the notification.
- * @return A character sequence containing the ticker's text.
- */
- private CharSequence createTickerText(String title, String body) {
- SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
-
- spannableStringBuilder.append(title);
- spannableStringBuilder.append("\n");
- spannableStringBuilder.append(body);
-
- // Mark the title of the notification as being bold.
- spannableStringBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
- 0, title.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-
- return spannableStringBuilder;
- }
-
- /**
- * Ensures the availability of an icon for the notification.
- *
- * If |icon| is a valid, non-empty Bitmap, the bitmap will be scaled to be of an appropriate
- * size for the current Android device. Otherwise, a default icon will be created based on the
- * origin the notification is being displayed for.
- *
- * @param icon The developer-provided icon they intend to use for the notification.
- * @param origin The origin the notification is being displayed for.
- * @return An appropriately sized icon to use for the notification.
- */
- @VisibleForTesting
- public Bitmap ensureNormalizedIcon(Bitmap icon, String origin) {
- if (icon == null || icon.getWidth() == 0) {
- if (mIconGenerator == null) {
- int cornerRadiusPx = Math.min(mLargeIconWidthPx, mLargeIconHeightPx) / 2;
- mIconGenerator =
- new RoundedIconGenerator(mLargeIconWidthPx, mLargeIconHeightPx,
- cornerRadiusPx,
- NOTIFICATION_ICON_BG_COLOR,
- NOTIFICATION_TEXT_SIZE_DP * mDensity);
- }
-
- return mIconGenerator.generateIconForUrl(origin, true);
- }
-
- if (icon.getWidth() > mLargeIconWidthPx || icon.getHeight() > mLargeIconHeightPx) {
- return icon.createScaledBitmap(icon, mLargeIconWidthPx, mLargeIconHeightPx,
- false /* not filtered */);
- }
-
- return icon;
- }
-
- /**
- * Determines whether to use standard notification layouts, using NotificationCompat.Builder,
- * or custom layouts using Chrome's own templates.
- *
- * The --{enable,disable}-web-notification-custom-layouts command line flags take precedence.
- *
- * @return Whether custom layouts should be used.
- */
- @VisibleForTesting
- static boolean useCustomLayouts() {
- CommandLine commandLine = CommandLine.getInstance();
- if (commandLine.hasSwitch(ChromeSwitches.ENABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS)) {
- return true;
- }
- if (commandLine.hasSwitch(ChromeSwitches.DISABLE_WEB_NOTIFICATION_CUSTOM_LAYOUTS)) {
- return false;
- }
- if (Build.VERSION.CODENAME.equals("N")) {
- return false;
- }
- return true;
- }
-
- /**
- * Returns whether a notification has been clicked in the last 5 seconds.
- * Used for Startup.BringToForegroundReason UMA histogram.
- */
- public static boolean wasNotificationRecentlyClicked() {
- if (sInstance == null) return false;
- long now = System.currentTimeMillis();
- return now - sInstance.mLastNotificationClickMs < 5 * 1000;
- }
-
- /**
- * Closes the notification associated with the given parameters.
- *
- * @param profileId of the profile whose notification this is for.
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin to which the notification belongs.
- * @param tag The tag of the notification. May be NULL.
- */
- @CalledByNative
- private void closeNotification(
- String profileId, long persistentNotificationId, String origin, String tag) {
- // TODO(miguelg) make profile_id part of the tag.
- String platformTag = makePlatformTag(persistentNotificationId, origin, tag);
- mNotificationManager.cancel(platformTag, PLATFORM_ID);
- }
-
- /**
- * Calls NotificationUIManagerAndroid::OnNotificationClicked in native code to indicate that
- * the notification with the given parameters has been clicked on.
- *
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin of the notification.
- * @param profileId Id of the profile that showed the notification.
- * @param incognito if the profile session was an off the record one.
- * @param tag The tag of the notification. May be NULL.
- */
- private void onNotificationClicked(long persistentNotificationId, String origin,
- String profileId, boolean incognito, String tag, int actionIndex) {
- mLastNotificationClickMs = System.currentTimeMillis();
- nativeOnNotificationClicked(mNativeNotificationManager, persistentNotificationId, origin,
- profileId, incognito, tag, actionIndex);
- }
-
- /**
- * Calls NotificationUIManagerAndroid::OnNotificationClosed in native code to indicate that
- * the notification with the given parameters has been closed.
- *
- * @param persistentNotificationId The persistent id of the notification.
- * @param origin The origin of the notification.
- * @param profileId Id of the profile that showed the notification.
- * @param incognito if the profile session was an off the record one.
- * @param tag The tag of the notification. May be NULL.
- * @param byUser Whether the notification was closed by a user gesture.
- */
- private void onNotificationClosed(long persistentNotificationId, String origin,
- String profileId, boolean incognito, String tag, boolean byUser) {
- nativeOnNotificationClosed(mNativeNotificationManager, persistentNotificationId, origin,
- profileId, incognito, tag, byUser);
- }
-
- private static native void nativeInitializeNotificationUIManager();
-
- private native void nativeOnNotificationClicked(long nativeNotificationUIManagerAndroid,
- long persistentNotificationId, String origin, String profileId, boolean incognito,
- String tag, int actionIndex);
- private native void nativeOnNotificationClosed(long nativeNotificationUIManagerAndroid,
- long persistentNotificationId, String origin, String profileId, boolean incognito,
- String tag, boolean byUser);
-}

Powered by Google App Engine
This is Rietveld 408576698