Commit 95a20c27 authored by zhiyuancai's avatar zhiyuancai Committed by Commit Bot

Update message card color in incognito mode

Bug: 1139194
Change-Id: If4fb560c5be11a613830ab76b2b9908904c882eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2490022Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarLijin Shen <lazzzis@google.com>
Reviewed-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@{#824050}
parent eb4d7806
......@@ -37,7 +37,9 @@ android_resources("java_resources") {
"java/res/drawable/iph_drag_and_drop_animated_drawable.xml",
"java/res/drawable/iph_drag_and_drop_drawable.xml",
"java/res/drawable/message_card_background.xml",
"java/res/drawable/message_card_background_incognito.xml",
"java/res/drawable/message_card_background_with_inset.xml",
"java/res/drawable/message_card_background_with_inset_incognito.xml",
"java/res/drawable/popup_bg_dark.xml",
"java/res/drawable/selected_tab_background.xml",
"java/res/drawable/selected_tab_background_incognito.xml",
......
......@@ -7,6 +7,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/default_bg_color" />
<stroke android:width="1dp" android:color="@color/hairline_stroke_color"/>
<stroke android:width="@dimen/divider_height" android:color="@color/hairline_stroke_color"/>
<corners android:radius="@dimen/tab_list_card_radius" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 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. -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="@color/default_bg_color_dark"/>
<stroke android:width="@dimen/divider_height" android:color="@color/hairline_stroke_color_dark"/>
<corners android:radius="@dimen/tab_list_card_radius" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 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. -->
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/message_card_background_incognito"
android:inset="@dimen/tab_list_selected_inset"/>
......@@ -49,6 +49,7 @@ public class IphMessageCardViewModel {
dismissButtonContextDescription)
.with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, true)
.with(MessageCardViewProperties.IS_ICON_VISIBLE, false)
.with(MessageCardViewProperties.IS_INCOGNITO, false)
.with(CARD_TYPE, MESSAGE)
.with(CARD_ALPHA, 1f)
.build();
......
......@@ -8,6 +8,8 @@ import android.content.Context;
import androidx.annotation.Nullable;
import org.chromium.base.supplier.Supplier;
import java.util.ArrayList;
import java.util.List;
......@@ -21,9 +23,10 @@ public class MessageCardProviderCoordinator {
private final MessageCardProviderMediator mMediator;
private final List<MessageService> mMessageServices = new ArrayList<>();
MessageCardProviderCoordinator(
Context context, MessageCardView.DismissActionProvider uiDismissActionProvider) {
mMediator = new MessageCardProviderMediator(context, uiDismissActionProvider);
MessageCardProviderCoordinator(Context context, Supplier<Boolean> isIncognitoSupplier,
MessageCardView.DismissActionProvider uiDismissActionProvider) {
mMediator = new MessageCardProviderMediator(
context, isIncognitoSupplier, uiDismissActionProvider);
}
/**
......
......@@ -11,6 +11,7 @@ import android.content.Context;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.supplier.Supplier;
import org.chromium.ui.modelutil.PropertyModel;
import java.util.ArrayList;
......@@ -39,15 +40,18 @@ public class MessageCardProviderMediator implements MessageService.MessageObserv
}
private final Context mContext;
private final Supplier<Boolean> mIsIncognitoSupplier;
private Map<Integer, List<Message>> mMessageItems = new LinkedHashMap<>();
private Map<Integer, Message> mShownMessageItems = new LinkedHashMap<>();
private MessageCardView.DismissActionProvider mUiDismissActionProvider;
public MessageCardProviderMediator(
Context context, MessageCardView.DismissActionProvider uiDismissActionProvider) {
public MessageCardProviderMediator(Context context, Supplier<Boolean> isIncognitoSupplier,
MessageCardView.DismissActionProvider uiDismissActionProvider) {
mContext = context;
mIsIncognitoSupplier = isIncognitoSupplier;
mUiDismissActionProvider = uiDismissActionProvider;
}
/**
* @return A list of {@link Message} that can be shown.
*/
......@@ -64,22 +68,28 @@ public class MessageCardProviderMediator implements MessageService.MessageObserv
if (messages.size() == 0) it.remove();
}
for (Message message : mShownMessageItems.values()) {
message.model.set(MessageCardViewProperties.IS_INCOGNITO, mIsIncognitoSupplier.get());
}
return new ArrayList<>(mShownMessageItems.values());
}
Message getNextMessageItemForType(@MessageService.MessageType int messageType) {
if (mShownMessageItems.containsKey(messageType)) return mShownMessageItems.get(messageType);
if (!mShownMessageItems.containsKey(messageType)) {
if (!mMessageItems.containsKey(messageType)) return null;
if (!mMessageItems.containsKey(messageType)) return null;
List<Message> messages = mMessageItems.get(messageType);
List<Message> messages = mMessageItems.get(messageType);
assert messages.size() > 0;
mShownMessageItems.put(messageType, messages.remove(0));
assert messages.size() > 0;
mShownMessageItems.put(messageType, messages.remove(0));
if (messages.size() == 0) mMessageItems.remove(messageType);
if (messages.size() == 0) mMessageItems.remove(messageType);
}
return mShownMessageItems.get(messageType);
Message message = mShownMessageItems.get(messageType);
message.model.set(MessageCardViewProperties.IS_INCOGNITO, mIsIncognitoSupplier.get());
return message;
}
private PropertyModel buildModel(int messageType, MessageService.MessageData data) {
......@@ -94,7 +104,9 @@ public class MessageCardProviderMediator implements MessageService.MessageObserv
return IphMessageCardViewModel.create(mContext, this::invalidateShownMessage,
(IphMessageService.IphMessageData) data);
default:
return new PropertyModel();
return new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
.with(MessageCardViewProperties.IS_INCOGNITO, false)
.build();
}
}
......
......@@ -11,6 +11,7 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.tab_ui.R;
import org.chromium.components.browser_ui.widget.text.TemplatePreservingTextView;
import org.chromium.ui.widget.ButtonCompat;
......@@ -144,4 +145,52 @@ class MessageCardView extends LinearLayout {
params.setMargins(margin, 0, 0, 0);
}
}
/**
* Set background resource.
* @param isIncognito Whether the resource is used for incognito mode.
*/
private void setBackground(boolean isIncognito) {
setBackgroundResource(TabUiColorProvider.getMessageCardBackgroundResourceId(isIncognito));
}
/**
* Set text appearance for description.
* @param isIncognito Whether the text appearance is used for incognito mode.
*/
private void setDescriptionTextAppearance(boolean isIncognito) {
ApiCompatibilityUtils.setTextAppearance(mDescription,
TabUiColorProvider.getMessageCardDescriptionTextAppearance(isIncognito));
}
/**
* Set text appearance for action button.
* @param isIncognito Whether the text appearance is used for incognito mode.
*/
private void setActionButtonTextAppearance(boolean isIncognito) {
ApiCompatibilityUtils.setTextAppearance(mActionButton,
TabUiColorProvider.getMessageCardActionButtonTextAppearance(isIncognito));
}
/**
* Set tint for close button.
* @param isIncognito Whether the tint is used for incognito mode.
*/
private void setCloseButtonTint(boolean isIncognito) {
ApiCompatibilityUtils.setImageTintList(mCloseButton,
TabUiColorProvider.getMessageCardCloseButtonTintList(
mCloseButton.getContext(), isIncognito));
}
/**
* Update Message Card when switching between normal mode and incognito mode.
* @param isIncognito Whether it is in the incognito mode.
*/
void updateMessageCardColor(boolean isIncognito) {
setBackground(isIncognito);
setDescriptionTextAppearance(isIncognito);
setActionButtonTextAppearance(isIncognito);
// TODO(crbug.com/1139194): Set action button ripple color.
setCloseButtonTint(isIncognito);
}
}
......@@ -61,6 +61,8 @@ class MessageCardViewBinder {
itemView.setAlpha(model.get(CARD_ALPHA));
} else if (MessageCardViewProperties.IS_ICON_VISIBLE == propertyKey) {
itemView.setIconVisibility(model.get(MessageCardViewProperties.IS_ICON_VISIBLE));
} else if (MessageCardViewProperties.IS_INCOGNITO == propertyKey) {
itemView.updateMessageCardColor(model.get(MessageCardViewProperties.IS_INCOGNITO));
}
}
}
......@@ -44,10 +44,12 @@ class MessageCardViewProperties {
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyModel.WritableBooleanPropertyKey IS_ICON_VISIBLE =
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyModel.WritableBooleanPropertyKey IS_INCOGNITO =
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {ACTION_TEXT, DESCRIPTION_TEXT,
DESCRIPTION_TEXT_TEMPLATE, MESSAGE_TYPE, ICON_PROVIDER, UI_ACTION_PROVIDER,
UI_DISMISS_ACTION_PROVIDER, MESSAGE_SERVICE_ACTION_PROVIDER,
MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER, DISMISS_BUTTON_CONTENT_DESCRIPTION,
SHOULD_KEEP_AFTER_REVIEW, IS_ICON_VISIBLE, CARD_TYPE, CARD_ALPHA};
SHOULD_KEEP_AFTER_REVIEW, IS_ICON_VISIBLE, CARD_TYPE, CARD_ALPHA, IS_INCOGNITO};
}
......@@ -53,6 +53,7 @@ public class TabSuggestionMessageCardViewModel {
.with(MessageCardViewProperties.DISMISS_BUTTON_CONTENT_DESCRIPTION,
dismissButtonContextDescription)
.with(MessageCardViewProperties.IS_ICON_VISIBLE, true)
.with(MessageCardViewProperties.IS_INCOGNITO, false)
.with(CARD_TYPE, MESSAGE)
.with(CARD_ALPHA, 1f)
.build();
......
......@@ -206,8 +206,8 @@ public class TabSwitcherCoordinator
});
}
mMessageCardProviderCoordinator =
new MessageCardProviderCoordinator(context, (identifier) -> {
mMessageCardProviderCoordinator = new MessageCardProviderCoordinator(
context, tabModelSelector::isIncognitoSelected, (identifier) -> {
mTabListCoordinator.removeSpecialListItem(
TabProperties.UiType.MESSAGE, identifier);
appendNextMessage(identifier);
......
......@@ -180,4 +180,51 @@ public class TabUiColorProvider {
isIncognito ? R.color.hovered_tab_grid_card_background_color_incognito
: R.color.hovered_tab_grid_card_background_color);
}
/**
* Returns the message card background resource id based on the incognito mode.
*
* @param isIncognito Whether the resource is used for incognito mode.
* @return The background resource id for message card view.
*/
public static int getMessageCardBackgroundResourceId(boolean isIncognito) {
return isIncognito ? R.drawable.message_card_background_with_inset_incognito
: R.drawable.message_card_background_with_inset;
}
/**
* Returns the text appearance for the message card description based on the incognito mode.
*
* @param isIncognito Whether the text appearance is used for incognito mode.
* @return The text appearance for the message card description.
*/
public static int getMessageCardDescriptionTextAppearance(boolean isIncognito) {
return isIncognito ? R.style.TextAppearance_TextMedium_Primary_Light
: R.style.TextAppearance_TextMedium_Primary;
}
/**
* Returns the text appearance for the message card action button based on the incognito mode.
*
* @param isIncognito Whether the text appearance is used for incognito mode.
* @return The text appearance for the message card action button.
*/
public static int getMessageCardActionButtonTextAppearance(boolean isIncognito) {
return isIncognito ? R.style.TextAppearance_Button_Text_Blue_Dark
: R.style.TextAppearance_Button_Text_Blue;
}
/**
* Returns the {@link ColorStateList} to use for the message card close button based on
* incognito mode.
*
* @param context {@link Context} used to retrieve color.
* @param isIncognito Whether the color is used for incognito mode.
* @return The {@link ColorStateList} for message card close button.
*/
public static ColorStateList getMessageCardCloseButtonTintList(
Context context, boolean isIncognito) {
return AppCompatResources.getColorStateList(context,
isIncognito ? R.color.default_icon_color_inverse : R.color.default_icon_color);
}
}
......@@ -133,7 +133,8 @@ public class MessageCardProviderTest extends DummyUiActivityTestCase {
view.addView(mRecyclerView);
});
mCoordinator = new MessageCardProviderCoordinator(getActivity(), mUiDismissActionProvider);
mCoordinator = new MessageCardProviderCoordinator(
getActivity(), () -> false, mUiDismissActionProvider);
mCoordinator.subscribeMessageService(mTestingService);
mCoordinator.subscribeMessageService(mSuggestionService);
......
......@@ -4,18 +4,23 @@
package org.chromium.chrome.browser.tasks.tab_management;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.test.filters.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.test.UiThreadTest;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
......@@ -160,6 +165,37 @@ public class MessageCardViewBinderTest extends DummyUiActivityTestCase {
assertEquals(0, params.leftMargin);
}
@Test
@UiThreadTest
@SmallTest
public void testUpdateMessageCardColor() {
TextView description = (TextView) mItemView.findViewById(R.id.description);
TextView actionButton = (TextView) mItemView.findViewById(R.id.action_button);
ImageView closeButton = (ImageView) mItemView.findViewById(R.id.close_button);
mItemViewModel.set(MessageCardViewProperties.IS_INCOGNITO, false);
assertThat(description.getCurrentTextColor(),
equalTo(ApiCompatibilityUtils.getColor(
mItemView.getResources(), R.color.default_text_color_list)));
assertThat(actionButton.getCurrentTextColor(),
equalTo(ApiCompatibilityUtils.getColor(
mItemView.getResources(), R.color.default_text_color_link)));
assertThat(closeButton.getImageTintList(),
equalTo(AppCompatResources.getColorStateList(
getActivity(), R.color.default_icon_color)));
mItemViewModel.set(MessageCardViewProperties.IS_INCOGNITO, true);
assertThat(description.getCurrentTextColor(),
equalTo(ApiCompatibilityUtils.getColor(
mItemView.getResources(), R.color.default_text_color_light_list)));
assertThat(actionButton.getCurrentTextColor(),
equalTo(ApiCompatibilityUtils.getColor(
mItemView.getResources(), R.color.default_text_color_link_light)));
assertThat(closeButton.getImageTintList(),
equalTo(AppCompatResources.getColorStateList(
getActivity(), R.color.default_icon_color_inverse)));
}
@Override
public void tearDownTest() throws Exception {
mItemMCP.destroy();
......
......@@ -19,6 +19,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.tasks.tab_management.suggestions.TabSuggestion;
import org.chromium.chrome.tab_ui.R;
import org.chromium.testing.local.LocalRobolectricTestRunner;
......@@ -45,12 +46,17 @@ public class MessageCardProviderMediatorUnitTest {
@Mock
private TabSuggestionMessageService.TabSuggestionMessageData mTabSuggestionMessageData;
@Mock
private Supplier<Boolean> mIsIncognitoSupplier;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
doReturn(false).when(mIsIncognitoSupplier).get();
doNothing().when(mUiDismissActionProvider).dismiss(anyInt());
mMediator = new MessageCardProviderMediator(mContext, mUiDismissActionProvider);
mMediator = new MessageCardProviderMediator(
mContext, mIsIncognitoSupplier, mUiDismissActionProvider);
}
private void enqueueMessageItem(@MessageService.MessageType int type, int tabSuggestionAction) {
......@@ -287,4 +293,34 @@ public class MessageCardProviderMediatorUnitTest {
Assert.assertEquals(groupingTabSuggestionMessage,
model.get(MessageCardViewProperties.DESCRIPTION_TEXT_TEMPLATE));
}
@Test
public void getMessageItemsTest_UpdateIncognito() {
enqueueMessageItem(
MessageService.MessageType.TAB_SUGGESTION, TabSuggestion.TabSuggestionAction.CLOSE);
PropertyModel messageModel = mMediator.getMessageItems().get(0).model;
Assert.assertFalse(messageModel.get(MessageCardViewProperties.IS_INCOGNITO));
doReturn(true).when(mIsIncognitoSupplier).get();
messageModel = mMediator.getMessageItems().get(0).model;
Assert.assertTrue(messageModel.get(MessageCardViewProperties.IS_INCOGNITO));
}
@Test
public void getNextMessageItemForTypeTest_UpdateIncognito() {
enqueueMessageItem(
MessageService.MessageType.TAB_SUGGESTION, TabSuggestion.TabSuggestionAction.CLOSE);
PropertyModel messageModel =
mMediator.getNextMessageItemForType(MessageService.MessageType.TAB_SUGGESTION)
.model;
Assert.assertFalse(messageModel.get(MessageCardViewProperties.IS_INCOGNITO));
doReturn(true).when(mIsIncognitoSupplier).get();
messageModel =
mMediator.getNextMessageItemForType(MessageService.MessageType.TAB_SUGGESTION)
.model;
Assert.assertTrue(messageModel.get(MessageCardViewProperties.IS_INCOGNITO));
}
}
......@@ -128,6 +128,7 @@ java_strings_grd("ui_strings_grd") {
android_resources("ui_java_resources") {
sources = [
"java/res/color/blue_when_enabled.xml",
"java/res/color/blue_when_enabled_dark.xml",
"java/res/color/chip_background_color.xml",
"java/res/color/chip_ripple_color.xml",
"java/res/color/chip_stroke_color.xml",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/default_text_color_link_disabled_light" android:state_enabled="false" />
<item android:color="@color/default_text_color_link_light"/>
</selector>
......@@ -317,6 +317,10 @@
tools:ignore="UnusedResources">
<item name="android:textColor">@color/blue_when_enabled</item>
</style>
<style name="TextAppearance.Button.Text.Blue.Dark" parent="TextAppearance.TextAccentMediumThick"
tools:ignore="UnusedResources">
<item name="android:textColor">@color/blue_when_enabled_dark</item>
</style>
<style name="TextAppearance.Button.Text.Filled" parent="TextAppearance.TextAccentMediumThick">
<item name="android:textColor">@color/default_text_color_inverse</item>
</style>
......
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