Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java |
| index 71204a5c8c04b203ec143cb51d04099ab9830fcc..a06051149ebe3fa95d940e59d48777f6c87ac3e5 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/SadTabViewFactory.java |
| @@ -5,45 +5,72 @@ |
| package org.chromium.chrome.browser.tab; |
| import android.content.Context; |
| -import android.support.annotation.StringRes; |
| +import android.support.annotation.IntDef; |
| +import android.text.SpannableString; |
| +import android.text.TextUtils; |
| import android.text.method.LinkMovementMethod; |
| +import android.text.style.BulletSpan; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.widget.Button; |
| import android.widget.TextView; |
| +import org.chromium.base.metrics.RecordHistogram; |
| import org.chromium.chrome.R; |
| import org.chromium.ui.text.NoUnderlineClickableSpan; |
| import org.chromium.ui.text.SpanApplier; |
| import org.chromium.ui.text.SpanApplier.SpanInfo; |
| +import java.lang.annotation.Retention; |
| +import java.lang.annotation.RetentionPolicy; |
| + |
| /** |
| * A factory class for creating the "Sad Tab" view, which is shown in place of a crashed renderer. |
| */ |
| public class SadTabViewFactory { |
| + // This IntDef backs an UMA histogram, so it should be treated as append-only. |
| + // A native counterpart exists in sad_tab.cc. |
| + @IntDef({SAD_TAB_EVENT_DISPLAYED, SAD_TAB_EVENT_BUTTON_CLICKED, |
| + SAD_TAB_EVENT_HELP_LINK_CLICKED}) |
| + @Retention(RetentionPolicy.SOURCE) |
| + public @interface SadTabEvent {} |
| + public static final int SAD_TAB_EVENT_DISPLAYED = 0; |
| + public static final int SAD_TAB_EVENT_BUTTON_CLICKED = 1; |
| + public static final int SAD_TAB_EVENT_HELP_LINK_CLICKED = 2; |
| + private static final int MAX_SAD_TAB_EVENT = 3; |
| + |
| + private static final int BULLET_GAP_WIDTH = 100; |
| /** |
| * @param context Context of the resulting Sad Tab view. |
| * @param suggestionAction Action to be executed when user clicks "try these suggestions". |
| * @param reloadButtonAction Action to be executed when Reload button is pressed. |
| * (e.g., refreshing the page) |
| - * @param buttonTextId The string resource for the button text label. |
| + * @param showSendFeedbackView Whether to show the "send feedback" version of the Sad Tab view. |
| * @return A "Sad Tab" view instance which is used in place of a crashed renderer. |
| */ |
| - public static View createSadTabView( |
| - Context context, final OnClickListener suggestionAction, |
| - OnClickListener reloadButtonAction, @StringRes int buttonTextId) { |
| + public static View createSadTabView(Context context, final OnClickListener suggestionAction, |
| + OnClickListener reloadButtonAction, boolean showSendFeedbackView) { |
| // Inflate Sad tab and initialize. |
| LayoutInflater inflater = (LayoutInflater) context.getSystemService( |
| Context.LAYOUT_INFLATER_SERVICE); |
| View sadTabView = inflater.inflate(R.layout.sad_tab, null); |
| + TextView titleText = (TextView) sadTabView.findViewById(R.id.sad_tab_title); |
| + int titleTextId = |
| + showSendFeedbackView ? R.string.sad_tab_reload_title : R.string.sad_tab_title; |
| + titleText.setText(titleTextId); |
| + |
| + if (showSendFeedbackView) intializeSuggestionsViews(context, sadTabView); |
| + |
| TextView messageText = (TextView) sadTabView.findViewById(R.id.sad_tab_message); |
| - messageText.setText(getHelpMessage(context, suggestionAction)); |
| + messageText.setText(getHelpMessage(context, suggestionAction, showSendFeedbackView)); |
| messageText.setMovementMethod(LinkMovementMethod.getInstance()); |
| Button reloadButton = (Button) sadTabView.findViewById(R.id.sad_tab_reload_button); |
| + int buttonTextId = showSendFeedbackView ? R.string.sad_tab_send_feedback_label |
| + : R.string.sad_tab_reload_label; |
| reloadButton.setText(buttonTextId); |
| reloadButton.setOnClickListener(reloadButtonAction); |
| @@ -53,19 +80,76 @@ public class SadTabViewFactory { |
| /** |
| * Construct and return help message to be displayed on R.id.sad_tab_message. |
| * @param context Context of the resulting Sad Tab view. This is needed to load the strings. |
| - * @param suggestionAction Action to be executed when user clicks "try these suggestions". |
| + * @param suggestionAction Action to be executed when user clicks "try these suggestions" |
| + * or "learn more". |
| * @return Help message to be displayed on R.id.sad_tab_message. |
| */ |
| private static CharSequence getHelpMessage( |
| - Context context, final OnClickListener suggestionAction) { |
| - String helpMessage = context.getString(R.string.sad_tab_message) |
| - + "\n\n" + context.getString(R.string.sad_tab_suggestions); |
| - NoUnderlineClickableSpan span = new NoUnderlineClickableSpan() { |
| + Context context, final OnClickListener suggestionAction, boolean showSendFeedback) { |
| + NoUnderlineClickableSpan linkSpan = new NoUnderlineClickableSpan() { |
| @Override |
| public void onClick(View view) { |
| suggestionAction.onClick(view); |
| } |
| }; |
| - return SpanApplier.applySpans(helpMessage, new SpanInfo("<link>", "</link>", span)); |
| + |
| + if (showSendFeedback) { |
| + SpannableString learnMoreLink = |
| + new SpannableString(context.getString(R.string.sad_tab_reload_learn_more)); |
| + learnMoreLink.setSpan(linkSpan, 0, learnMoreLink.length(), 0); |
| + return learnMoreLink; |
| + } else { |
| + String helpMessage = context.getString(R.string.sad_tab_message) + "\n\n" |
| + + context.getString(R.string.sad_tab_suggestions); |
| + return SpanApplier.applySpans(helpMessage, new SpanInfo("<link>", "</link>", linkSpan)); |
| + } |
| + } |
| + |
| + /** |
| + * Initializes the TextViews that display tips for handling repeated crashes. |
| + * @param context Context of the resulting Sad Tab view. |
|
Theresa
2017/05/09 21:01:36
nit: This comment could be better.
|
| + * @param sadTabView The parent Sad Tab view that contains the TextViews. |
| + */ |
| + private static void intializeSuggestionsViews(Context context, View sadTabView) { |
| + TextView suggestionsTitle = |
| + (TextView) sadTabView.findViewById(R.id.sad_tab_suggestions_title); |
| + suggestionsTitle.setVisibility(View.VISIBLE); |
| + suggestionsTitle.setText(R.string.sad_tab_reload_try); |
| + |
| + SpannableString bullet1 = |
| + new SpannableString(context.getString(R.string.sad_tab_reload_close_notabs)); |
| + bullet1.setSpan(new BulletSpan(BULLET_GAP_WIDTH), 0, bullet1.length(), 0); |
| + |
| + SpannableString bullet2 = |
| + new SpannableString(context.getString(R.string.sad_tab_reload_incognito)); |
| + bullet2.setSpan(new BulletSpan(BULLET_GAP_WIDTH), 0, bullet2.length(), 0); |
| + |
| + SpannableString bullet3 = |
| + new SpannableString(context.getString(R.string.sad_tab_reload_restart_browser)); |
| + bullet3.setSpan(new BulletSpan(BULLET_GAP_WIDTH), 0, bullet3.length(), 0); |
| + |
| + SpannableString bullet4 = |
| + new SpannableString(context.getString(R.string.sad_tab_reload_restart_device)); |
| + bullet4.setSpan(new BulletSpan(BULLET_GAP_WIDTH), 0, bullet4.length(), 0); |
| + |
| + TextView suggestions = (TextView) sadTabView.findViewById(R.id.sad_tab_suggestions); |
| + suggestions.setVisibility(View.VISIBLE); |
| + suggestions.setText( |
| + TextUtils.concat(bullet1, "\n", bullet2, "\n", bullet3, "\n", bullet4, "\n")); |
| + } |
| + |
| + /** |
| + * Records enumerated histograms for {@link SadTabEvent}. |
| + * @param sendFeedbackView Whether the event is for the "send feedback" version of the Sad Tab. |
| + * @param event The {@link SadTabEvent} to record. |
| + */ |
| + public static void recordEvent(boolean sendFeedbackView, @SadTabEvent int event) { |
| + if (sendFeedbackView) { |
| + RecordHistogram.recordEnumeratedHistogram( |
| + "Tabs.SadTab.Feedback.Event", event, MAX_SAD_TAB_EVENT); |
| + } else { |
| + RecordHistogram.recordEnumeratedHistogram( |
| + "Tabs.SadTab.Reload.Event", event, MAX_SAD_TAB_EVENT); |
| + } |
| } |
| } |