Commit 39313249 authored by Zhiyuan Cai's avatar Zhiyuan Cai Committed by Chromium LUCI CQ

PriceWelcomeMessageCard component follow-on

This change contains the following:
* Remove/restore the message when the binding tab closes/closure undone.
* Disable the message after showing 10 times and no actions taken.
* Reset tabs when users turn on/off "track prices on tabs" from the menu.

Bug: 1148020
Change-Id: If54e9352aa5f3ce724f1141a90f40d8cc0e0a230
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2575579Reviewed-by: default avatarYue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarMei Liang <meiliang@chromium.org>
Commit-Queue: Zhiyuan Cai <zhiyuancai@google.com>
Cr-Commit-Position: refs/heads/master@{#837350}
parent 4e9b4c26
......@@ -49,6 +49,7 @@ class MessageCardViewProperties {
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyModel.WritableObjectPropertyKey<String> TITLE_TEXT =
new PropertyModel.WritableObjectPropertyKey<>();
// TODO(crbug.com/1148020): Change to a more general property CUSTOM_INFO_OBJECT
public static final PropertyModel
.WritableObjectPropertyKey<ShoppingPersistedTabData.PriceDrop> PRICE_DROP =
new PropertyModel.WritableObjectPropertyKey<>();
......
......@@ -25,6 +25,8 @@ public class PriceTrackingUtilities {
ChromePreferenceKeys.PRICE_TRACKING_TRACK_PRICES_ON_TABS;
private static final String PRICE_WELCOME_MESSAGE_CARD =
ChromePreferenceKeys.PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD;
private static final String PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT =
ChromePreferenceKeys.PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT;
@VisibleForTesting
public static final SharedPreferencesManager SHARED_PREFERENCES_MANAGER =
......@@ -75,7 +77,23 @@ public class PriceTrackingUtilities {
* @return Whether the PriceWelcomeMessageCard is disabled by users.
*/
public static boolean isPriceWelcomeMessageCardDisabled() {
return !SHARED_PREFERENCES_MANAGER.readBoolean(PRICE_WELCOME_MESSAGE_CARD, true);
return !SHARED_PREFERENCES_MANAGER.readBoolean(
PRICE_WELCOME_MESSAGE_CARD, TabUiFeatureUtilities.isPriceTrackingEnabled());
}
/**
* Increase the show count of PriceWelcomeMessageCard every time it shows in the tab switcher.
*/
public static void increasePriceWelcomeMessageCardShowCount() {
SHARED_PREFERENCES_MANAGER.writeInt(
PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT, getPriceWelcomeMessageCardShowCount() + 1);
}
/**
* @return The show count of PriceWelcomeMessageCard.
*/
public static int getPriceWelcomeMessageCardShowCount() {
return SHARED_PREFERENCES_MANAGER.readInt(PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT, 0);
}
private static boolean isSignedIn() {
......
......@@ -113,6 +113,14 @@ public class PriceWelcomeMessageService extends MessageService {
}
}
private static final int MAX_PRICE_WELCOME_MESSAGE_SHOW_COUNT = 10;
// TODO(crbug.com/1148020): Currently every time entering the tab switcher, {@link
// ResetHandler.resetWithTabs} will be called twice if {@link
// TabUiFeatureUtilities#isTabToGtsAnimationEnabled} returns true, see {@link
// TabSwitcherMediator#prepareOverview}.
private static final int PREPARE_MESSAGE_TIMES_ENTERING_TAB_SWITCHER =
TabUiFeatureUtilities.isTabToGtsAnimationEnabled() ? 2 : 1;
private final PriceWelcomeMessageProvider mPriceWelcomeMessageProvider;
private final PriceWelcomeMessageReviewActionProvider mPriceWelcomeMessageReviewActionProvider;
......@@ -130,8 +138,15 @@ public class PriceWelcomeMessageService extends MessageService {
if (PriceTrackingUtilities.isPriceWelcomeMessageCardDisabled()) return;
PriceTabData priceTabData = mPriceWelcomeMessageProvider.getFirstTabShowingPriceCard();
if (priceTabData == null) {
mPriceTabData = null;
sendInvalidNotification();
invalidateMessage();
return;
}
PriceTrackingUtilities.increasePriceWelcomeMessageCardShowCount();
if (PriceTrackingUtilities.getPriceWelcomeMessageCardShowCount()
> MAX_PRICE_WELCOME_MESSAGE_SHOW_COUNT
* PREPARE_MESSAGE_TIMES_ENTERING_TAB_SWITCHER) {
invalidateMessage();
PriceTrackingUtilities.disablePriceWelcomeMessageCard();
} else if (!priceTabData.equals(mPriceTabData)) {
mPriceTabData = priceTabData;
sendInvalidNotification();
......@@ -140,6 +155,16 @@ public class PriceWelcomeMessageService extends MessageService {
}
}
int getBindingTabId() {
if (mPriceTabData == null) return Tab.INVALID_TAB_ID;
return mPriceTabData.bindingTabId;
}
void invalidateMessage() {
mPriceTabData = null;
sendInvalidNotification();
}
private void review() {
assert mPriceTabData != null;
mPriceWelcomeMessageReviewActionProvider.scrollToBindingTab(
......
......@@ -237,6 +237,7 @@ class TabGridViewBinder {
});
} else {
priceCardView.setVisibility(View.GONE);
// TODO(crbug.com/1157578): Update the model in mediator.
model.set(TabProperties.PRICE_DROP, null);
}
} else if (TabProperties.PAGE_INFO_LISTENER == propertyKey) {
......
......@@ -340,13 +340,6 @@ public class TabListCoordinator
return tabListRect.top;
}
/**
* @return The index of the model list where the PriceWelcomeMessage should be inserted.
*/
int getPriceWelcomeMessageIndex() {
return mModel.size();
}
/**
* @return The container {@link androidx.recyclerview.widget.RecyclerView} that is showing the
* tab list UI.
......
......@@ -54,7 +54,8 @@ import java.util.List;
*/
public class TabSwitcherCoordinator
implements Destroyable, TabSwitcher, TabSwitcher.TabListDelegate,
TabSwitcherMediator.ResetHandler, TabSwitcherMediator.MessageItemsController {
TabSwitcherMediator.ResetHandler, TabSwitcherMediator.MessageItemsController,
TabSwitcherMediator.PriceWelcomeMessageController {
/**
* Interface to control the IPH dialog.
*/
......@@ -135,6 +136,9 @@ public class TabSwitcherCoordinator
return true;
} else if (id == R.id.track_prices_id || id == R.id.track_prices_check_id) {
PriceTrackingUtilities.flipTrackPricesOnTabs();
resetWithTabList(mTabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter(),
false, TabSwitcherMediator.isShowingTabsInMRUOrder());
return true;
}
return false;
......@@ -159,8 +163,8 @@ public class TabSwitcherCoordinator
PropertyModel containerViewModel = new PropertyModel(TabListContainerProperties.ALL_KEYS);
mMediator = new TabSwitcherMediator(context, this, containerViewModel, tabModelSelector,
browserControls, container, tabContentManager, this, multiWindowModeStateDispatcher,
mode);
browserControls, container, tabContentManager, this, this,
multiWindowModeStateDispatcher, mode);
mMultiThumbnailCardProvider =
new MultiThumbnailCardProvider(context, tabContentManager, tabModelSelector);
......@@ -321,11 +325,13 @@ public class TabSwitcherCoordinator
mMessageCardProviderCoordinator.subscribeMessageService(iphMessageService);
}
if (TabUiFeatureUtilities.isPriceTrackingEnabled()) {
if (TabUiFeatureUtilities.isPriceTrackingEnabled()
&& !PriceTrackingUtilities.isPriceWelcomeMessageCardDisabled()) {
mPriceWelcomeMessageService =
new PriceWelcomeMessageService(mTabListCoordinator, mMediator);
mMessageCardProviderCoordinator.subscribeMessageService(
mPriceWelcomeMessageService);
mMediator.setPriceWelcomeMessageService(mPriceWelcomeMessageService);
}
}
mIsInitialized = true;
......@@ -470,6 +476,8 @@ public class TabSwitcherCoordinator
}
if (tabs != null && tabs.size() > 0) {
// TODO(crbug.com/1157578): Auto update the PriceWelcomeMessageService instead of
// updating it based on the client caller.
if (mPriceWelcomeMessageService != null) {
mPriceWelcomeMessageService.preparePriceMessage();
}
......@@ -494,8 +502,7 @@ public class TabSwitcherCoordinator
mMessageCardProviderCoordinator.getMessageItems();
for (int i = 0; i < messages.size(); i++) {
if (messages.get(i).type == MessageService.MessageType.PRICE_WELCOME) {
mTabListCoordinator.addSpecialListItem(
mTabListCoordinator.getPriceWelcomeMessageIndex(),
mTabListCoordinator.addSpecialListItemToEnd(
TabProperties.UiType.PRICE_WELCOME, messages.get(i).model);
} else {
mTabListCoordinator.addSpecialListItemToEnd(
......@@ -505,6 +512,18 @@ public class TabSwitcherCoordinator
sAppendedMessagesForTesting = messages.size() > 0;
}
// PriceWelcomeMessageController implementation.
@Override
public void removePriceWelcomeMessage() {
mTabListCoordinator.removeSpecialListItem(
TabProperties.UiType.PRICE_WELCOME, MessageService.MessageType.PRICE_WELCOME);
}
@Override
public void restorePriceWelcomeMessage() {
appendNextMessage(MessageService.MessageType.PRICE_WELCOME);
}
private void appendMessagesTo(int index) {
if (mMultiWindowModeStateDispatcher.isInMultiWindowMode()) return;
sAppendedMessagesForTesting = false;
......@@ -513,8 +532,7 @@ public class TabSwitcherCoordinator
for (int i = 0; i < messages.size(); i++) {
if (messages.get(i).type == MessageService.MessageType.PRICE_WELCOME) {
mTabListCoordinator.addSpecialListItem(
mTabListCoordinator.getPriceWelcomeMessageIndex(),
TabProperties.UiType.PRICE_WELCOME, messages.get(i).model);
index + i, TabProperties.UiType.PRICE_WELCOME, messages.get(i).model);
} else {
mTabListCoordinator.addSpecialListItem(
index + i, TabProperties.UiType.MESSAGE, messages.get(i).model);
......@@ -529,8 +547,13 @@ public class TabSwitcherCoordinator
MessageCardProviderMediator.Message nextMessage =
mMessageCardProviderCoordinator.getNextMessageItemForType(messageType);
if (nextMessage == null) return;
mTabListCoordinator.addSpecialListItemToEnd(
TabProperties.UiType.MESSAGE, nextMessage.model);
if (messageType == MessageService.MessageType.PRICE_WELCOME) {
mTabListCoordinator.addSpecialListItemToEnd(
TabProperties.UiType.PRICE_WELCOME, nextMessage.model);
} else {
mTabListCoordinator.addSpecialListItemToEnd(
TabProperties.UiType.MESSAGE, nextMessage.model);
}
}
private View getTabGridDialogAnimationSourceView(int tabId) {
......
......@@ -110,6 +110,7 @@ class TabSwitcherMediator
private TabSelectionEditorCoordinator
.TabSelectionEditorController mTabSelectionEditorController;
private TabSwitcher.OnTabSelectingListener mOnTabSelectingListener;
private PriceWelcomeMessageService mPriceWelcomeMessageService;
/**
* In cases where a didSelectTab was due to switching models with a toggle,
......@@ -189,6 +190,23 @@ class TabSwitcherMediator
void restoreAllAppendedMessage();
}
/**
* An interface to control price welcome message in grid tab switcher.
*/
interface PriceWelcomeMessageController {
/**
* Remove the price welcome message item in the model list. Right now this is used when
* its binding tab is closed in the grid tab switcher.
*/
void removePriceWelcomeMessage();
/**
* Restore the price welcome message item that should show. Right now this is only used
* when the closure of the binding tab in tab switcher is undone.
*/
void restorePriceWelcomeMessage();
}
/**
* Basic constructor for the Mediator.
* @param context The context to use for accessing {@link android.content.res.Resources}.
......@@ -207,6 +225,7 @@ class TabSwitcherMediator
PropertyModel containerViewModel, TabModelSelector tabModelSelector,
BrowserControlsStateProvider browserControlsStateProvider, ViewGroup containerView,
TabContentManager tabContentManager, MessageItemsController messageItemsController,
PriceWelcomeMessageController priceWelcomeMessageController,
MultiWindowModeStateDispatcher multiWindowModeStateDispatcher,
@TabListCoordinator.TabListMode int mode) {
mResetHandler = resetHandler;
......@@ -293,6 +312,9 @@ class TabSwitcherMediator
public void willCloseTab(Tab tab, boolean animate) {
if (mTabModelSelector.getCurrentModel().getCount() == 1) {
messageItemsController.removeAllAppendedMessage();
} else if (mPriceWelcomeMessageService != null
&& mPriceWelcomeMessageService.getBindingTabId() == tab.getId()) {
priceWelcomeMessageController.removePriceWelcomeMessage();
}
}
......@@ -300,6 +322,19 @@ class TabSwitcherMediator
public void tabClosureUndone(Tab tab) {
if (mTabModelSelector.getCurrentModel().getCount() == 1) {
messageItemsController.restoreAllAppendedMessage();
} else if (mPriceWelcomeMessageService != null
&& mPriceWelcomeMessageService.getBindingTabId() == tab.getId()) {
priceWelcomeMessageController.restorePriceWelcomeMessage();
}
}
@Override
public void tabClosureCommitted(Tab tab) {
// TODO(crbug.com/1157578): Auto update the PriceWelcomeMessageService instead of
// updating it based on the client caller.
if (mPriceWelcomeMessageService != null
&& mPriceWelcomeMessageService.getBindingTabId() == tab.getId()) {
mPriceWelcomeMessageService.invalidateMessage();
}
}
};
......@@ -755,6 +790,10 @@ class TabSwitcherMediator
mOnTabSelectingListener = listener;
}
void setPriceWelcomeMessageService(PriceWelcomeMessageService priceWelcomeMessageService) {
mPriceWelcomeMessageService = priceWelcomeMessageService;
}
// GridCardOnClickListenerProvider implementation.
@Override
@Nullable
......
......@@ -126,6 +126,8 @@ public class TabSwitcherMediatorUnitTest {
@Mock
TabSwitcherMediator.MessageItemsController mMessageItemsController;
@Mock
TabSwitcherMediator.PriceWelcomeMessageController mPriceWelcomeMessageController;
@Mock
MultiWindowModeStateDispatcher mMultiWindowModeStateDispatcher;
@Captor
......@@ -201,7 +203,8 @@ public class TabSwitcherMediatorUnitTest {
mModel.addObserver(mPropertyObserver);
mMediator = new TabSwitcherMediator(mContext, mResetHandler, mModel, mTabModelSelector,
mBrowserControlsStateProvider, mCompositorViewHolder, null, mMessageItemsController,
mMultiWindowModeStateDispatcher, TabListCoordinator.TabListMode.GRID);
mPriceWelcomeMessageController, mMultiWindowModeStateDispatcher,
TabListCoordinator.TabListMode.GRID);
mMediator.initWithNative(null);
mMediator.addOverviewModeObserver(mOverviewModeObserver);
mMediator.setOnTabSelectingListener(mLayout::onTabSelecting);
......@@ -792,13 +795,15 @@ public class TabSwitcherMediatorUnitTest {
assertEquals(0, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
new TabSwitcherMediator(mContext, mResetHandler, mModel, mTabModelSelector,
mBrowserControlsStateProvider, mCompositorViewHolder, null, mMessageItemsController,
mMultiWindowModeStateDispatcher, TabListCoordinator.TabListMode.GRID);
mPriceWelcomeMessageController, mMultiWindowModeStateDispatcher,
TabListCoordinator.TabListMode.GRID);
assertEquals(16, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
mModel.set(TabListContainerProperties.BOTTOM_PADDING, 0);
new TabSwitcherMediator(mContext, mResetHandler, mModel, mTabModelSelector,
mBrowserControlsStateProvider, mCompositorViewHolder, null, mMessageItemsController,
mMultiWindowModeStateDispatcher, TabListCoordinator.TabListMode.STRIP);
mPriceWelcomeMessageController, mMultiWindowModeStateDispatcher,
TabListCoordinator.TabListMode.STRIP);
assertEquals(0, mModel.get(TabListContainerProperties.BOTTOM_PADDING));
}
......
......@@ -537,6 +537,11 @@ public final class ChromePreferenceKeys {
*/
public static final String PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD =
"Chrome.PriceTracking.PriceWelcome";
/**
* Indicates how many times the PriceWelcomeMessageCard has shown in the tab switcher.
*/
public static final String PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT =
"Chrome.PriceTracking.PriceWelcomeShowCount";
/**
* Whether users turn on the feature track prices on tabs.
*/
......@@ -844,6 +849,7 @@ public final class ChromePreferenceKeys {
IMAGE_DESCRIPTIONS_DONT_ASK_AGAIN,
PERSISTENT_OFFLINE_CONTENT_AVAILABILITY_STATUS,
PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD,
PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD_SHOW_COUNT,
PRICE_TRACKING_TRACK_PRICES_ON_TABS,
PROMO_IS_DISMISSED.pattern(),
PROMO_TIMES_SEEN.pattern(),
......
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