[Start] Add IPH for the home button on tab switcher page.
Bug: 1219498 Change-Id: I86e63394c68aa8e0087c1f2813aef68fc2d8f85b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2939462 Reviewed-by: Yashar Dabiran <yashard@chromium.org> Reviewed-by: David Trainor <dtrainor@chromium.org> Reviewed-by: Yaron Friedman <yfriedman@chromium.org> Reviewed-by: Xi Han <hanxi@chromium.org> Commit-Queue: Hao Dong <spdonghao@chromium.org> Cr-Commit-Position: refs/heads/master@{#894029}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
86edae5b23
commit
9123e9c6cc
chrome/android
components/feature_engagement/public
android
java
src
org
chromium
components
feature_engagement
tools/metrics
@ -1194,6 +1194,7 @@ chrome_java_sources = [
|
||||
"java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonProperties.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/menu_button/MenuButtonViewBinder.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonController.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceHomeButtonIPHController.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarMediator.java",
|
||||
"java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java",
|
||||
|
@ -1,16 +1,19 @@
|
||||
noparent = True
|
||||
|
||||
include_rules = [
|
||||
# Allow dependencies on chrome/browser modules
|
||||
"+chrome/browser",
|
||||
|
||||
# Restrict dependencies to xsurface by default (crbug.com/1115137)
|
||||
"-chrome/browser/xsurface",
|
||||
|
||||
"-chrome/android/java/src/org/chromium/chrome/browser",
|
||||
"+base/android/java/src/org/chromium/base",
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser/toolbar",
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser/omnibox",
|
||||
"+chrome/browser/ui/android/theme",
|
||||
"+components/browser_ui/widget/android/java",
|
||||
"+ui/android/java/src/org/chromium/ui",
|
||||
"+url/android",
|
||||
"+chrome/browser/tabmodel/android/java",
|
||||
"+chrome/browser/ui/messages/android/java",
|
||||
"+components/browser_ui/bottomsheet/android/java",
|
||||
]
|
||||
|
||||
@ -22,7 +25,6 @@ specific_include_rules = {
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser",
|
||||
"-chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
|
||||
"-chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java",
|
||||
"+chrome/browser/ui/android/toolbar",
|
||||
],
|
||||
'ToolbarButtonInProductHelpController.java': [
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser",
|
||||
@ -32,7 +34,4 @@ specific_include_rules = {
|
||||
'LocationBarModel.java': [
|
||||
"+chrome/android/features/start_surface/public/java/src/org/chromium/chrome/features/start_surface/StartSurfaceConfiguration.java",
|
||||
],
|
||||
'ToolbarControlContainer.java': [
|
||||
"+chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags",
|
||||
]
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
include_rules = [
|
||||
"+chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel",
|
||||
"+chrome/browser/ui/android/layouts",
|
||||
"+chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar",
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java",
|
||||
"+chrome/android/java/src/org/chromium/chrome/browser/incognito",
|
||||
"+components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement",
|
||||
]
|
||||
|
78
chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceHomeButtonIPHController.java
Normal file
78
chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceHomeButtonIPHController.java
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2021 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.top;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.chrome.browser.user_education.IPHCommand;
|
||||
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
|
||||
import org.chromium.chrome.browser.user_education.UserEducationHelper;
|
||||
import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
|
||||
import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
|
||||
import org.chromium.components.feature_engagement.EventConstants;
|
||||
import org.chromium.components.feature_engagement.FeatureConstants;
|
||||
import org.chromium.components.feature_engagement.Tracker;
|
||||
|
||||
/**
|
||||
* Controller to manage when and how we show home button in-product-help messages on the tab
|
||||
* switcher when start surface is enabled to users.
|
||||
*/
|
||||
public class StartSurfaceHomeButtonIPHController {
|
||||
private final UserEducationHelper mUserEducationHelper;
|
||||
private final IPHCommand mIPHCommand;
|
||||
private boolean mIsShowingIPH;
|
||||
|
||||
public StartSurfaceHomeButtonIPHController(
|
||||
UserEducationHelper userEducationHelper, View homeButtonView) {
|
||||
mUserEducationHelper = userEducationHelper;
|
||||
mIPHCommand = new IPHCommandBuilder(homeButtonView.getResources(),
|
||||
FeatureConstants.START_SURFACE_TAB_SWITCHER_HOME_BUTTON_FEATURE,
|
||||
org.chromium.chrome.R.string.iph_ntp_with_feed_text,
|
||||
org.chromium.chrome.R.string.iph_ntp_with_feed_accessibility_text)
|
||||
.setAnchorView(homeButtonView)
|
||||
.setHighlightParams(new HighlightParams(HighlightShape.CIRCLE))
|
||||
.setDismissOnTouch(true)
|
||||
.setOnShowCallback(() -> mIsShowingIPH = true)
|
||||
.setOnDismissCallback(() -> mIsShowingIPH = false)
|
||||
.setAutoDismissTimeout(10 * 1000)
|
||||
.build();
|
||||
}
|
||||
|
||||
public void maybeShowIPH() {
|
||||
if (!mIsShowingIPH) {
|
||||
mUserEducationHelper.requestShowIPH(mIPHCommand);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Record the home button has been clicked when IPH is showing.
|
||||
*/
|
||||
public void onHomeButtonClicked() {
|
||||
if (mIsShowingIPH) {
|
||||
Tracker tracker =
|
||||
TrackerFactory.getTrackerForProfile(Profile.getLastUsedRegularProfile());
|
||||
tracker.notifyEvent(EventConstants.START_SURFACE_TAB_SWITCHER_HOME_BUTTON_CLICKED);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isShowingHomeButtonIPHForTesting() {
|
||||
return mIsShowingIPH;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setIsShowingIPHForTesting(boolean isShowing) {
|
||||
mIsShowingIPH = isShowing;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
IPHCommand getIPHCommand() {
|
||||
return mIPHCommand;
|
||||
}
|
||||
}
|
4
chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
4
chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarCoordinator.java
@ -95,7 +95,7 @@ public class StartSurfaceToolbarCoordinator {
|
||||
homepageEnabledSupplier, startSurfaceAsHomepageSupplier,
|
||||
homepageManagedByPolicySupplier, homeButtonOnClickHandler,
|
||||
StartSurfaceConfiguration.shouldShowNewSurfaceFromHomeButton(),
|
||||
isTabGroupsAndroidContinuationEnabled);
|
||||
isTabGroupsAndroidContinuationEnabled, userEducationHelper);
|
||||
|
||||
mThemeColorProvider = provider;
|
||||
mMenuButtonCoordinator = menuButtonCoordinator;
|
||||
@ -259,6 +259,8 @@ public class StartSurfaceToolbarCoordinator {
|
||||
mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(
|
||||
mPropertyModel, mView, StartSurfaceToolbarViewBinder::bind);
|
||||
|
||||
mToolbarMediator.setHomeButtonView(mView.getHomeButtonView());
|
||||
|
||||
if (StartSurfaceConfiguration.shouldShowNewSurfaceFromHomeButton()) {
|
||||
mTabSwitcherButtonView = mView.findViewById(R.id.start_tab_switcher_button);
|
||||
if (mTabSwitcherLongClickListener != null) {
|
||||
|
@ -52,6 +52,7 @@ import org.chromium.chrome.browser.toolbar.ButtonData.ButtonSpec;
|
||||
import org.chromium.chrome.browser.toolbar.TabCountProvider;
|
||||
import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
|
||||
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
|
||||
import org.chromium.chrome.browser.user_education.UserEducationHelper;
|
||||
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
|
||||
import org.chromium.chrome.features.start_surface.StartSurfaceState;
|
||||
import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver;
|
||||
@ -60,11 +61,12 @@ import org.chromium.ui.modelutil.PropertyModel;
|
||||
/** The mediator implements interacts between the views and the caller. */
|
||||
class StartSurfaceToolbarMediator {
|
||||
private final PropertyModel mPropertyModel;
|
||||
private final Callback<IPHCommandBuilder> mShowIPHCallback;
|
||||
private final Callback<IPHCommandBuilder> mShowIdentityIPHCallback;
|
||||
private final boolean mHideIncognitoSwitchWhenNoTabs;
|
||||
private final boolean mShouldShowTabSwitcherButtonOnHomepage;
|
||||
private final Supplier<ButtonData> mIdentityDiscButtonSupplier;
|
||||
private final boolean mIsTabGroupsAndroidContinuationEnabled;
|
||||
private final UserEducationHelper mUserEducationHelper;
|
||||
|
||||
private TabModelSelector mTabModelSelector;
|
||||
private TabCountProvider mTabCountProvider;
|
||||
@ -83,8 +85,11 @@ class StartSurfaceToolbarMediator {
|
||||
private float mNonIncognitoHomepageTranslationY;
|
||||
|
||||
private boolean mShowHomeButtonOnTabSwitcher;
|
||||
private StartSurfaceHomeButtonIPHController mStartSurfaceHomeButtonIPHController;
|
||||
private View mHomeButtonView;
|
||||
|
||||
StartSurfaceToolbarMediator(PropertyModel model, Callback<IPHCommandBuilder> showIPHCallback,
|
||||
StartSurfaceToolbarMediator(PropertyModel model,
|
||||
Callback<IPHCommandBuilder> showIdentityIPHCallback,
|
||||
boolean hideIncognitoSwitchWhenNoTabs, boolean showHomeButtonOnTabSwitcher,
|
||||
MenuButtonCoordinator menuButtonCoordinator,
|
||||
ObservableSupplier<Boolean> identityDiscStateSupplier,
|
||||
@ -93,14 +98,16 @@ class StartSurfaceToolbarMediator {
|
||||
ObservableSupplier<Boolean> startSurfaceAsHomepageSupplier,
|
||||
ObservableSupplier<Boolean> homepageManagedByPolicySupplier,
|
||||
OnClickListener homeButtonOnClickHandler, boolean shouldShowTabSwitcherButtonOnHomepage,
|
||||
boolean isTabGroupsAndroidContinuationEnabled) {
|
||||
boolean isTabGroupsAndroidContinuationEnabled,
|
||||
UserEducationHelper userEducationHelper) {
|
||||
mPropertyModel = model;
|
||||
mOverviewModeState = StartSurfaceState.NOT_SHOWN;
|
||||
mShowIPHCallback = showIPHCallback;
|
||||
mShowIdentityIPHCallback = showIdentityIPHCallback;
|
||||
mHideIncognitoSwitchWhenNoTabs = hideIncognitoSwitchWhenNoTabs;
|
||||
mMenuButtonCoordinator = menuButtonCoordinator;
|
||||
mIdentityDiscButtonSupplier = identityDiscButtonSupplier;
|
||||
mIsTabGroupsAndroidContinuationEnabled = isTabGroupsAndroidContinuationEnabled;
|
||||
mUserEducationHelper = userEducationHelper;
|
||||
identityDiscStateSupplier.addObserver((canShowHint) -> {
|
||||
// If the identity disc wants to be hidden and is hidden, there's nothing we need to do.
|
||||
if (!canShowHint && !mPropertyModel.get(IDENTITY_DISC_IS_VISIBLE)) return;
|
||||
@ -116,7 +123,16 @@ class StartSurfaceToolbarMediator {
|
||||
}));
|
||||
mPropertyModel.set(
|
||||
HOMEPAGE_MANAGED_BY_POLICY_SUPPLIER, homepageManagedByPolicySupplier);
|
||||
mPropertyModel.set(HOME_BUTTON_CLICK_HANDLER, homeButtonOnClickHandler);
|
||||
|
||||
View.OnClickListener homeButtonOnClickListener = v -> {
|
||||
if (homeButtonOnClickHandler != null) homeButtonOnClickHandler.onClick(v);
|
||||
|
||||
if (mStartSurfaceHomeButtonIPHController != null) {
|
||||
mStartSurfaceHomeButtonIPHController.onHomeButtonClicked();
|
||||
}
|
||||
};
|
||||
|
||||
mPropertyModel.set(HOME_BUTTON_CLICK_HANDLER, homeButtonOnClickListener);
|
||||
startSurfaceAsHomepageSupplier.addObserver(
|
||||
mCallbackController.makeCancelable((showStartSurfaceAsHomepage) -> {
|
||||
mShouldShowStartSurfaceAsHomepage = showStartSurfaceAsHomepage;
|
||||
@ -356,6 +372,10 @@ class StartSurfaceToolbarMediator {
|
||||
mPropertyModel.set(NEW_TAB_BUTTON_HIGHLIGHT, highlight);
|
||||
}
|
||||
|
||||
void setHomeButtonView(View homeButtonView) {
|
||||
mHomeButtonView = homeButtonView;
|
||||
}
|
||||
|
||||
private void updateLogoVisibility(boolean isGoogleSearchEngine) {
|
||||
mIsGoogleSearchEngine = isGoogleSearchEngine;
|
||||
boolean shouldShowLogo =
|
||||
@ -375,7 +395,7 @@ class StartSurfaceToolbarMediator {
|
||||
IDENTITY_DISC_IMAGE, buttonSpec.getDrawable().getConstantState().newDrawable());
|
||||
mPropertyModel.set(IDENTITY_DISC_DESCRIPTION, buttonSpec.getContentDescriptionResId());
|
||||
mPropertyModel.set(IDENTITY_DISC_IS_VISIBLE, true);
|
||||
mShowIPHCallback.onResult(buttonSpec.getIPHCommandBuilder());
|
||||
mShowIdentityIPHCallback.onResult(buttonSpec.getIPHCommandBuilder());
|
||||
} else {
|
||||
mPropertyModel.set(IDENTITY_DISC_IS_VISIBLE, false);
|
||||
}
|
||||
@ -394,11 +414,21 @@ class StartSurfaceToolbarMediator {
|
||||
|
||||
private void updateHomeButtonVisibility() {
|
||||
boolean isShownTabSwitcherState = mOverviewModeState == StartSurfaceState.SHOWN_TABSWITCHER;
|
||||
boolean shouldShow = mHomepageEnabled && isShownTabSwitcherState
|
||||
&& !mPropertyModel.get(IS_INCOGNITO) && mShowHomeButtonOnTabSwitcher
|
||||
&& mShouldShowStartSurfaceAsHomepage;
|
||||
// If start surface is not shown as the homepage, home button shouldn't be shown on tab
|
||||
// switcher page.
|
||||
mPropertyModel.set(HOME_BUTTON_IS_VISIBLE,
|
||||
mHomepageEnabled && isShownTabSwitcherState && !mPropertyModel.get(IS_INCOGNITO)
|
||||
&& mShowHomeButtonOnTabSwitcher && mShouldShowStartSurfaceAsHomepage);
|
||||
mPropertyModel.set(HOME_BUTTON_IS_VISIBLE, shouldShow);
|
||||
|
||||
// If the home button is shown, maybe show the IPH.
|
||||
if (shouldShow) {
|
||||
if (mStartSurfaceHomeButtonIPHController == null) {
|
||||
mStartSurfaceHomeButtonIPHController = new StartSurfaceHomeButtonIPHController(
|
||||
mUserEducationHelper, mHomeButtonView);
|
||||
}
|
||||
mStartSurfaceHomeButtonIPHController.maybeShowIPH();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTabSwitcherButtonVisibility() {
|
||||
@ -433,4 +463,10 @@ class StartSurfaceToolbarMediator {
|
||||
void setShowHomeButtonOnTabSwitcherForTesting(boolean showHomeButtonOnTabSwitcher) {
|
||||
mShowHomeButtonOnTabSwitcher = showHomeButtonOnTabSwitcher;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setStartSurfaceHomeButtonIPHControllerForTesting(
|
||||
StartSurfaceHomeButtonIPHController startSurfaceHomeButtonIPHController) {
|
||||
mStartSurfaceHomeButtonIPHController = startSurfaceHomeButtonIPHController;
|
||||
}
|
||||
}
|
||||
|
@ -246,6 +246,11 @@ class StartSurfaceToolbarView extends RelativeLayout {
|
||||
return mIdentityDiscButton;
|
||||
}
|
||||
|
||||
/** Return the home button view. */
|
||||
View getHomeButtonView() {
|
||||
return mHomeButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isAtStart Whether the identity disc is at start.
|
||||
*/
|
||||
|
@ -13,8 +13,10 @@ import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.BUTTONS_CLICKABLE;
|
||||
import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_CLICK_HANDLER;
|
||||
import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.HOME_BUTTON_IS_VISIBLE;
|
||||
import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_AT_START;
|
||||
import static org.chromium.chrome.browser.toolbar.top.StartSurfaceToolbarProperties.IDENTITY_DISC_CLICK_HANDLER;
|
||||
@ -47,9 +49,11 @@ import org.robolectric.annotation.Config;
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.base.supplier.ObservableSupplierImpl;
|
||||
import org.chromium.base.test.BaseRobolectricTestRunner;
|
||||
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
|
||||
import org.chromium.chrome.browser.identity_disc.IdentityDiscController;
|
||||
import org.chromium.chrome.browser.layouts.LayoutStateProvider;
|
||||
import org.chromium.chrome.browser.layouts.LayoutType;
|
||||
import org.chromium.chrome.browser.profiles.Profile;
|
||||
import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
|
||||
import org.chromium.chrome.browser.tab.Tab;
|
||||
import org.chromium.chrome.browser.tabmodel.TabModel;
|
||||
@ -59,8 +63,11 @@ import org.chromium.chrome.browser.toolbar.ButtonData.ButtonSpec;
|
||||
import org.chromium.chrome.browser.toolbar.ButtonDataImpl;
|
||||
import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
|
||||
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
|
||||
import org.chromium.chrome.browser.user_education.UserEducationHelper;
|
||||
import org.chromium.chrome.browser.util.ChromeAccessibilityUtil;
|
||||
import org.chromium.chrome.features.start_surface.StartSurfaceState;
|
||||
import org.chromium.components.feature_engagement.EventConstants;
|
||||
import org.chromium.components.feature_engagement.Tracker;
|
||||
import org.chromium.components.search_engines.TemplateUrlService;
|
||||
import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver;
|
||||
import org.chromium.ui.modelutil.PropertyModel;
|
||||
@ -92,11 +99,21 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
@Mock
|
||||
Drawable.ConstantState mMockConstantState;
|
||||
@Mock
|
||||
Callback<IPHCommandBuilder> mMockCallback;
|
||||
Callback<IPHCommandBuilder> mMockIdentityIPHCallback;
|
||||
@Mock
|
||||
Tab mMockIncognitoTab;
|
||||
@Mock
|
||||
MenuButtonCoordinator mMenuButtonCoordinator;
|
||||
@Mock
|
||||
UserEducationHelper mUserEducationHelper;
|
||||
@Mock
|
||||
View mHomeButtonView;
|
||||
@Mock
|
||||
Resources mResources;
|
||||
@Mock
|
||||
private Profile mProfile;
|
||||
@Mock
|
||||
Tracker mTracker;
|
||||
@Captor
|
||||
private ArgumentCaptor<LayoutStateProvider.LayoutStateObserver> mLayoutStateObserverCaptor;
|
||||
@Captor
|
||||
@ -109,6 +126,7 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
private ObservableSupplierImpl<Boolean> mIdentityDiscStateSupplier;
|
||||
private ObservableSupplierImpl<Boolean> mStartSurfaceAsHomepageSupplier;
|
||||
private ObservableSupplierImpl<Boolean> mHomepageEnabledSupplier;
|
||||
private StartSurfaceHomeButtonIPHController mStartSurfaceHomeButtonIPHController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -129,6 +147,12 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
mHomepageEnabledSupplier = new ObservableSupplierImpl<>();
|
||||
mHomepageEnabledSupplier.set(true);
|
||||
|
||||
Profile.setLastUsedProfileForTesting(mProfile);
|
||||
when(mHomeButtonView.getResources()).thenReturn(mResources);
|
||||
TrackerFactory.setTrackerForTests(mTracker);
|
||||
mStartSurfaceHomeButtonIPHController =
|
||||
new StartSurfaceHomeButtonIPHController(mUserEducationHelper, mHomeButtonView);
|
||||
|
||||
doReturn(mButtonData)
|
||||
.when(mIdentityDiscController)
|
||||
.getForStartSurface(StartSurfaceState.SHOWN_HOMEPAGE);
|
||||
@ -424,7 +448,7 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
mMediator.updateIdentityDisc(mButtonData);
|
||||
assertTrue(mPropertyModel.get(IDENTITY_DISC_IS_VISIBLE));
|
||||
|
||||
verify(mMockCallback, times(1))
|
||||
verify(mMockIdentityIPHCallback, times(1))
|
||||
.onResult(mButtonData.getButtonSpec().getIPHCommandBuilder());
|
||||
}
|
||||
|
||||
@ -680,6 +704,27 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
assertFalse(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowHomeButtonIPH() {
|
||||
createMediator(false, true, false, false);
|
||||
|
||||
// Show tab switcher surface and the IPH should show.
|
||||
assertFalse(mStartSurfaceHomeButtonIPHController.isShowingHomeButtonIPHForTesting());
|
||||
mMediator.setStartSurfaceMode(true);
|
||||
mLayoutStateObserverCaptor.getValue().onStartedShowing(LayoutType.TAB_SWITCHER, false);
|
||||
mLayoutStateObserverCaptor.getValue().onFinishedShowing(LayoutType.TAB_SWITCHER);
|
||||
mMediator.onStartSurfaceStateChanged(StartSurfaceState.SHOWN_TABSWITCHER, true);
|
||||
assertTrue(mPropertyModel.get(HOME_BUTTON_IS_VISIBLE));
|
||||
verify(mUserEducationHelper, times(1))
|
||||
.requestShowIPH(mStartSurfaceHomeButtonIPHController.getIPHCommand());
|
||||
|
||||
// When the IPH is showing and the home button is clicked,
|
||||
// START_SURFACE_TAB_SWITCHER_HOME_BUTTON_CLICKED event should be notified.
|
||||
mStartSurfaceHomeButtonIPHController.setIsShowingIPHForTesting(true);
|
||||
mPropertyModel.get(HOME_BUTTON_CLICK_HANDLER).onClick(mHomeButtonView);
|
||||
verify(mTracker).notifyEvent(EventConstants.START_SURFACE_TAB_SWITCHER_HOME_BUTTON_CLICKED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewHomeSurface() {
|
||||
createMediator(false, true, true, false);
|
||||
@ -752,7 +797,7 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
private void createMediator(boolean hideIncognitoSwitchWhenNoTabs,
|
||||
boolean showHomeButtonOnTabSwitcher, boolean shouldShowTabSwitcherButtonOnHomepage,
|
||||
boolean isTabGroupsAndroidContinuationEnabled) {
|
||||
mMediator = new StartSurfaceToolbarMediator(mPropertyModel, mMockCallback,
|
||||
mMediator = new StartSurfaceToolbarMediator(mPropertyModel, mMockIdentityIPHCallback,
|
||||
hideIncognitoSwitchWhenNoTabs, showHomeButtonOnTabSwitcher, mMenuButtonCoordinator,
|
||||
mIdentityDiscStateSupplier,
|
||||
()
|
||||
@ -760,9 +805,11 @@ public class StartSurfaceToolbarMediatorUnitTest {
|
||||
mMediator.getOverviewModeStateForTesting()),
|
||||
mHomepageEnabledSupplier, mStartSurfaceAsHomepageSupplier,
|
||||
new ObservableSupplierImpl<>(), null, shouldShowTabSwitcherButtonOnHomepage,
|
||||
isTabGroupsAndroidContinuationEnabled);
|
||||
isTabGroupsAndroidContinuationEnabled, mUserEducationHelper);
|
||||
|
||||
mMediator.setLayoutStateProvider(mLayoutStateProvider);
|
||||
mMediator.setStartSurfaceHomeButtonIPHControllerForTesting(
|
||||
mStartSurfaceHomeButtonIPHController);
|
||||
verify(mLayoutStateProvider).addObserver(mLayoutStateObserverCaptor.capture());
|
||||
}
|
||||
}
|
||||
|
@ -253,6 +253,10 @@ public final class EventConstants {
|
||||
/** WebFeed events. */
|
||||
public static final String WEB_FEED_FOLLOW_INTRO_CLICKED = "web_feed_follow_intro_clicked";
|
||||
|
||||
/** Tab switcher home button events. */
|
||||
public static final String START_SURFACE_TAB_SWITCHER_HOME_BUTTON_CLICKED =
|
||||
"start_surface_tab_switcher_home_button_clicked";
|
||||
|
||||
/**
|
||||
* Do not instantiate.
|
||||
*/
|
||||
|
@ -55,7 +55,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
FeatureConstants.PWA_INSTALL_AVAILABLE_FEATURE, FeatureConstants.PAGE_INFO_FEATURE,
|
||||
FeatureConstants.IPH_SHARE_SCREENSHOT_FEATURE, FeatureConstants.IPH_WEB_FEED_FOLLOW_FEATURE,
|
||||
FeatureConstants.IPH_WEB_FEED_POST_FOLLOW_DIALOG_FEATURE,
|
||||
FeatureConstants.SHARED_HIGHLIGHTING_BUILDER_FEATURE})
|
||||
FeatureConstants.SHARED_HIGHLIGHTING_BUILDER_FEATURE,
|
||||
FeatureConstants.START_SURFACE_TAB_SWITCHER_HOME_BUTTON_FEATURE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FeatureConstants {
|
||||
String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_NEW_TAB_FEATURE =
|
||||
@ -273,4 +274,10 @@ public @interface FeatureConstants {
|
||||
* An IPH feature to inform users about the link-to-text on selection share.
|
||||
*/
|
||||
String SHARED_HIGHLIGHTING_BUILDER_FEATURE = "IPH_SharedHighlightingBuilder";
|
||||
|
||||
/**
|
||||
* An IPH feature to prompt users to click home button on the tab switcher surface when start
|
||||
* surface is enabled.
|
||||
*/
|
||||
String START_SURFACE_TAB_SWITCHER_HOME_BUTTON_FEATURE = "IPH_StartSurfaceTabSwitcherHomeButton";
|
||||
}
|
||||
|
@ -227,6 +227,28 @@ absl::optional<FeatureConfig> GetClientSideFeatureConfig(
|
||||
Comparator(ANY, 0), 360, 360);
|
||||
return config;
|
||||
}
|
||||
|
||||
if (kIPHStartSurfaceTabSwitcherHomeButton.name == feature->name) {
|
||||
// A config that allows the StartSurfaceTabSwitcherHomeButton IPH to be
|
||||
// shown:
|
||||
// * Once per day
|
||||
// * Up to 7 times but only if the home button is not clicked when IPH is
|
||||
// showing.
|
||||
absl::optional<FeatureConfig> config = FeatureConfig();
|
||||
config->valid = true;
|
||||
config->availability = Comparator(ANY, 0);
|
||||
config->session_rate = Comparator(ANY, 0);
|
||||
config->trigger =
|
||||
EventConfig("start_surface_tab_switcher_home_button_iph_trigger",
|
||||
Comparator(LESS_THAN, 7), k10YearsInDays, k10YearsInDays);
|
||||
config->used =
|
||||
EventConfig("start_surface_tab_switcher_home_button_clicked",
|
||||
Comparator(EQUAL, 0), k10YearsInDays, k10YearsInDays);
|
||||
config->event_configs.insert(
|
||||
EventConfig("start_surface_tab_switcher_home_button_iph_trigger",
|
||||
Comparator(EQUAL, 0), 1, 360));
|
||||
return config;
|
||||
}
|
||||
#endif // defined(OS_ANDROID)
|
||||
|
||||
if (kIPHDummyFeature.name == feature->name) {
|
||||
|
@ -180,6 +180,8 @@ const base::Feature kIPHWebFeedPostFollowDialogFeature{
|
||||
"IPH_WebFeedPostFollowDialog", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
const base::Feature kIPHSharedHighlightingBuilder{
|
||||
"IPH_SharedHighlightingBuilder", base::FEATURE_DISABLED_BY_DEFAULT};
|
||||
const base::Feature kIPHStartSurfaceTabSwitcherHomeButton{
|
||||
"IPH_StartSurfaceTabSwitcherHomeButton", base::FEATURE_ENABLED_BY_DEFAULT};
|
||||
#endif // defined(OS_ANDROID)
|
||||
|
||||
#if defined(OS_IOS)
|
||||
|
@ -107,6 +107,7 @@ extern const base::Feature kIPHShareScreenshotFeature;
|
||||
extern const base::Feature kIPHWebFeedFollowFeature;
|
||||
extern const base::Feature kIPHWebFeedPostFollowDialogFeature;
|
||||
extern const base::Feature kIPHSharedHighlightingBuilder;
|
||||
extern const base::Feature kIPHStartSurfaceTabSwitcherHomeButton;
|
||||
#endif // defined(OS_ANDROID)
|
||||
|
||||
#if defined(OS_IOS)
|
||||
|
@ -80,6 +80,7 @@ const base::Feature* const kAllFeatures[] = {
|
||||
&kIPHWebFeedFollowFeature,
|
||||
&kIPHWebFeedPostFollowDialogFeature,
|
||||
&kIPHSharedHighlightingBuilder,
|
||||
&kIPHStartSurfaceTabSwitcherHomeButton,
|
||||
#endif // defined(OS_ANDROID)
|
||||
#if defined(OS_IOS)
|
||||
&kIPHBottomToolbarTipFeature,
|
||||
|
@ -155,6 +155,8 @@ DEFINE_VARIATION_PARAM(kIPHWebFeedPostFollowDialogFeature,
|
||||
"IPH_WebFeedPostFollowDialog");
|
||||
DEFINE_VARIATION_PARAM(kIPHSharedHighlightingBuilder,
|
||||
"IPH_SharedHighlightingBuilder");
|
||||
DEFINE_VARIATION_PARAM(kIPHStartSurfaceTabSwitcherHomeButton,
|
||||
"IPH_StartSurfaceTabSwitcherHomeButton");
|
||||
#endif // defined(OS_ANDROID)
|
||||
#if defined(OS_IOS)
|
||||
DEFINE_VARIATION_PARAM(kIPHBottomToolbarTipFeature, "IPH_BottomToolbarTip");
|
||||
|
@ -28590,6 +28590,8 @@ should be able to be added at any place in this file.
|
||||
<suffix name="ReopenTab" label="For ReopenTab feature."/>
|
||||
<suffix name="SharedHighlightingBuilder"
|
||||
label="For SharedHighlightingBuilder feature."/>
|
||||
<suffix name="StartSurfaceTabSwitcherHomeButton"
|
||||
label="For StartSurfaceTabSwitcherHomeButton feature."/>
|
||||
<suffix name="TabGroupsDragAndDrop" label="For drop-to-merge in tab group."/>
|
||||
<suffix name="TabGroupsQuicklyComparePages"
|
||||
label="For long press links to create tab groups."/>
|
||||
|
@ -8299,6 +8299,9 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
|
||||
<suffix name="IPH_SharedHighlightingBuilder"
|
||||
label="The in product help message to notify the user that the share
|
||||
action can preemptively share a link-to-text."/>
|
||||
<suffix name="IPH_StartSurfaceTabSwitcherHomeButton"
|
||||
label="In product help for home button on the tab switcher when start
|
||||
surface is enabled."/>
|
||||
<suffix name="IPH_TabGroupsDragAndDrop"
|
||||
label="In product help for educating user to drop one tab on another
|
||||
tab to create group."/>
|
||||
|
Reference in New Issue
Block a user