Commit 0c8693cb authored by Daniel Park's avatar Daniel Park Committed by Commit Bot

[NTP Button] Shows IPH on cold start

> Displays an IPH on the NTP Button on cold start
> IPH text is based on finch config

Bug: 843639
Change-Id: Ibaf1e085d52d233b3be95b9f16d146fdf74d902c
Reviewed-on: https://chromium-review.googlesource.com/1070414Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Commit-Queue: Daniel Park <danielpark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561789}
parent f4f527cb
......@@ -21,7 +21,6 @@ import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.text.TextUtils;
import android.util.Pair;
import android.view.KeyEvent;
......@@ -38,7 +37,6 @@ import android.widget.FrameLayout;
import org.chromium.base.ActivityState;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.Callback;
import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
......@@ -122,15 +120,14 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.tabmodel.TabWindowManager;
import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController;
import org.chromium.chrome.browser.toolbar.ToolbarControlContainer;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
import org.chromium.chrome.browser.vr_shell.VrShellDelegate;
import org.chromium.chrome.browser.widget.OverviewListLayout;
import org.chromium.chrome.browser.widget.ViewHighlighter;
import org.chromium.chrome.browser.widget.emptybackground.EmptyBackgroundViewWrapper;
import org.chromium.chrome.browser.widget.textbubble.TextBubble;
import org.chromium.components.feature_engagement.EventConstants;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.components.feature_engagement.Tracker;
......@@ -143,7 +140,6 @@ import org.chromium.content_public.common.Referrer;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.ui.widget.Toast;
import org.chromium.ui.widget.ViewRectProvider;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -577,13 +573,7 @@ public class ChromeTabbedActivity
}
if (!isShowingPromo) {
final Tracker tracker =
TrackerFactory.getTrackerForProfile(Profile.getLastUsedProfile());
tracker.addOnInitializedCallback((Callback<Boolean>) success
-> maybeShowAppMenuTextBubble(tracker,
FeatureConstants.DOWNLOAD_HOME_FEATURE, R.id.downloads_menu_id,
R.string.iph_download_home_text,
R.string.iph_download_home_accessibility_text));
ToolbarButtonInProductHelpController.maybeShowColdStartIPH(this);
}
super.finishNativeInitialization();
......@@ -871,49 +861,6 @@ public class ChromeTabbedActivity
}
}
/**
* Shows an IPH text bubble that points to the app menu. If |highlightMenuItemId| is non-null,
* the corresponding menu item will be highlighted upon opening the app menu.
* @param tracker The feature engagement tracker
* @param featureName The name of the feature for which in-product help will be shown.
* @param highlightMenuItemId The menu item which should be highlighted when menu is opened.
* @param stringId The string resource corresponding to the message in the bubble.
* @param accessibilityStringId The string resource for the message in accessibility mode.
*/
public void maybeShowAppMenuTextBubble(final Tracker tracker, String featureName,
Integer highlightMenuItemId, @StringRes int stringId,
@StringRes int accessibilityStringId) {
// Don't show the IPH if we're in the process of destroying the activity.
if (isActivityDestroyed()) return;
if (!tracker.shouldTriggerHelpUI(featureName)) return;
View anchorView = getToolbarManager().getMenuButton();
ViewRectProvider rectProvider = new ViewRectProvider(anchorView);
TextBubble textBubble =
new TextBubble(this, anchorView, stringId, accessibilityStringId, rectProvider);
textBubble.setDismissOnTouchInteraction(true);
textBubble.addOnDismissListener(() -> mHandler.postDelayed(() -> {
tracker.dismissed(featureName);
turnOffHighlightForAppMenuTextBubble();
}, ViewHighlighter.IPH_MIN_DELAY_BETWEEN_TWO_HIGHLIGHTS));
turnOnHighlightForAppMenuTextBubble(highlightMenuItemId);
int yInsetPx =
getResources().getDimensionPixelOffset(R.dimen.text_bubble_menu_anchor_y_inset);
rectProvider.setInsetPx(0, 0, 0, yInsetPx);
textBubble.show();
}
private void turnOnHighlightForAppMenuTextBubble(@Nullable Integer highlightMenuItemId) {
getAppMenuHandler().setMenuHighlight(highlightMenuItemId);
}
private void turnOffHighlightForAppMenuTextBubble() {
getAppMenuHandler().setMenuHighlight(null);
}
private boolean isMainIntentFromLauncher(Intent intent) {
return intent != null && TextUtils.equals(intent.getAction(), Intent.ACTION_MAIN)
&& intent.hasCategory(Intent.CATEGORY_LAUNCHER);
......
......@@ -11,7 +11,6 @@ import android.support.annotation.PluralsRes;
import android.text.TextUtils;
import android.text.format.Formatter;
import org.chromium.base.Callback;
import org.chromium.base.ContextUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
......@@ -19,7 +18,6 @@ import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.download.items.OfflineContentAggregatorFactory;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.infobar.DownloadProgressInfoBar;
import org.chromium.chrome.browser.infobar.IPHInfoBarSupport;
import org.chromium.chrome.browser.infobar.InfoBar;
......@@ -29,10 +27,10 @@ import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.toolbar.ToolbarButtonInProductHelpController;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.components.download.DownloadState;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.LegacyHelpers;
import org.chromium.components.offline_items_collection.OfflineContentProvider;
......@@ -784,14 +782,7 @@ public class DownloadInfoBarController implements OfflineContentProvider.Observe
ChromeTabbedActivity activity = (ChromeTabbedActivity) getCurrentTab().getActivity();
Profile profile = mIsIncognito ? Profile.getLastUsedProfile().getOffTheRecordProfile()
: Profile.getLastUsedProfile().getOriginalProfile();
final Tracker tracker = TrackerFactory.getTrackerForProfile(profile);
tracker.addOnInitializedCallback((Callback<Boolean>) success
-> activity.maybeShowAppMenuTextBubble(tracker,
FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE,
R.id.downloads_menu_id,
R.string.iph_download_infobar_download_continuing_text,
R.string.iph_download_infobar_download_continuing_text));
ToolbarButtonInProductHelpController.maybeShowDownloadContinuingIPH(activity, profile);
}
@Nullable
......
// Copyright 2018 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.toolbar;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.text.TextUtils;
import android.view.View;
import org.chromium.base.Callback;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.appmenu.AppMenuHandler;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.chrome.browser.widget.ViewHighlighter;
import org.chromium.chrome.browser.widget.textbubble.TextBubble;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.ui.widget.ViewRectProvider;
/**
* A helper class for IPH shown on the toolbar.
*/
public class ToolbarButtonInProductHelpController {
private ToolbarButtonInProductHelpController() {}
/**
* Attempts to show an IPH text bubble for those that trigger on a cold start.
* @param activity The activity to use for the IPH.
*/
public static void maybeShowColdStartIPH(ChromeTabbedActivity activity) {
maybeShowDownloadHomeIPH(activity);
maybeShowNTPButtonIPH(activity);
}
private static void maybeShowDownloadHomeIPH(ChromeTabbedActivity activity) {
setupAndMaybeShowIPHForFeature(FeatureConstants.DOWNLOAD_HOME_FEATURE,
R.id.downloads_menu_id, R.string.iph_download_home_text,
R.string.iph_download_home_accessibility_text,
activity.getToolbarManager().getMenuButton(), activity.getAppMenuHandler(),
Profile.getLastUsedProfile(), activity);
}
private static void maybeShowNTPButtonIPH(ChromeTabbedActivity activity) {
if (!canShowNTPButtonIPH(activity)) return;
String variation = ToolbarLayout.getNTPButtonVariation();
if (TextUtils.isEmpty(variation)) return;
int iphText = 0;
int iphTextForAccessibility = 0;
switch (variation) {
case "home":
iphText = R.string.iph_ntp_button_text_home_text;
iphTextForAccessibility = R.string.iph_ntp_button_text_home_accessibility_text;
break;
case "news_feed":
iphText = R.string.iph_ntp_button_text_news_feed_text;
iphTextForAccessibility = R.string.iph_ntp_button_text_news_feed_accessibility_text;
break;
case "chrome":
iphText = R.string.iph_ntp_button_text_chrome_text;
iphTextForAccessibility = R.string.iph_ntp_button_text_chrome_accessibility_text;
break;
default:
break;
}
setupAndMaybeShowIPHForFeature(FeatureConstants.NTP_BUTTON_FEATURE, null, iphText,
iphTextForAccessibility, activity.findViewById(R.id.home_button), null,
Profile.getLastUsedProfile(), activity);
}
/**
* Attempts to show an IPH text bubble for download continuing.
* @param activity The activity to use for the IPH.
* @param profile The profile to use for the tracker.
*/
public static void maybeShowDownloadContinuingIPH(
ChromeTabbedActivity activity, Profile profile) {
setupAndMaybeShowIPHForFeature(
FeatureConstants.DOWNLOAD_INFOBAR_DOWNLOAD_CONTINUING_FEATURE,
R.id.downloads_menu_id, R.string.iph_download_infobar_download_continuing_text,
R.string.iph_download_infobar_download_continuing_text,
activity.getToolbarManager().getMenuButton(), activity.getAppMenuHandler(), profile,
activity);
}
private static void setupAndMaybeShowIPHForFeature(String featureName,
Integer highlightMenuItemId, @StringRes int stringId,
@StringRes int accessibilityStringId, View anchorView,
@Nullable AppMenuHandler appMenuHandler, Profile profile,
ChromeTabbedActivity activity) {
final Tracker tracker = TrackerFactory.getTrackerForProfile(profile);
tracker.addOnInitializedCallback((Callback<Boolean>) success
-> maybeShowIPH(tracker, featureName, highlightMenuItemId, stringId,
accessibilityStringId, anchorView, appMenuHandler, activity));
}
private static void maybeShowIPH(Tracker tracker, String featureName,
Integer highlightMenuItemId, @StringRes int stringId,
@StringRes int accessibilityStringId, View anchorView, AppMenuHandler appMenuHandler,
ChromeTabbedActivity activity) {
// Activity was destroyed; don't show IPH.
if (activity.isActivityDestroyed()) return;
assert(stringId != 0 && accessibilityStringId != 0);
if (!tracker.shouldTriggerHelpUI(featureName)) return;
ViewRectProvider rectProvider = new ViewRectProvider(anchorView);
TextBubble textBubble =
new TextBubble(activity, anchorView, stringId, accessibilityStringId, rectProvider);
textBubble.setDismissOnTouchInteraction(true);
textBubble.addOnDismissListener(() -> anchorView.getHandler().postDelayed(() -> {
tracker.dismissed(featureName);
turnOffHighlightForTextBubble(appMenuHandler, anchorView);
}, ViewHighlighter.IPH_MIN_DELAY_BETWEEN_TWO_HIGHLIGHTS));
turnOnHighlightForTextBubble(appMenuHandler, highlightMenuItemId, anchorView);
int yInsetPx = activity.getResources().getDimensionPixelOffset(
R.dimen.text_bubble_menu_anchor_y_inset);
rectProvider.setInsetPx(0, 0, 0, yInsetPx);
textBubble.show();
}
private static void turnOnHighlightForTextBubble(
AppMenuHandler handler, Integer highlightMenuItemId, View anchorView) {
if (handler != null) {
handler.setMenuHighlight(highlightMenuItemId);
} else {
ViewHighlighter.turnOnHighlight(anchorView, true);
}
}
private static void turnOffHighlightForTextBubble(AppMenuHandler handler, View anchorView) {
if (handler != null) {
handler.setMenuHighlight(null);
} else {
ViewHighlighter.turnOffHighlight(anchorView);
}
}
private static boolean canShowNTPButtonIPH(ChromeTabbedActivity activity) {
return FeatureUtilities.isNewTabPageButtonEnabled()
&& !activity.getCurrentTabModel().isIncognito()
&& activity.findViewById(R.id.home_button).getVisibility() == View.VISIBLE;
}
}
......@@ -41,6 +41,7 @@ import org.chromium.chrome.browser.widget.TintedImageButton;
import org.chromium.chrome.browser.widget.ToolbarProgressBar;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.components.variations.VariationsAssociatedData;
import org.chromium.ui.UiUtils;
import javax.annotation.Nullable;
......@@ -53,6 +54,9 @@ import javax.annotation.Nullable;
public abstract class ToolbarLayout extends FrameLayout implements Toolbar {
protected static final int BACKGROUND_TRANSITION_DURATION_MS = 400;
private static final String NTP_BUTTON_TRIAL_NAME = "NewTabPage";
private static final String NTP_BUTTON_VARIATION_PARAM_NAME = "variation";
private Invalidator mInvalidator;
private final int[] mTempPosition = new int[2];
......@@ -951,4 +955,13 @@ public abstract class ToolbarLayout extends FrameLayout implements Toolbar {
* it.
*/
public void setTabModelSelector(TabModelSelector selector) {}
/**
* Gets the variation of the NTP button based on finch config.
* @return The NTP button variation.
*/
public static String getNTPButtonVariation() {
return VariationsAssociatedData.getVariationParamValue(
NTP_BUTTON_TRIAL_NAME, NTP_BUTTON_VARIATION_PARAM_NAME);
}
}
......@@ -3319,6 +3319,24 @@ However, you aren’t invisible. Going incognito doesn’t hide your browsing fr
<message name="IDS_IPH_DOWNLOAD_INFOBAR_DOWNLOADS_ARE_FASTER_TEXT" desc="The in-product-help message on the download InfoBar to inform that downloads are now faster than before.">
Chrome now downloads files faster
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_HOME_TEXT" desc="The in-product-help message to tap on the home button to navigate to the new tab page on the current tab.">
Tap to load the new tab page and view suggested articles
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_HOME_ACCESSIBILITY_TEXT" desc="The in-product-help accessibility message to tap on the home button to navigate to the new tab page on the current tab.">
Tap the home button to load the new tab page and view suggested articles
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_NEWS_FEED_TEXT" desc="The in-product-help message to tap on the home button to navigate to the new tab page on the current tab.">
Tap to view articles selected specifically for you
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_NEWS_FEED_ACCESSIBILITY_TEXT" desc="The in-product-help accessibility message to tap on the home button to navigate to the new tab page on the current tab.">
Tap the home button to view articles selected specifically for you
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_CHROME_TEXT" desc="The in-product-help message to tap on the home button to navigate to the new tab page on the current tab.">
Tap to get to the new tab page in your current tab
</message>
<message name="IDS_IPH_NTP_BUTTON_TEXT_CHROME_ACCESSIBILITY_TEXT" desc="The in-product-help accessibility message to tap on the home button to navigate to the new tab page on the current tab.">
Tap the home button to get to the new tab page in your current tab
</message>
<!-- Launcher Shortcuts -->
<message name="IDS_DISABLED_INCOGNITO_LAUNCHER_SHORTCUT_MESSAGE" desc="Text for a toast displayed prompting the user to remove the disabled 'New incognito tab' app shortcut and recreate it.">
......
......@@ -1333,6 +1333,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java",
"java/src/org/chromium/chrome/browser/toolbar/Toolbar.java",
"java/src/org/chromium/chrome/browser/toolbar/ToolbarActionModeCallback.java",
"java/src/org/chromium/chrome/browser/toolbar/ToolbarButtonInProductHelpController.java",
"java/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java",
"java/src/org/chromium/chrome/browser/toolbar/ToolbarDataProvider.java",
"java/src/org/chromium/chrome/browser/toolbar/ToolbarLayout.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment