blob: ecf2ba2b47c9009a88f70fd71fe2a77f97943ff4 [file] [log] [blame]
// 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.base.ThreadUtils;
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.ntp.NewTabPage;
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;
setupAndMaybeShowIPHForFeature(FeatureConstants.NTP_BUTTON_FEATURE, null,
R.string.iph_ntp_button_text_home_text,
R.string.iph_ntp_button_text_home_accessibility_text,
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() || anchorView == null) return;
assert(stringId != 0 && accessibilityStringId != 0);
// Post a request to show the IPH bubble to allow time for a layout pass. Since the bubble
// is shown on startup, the anchor view may not have a height initially see
// https://crbug.com/871537.
ThreadUtils.postOnUiThread(() -> {
if (activity.isActivityDestroyed()) return;
if (TextUtils.equals(featureName, FeatureConstants.NTP_BUTTON_FEATURE)
&& !canShowNTPButtonIPH(activity)) {
return;
}
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) {
View homeButton = activity.findViewById(R.id.home_button);
return FeatureUtilities.isNewTabPageButtonEnabled()
&& !activity.getCurrentTabModel().isIncognito() && activity.getActivityTab() != null
&& !NewTabPage.isNTPUrl(activity.getActivityTab().getUrl()) && homeButton != null
&& homeButton.getVisibility() == View.VISIBLE;
}
}