Commit fea89df3 authored by Ioana Pandele's avatar Ioana Pandele Committed by Commit Bot

[ReEPwdSave] Add support for Keyboard Accessory v1

Clicking the toggle changes the tab icon by replacing all tabs. This
requires the tab to be re-marked as selected after its replacement.

Bug: 1044930
Change-Id: Ife8ef25cf6a7b081fba4dcabd9d81c9fa7dd0f94
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2250111Reviewed-by: default avatarFriedrich [CET] <fhorschig@chromium.org>
Commit-Queue: Ioana Pandele <ioanap@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780798}
parent 57c4e82f
...@@ -50,6 +50,8 @@ class PasswordAccessorySheetViewBinder { ...@@ -50,6 +50,8 @@ class PasswordAccessorySheetViewBinder {
return new PasswordsInfoViewHolder(parent); return new PasswordsInfoViewHolder(parent);
case AccessorySheetDataPiece.Type.FOOTER_COMMAND: case AccessorySheetDataPiece.Type.FOOTER_COMMAND:
return new FooterCommandViewHolder(parent); return new FooterCommandViewHolder(parent);
case AccessorySheetDataPiece.Type.OPTION_TOGGLE:
return AccessorySheetTabViewBinder.create(parent, viewType);
} }
assert false : "Unhandled type of data piece: " + viewType; assert false : "Unhandled type of data piece: " + viewType;
return null; return null;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.keyboard_accessory.tab_layout_component; package org.chromium.chrome.browser.keyboard_accessory.tab_layout_component;
import android.content.Context; import android.content.Context;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.util.AttributeSet; import android.util.AttributeSet;
...@@ -66,6 +67,27 @@ class KeyboardAccessoryTabLayoutView extends TabLayout { ...@@ -66,6 +67,27 @@ class KeyboardAccessoryTabLayoutView extends TabLayout {
addOnTabSelectedListener(tabSelectionCallbacks); addOnTabSelectedListener(tabSelectionCallbacks);
} }
/**
* Applies the previous tabs properties to the replaced tabs, if such properties exist. This
* helps customize the appearance of the active tab if the tabs have been replaced without the
* active tab changing.
* @param colorFilters Icon color filters previously applied to the tabs' icons.
* @param tabDescriptions Content descriptions for the tabs.
*/
void applyColorFiltersAndDescriptions(
ColorFilter[] colorFilters, CharSequence[] tabDescriptions) {
// If tabs were added/removed, the old color filters and tab descriptions might not match
// the new order.
if (colorFilters.length != getTabCount() || tabDescriptions.length != getTabCount()) return;
for (int i = getTabCount() - 1; i >= 0; i--) {
TabLayout.Tab t = getTabAt(i);
if (t == null || t.getIcon() == null) continue;
t.getIcon().setColorFilter(colorFilters[i]);
t.setContentDescription(tabDescriptions[i]);
}
}
/** /**
* Marks only the given tab with the active tab color and resets all others. * Marks only the given tab with the active tab color and resets all others.
* @param activeTab The active tab to change. If null, all tabs are reset. * @param activeTab The active tab to change. If null, all tabs are reset.
......
...@@ -8,6 +8,8 @@ import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_componen ...@@ -8,6 +8,8 @@ import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_componen
import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TABS; import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TABS;
import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS;
import android.graphics.ColorFilter;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import org.chromium.chrome.browser.keyboard_accessory.R; import org.chromium.chrome.browser.keyboard_accessory.R;
...@@ -46,12 +48,33 @@ class KeyboardAccessoryTabLayoutViewBinder ...@@ -46,12 +48,33 @@ class KeyboardAccessoryTabLayoutViewBinder
private void updateAllTabs( private void updateAllTabs(
KeyboardAccessoryTabLayoutView view, ListModel<KeyboardAccessoryData.Tab> model) { KeyboardAccessoryTabLayoutView view, ListModel<KeyboardAccessoryData.Tab> model) {
ColorFilter[] colorFilters = getTabIconsColorFilters(view);
CharSequence[] tabDescriptions = getTabDescriptions(view);
view.removeAllTabs(); view.removeAllTabs();
if (model.size() <= 0) return; if (model.size() <= 0) return;
for (int i = 0; i < model.size(); i++) { for (int i = 0; i < model.size(); i++) {
KeyboardAccessoryData.Tab tab = model.get(i); KeyboardAccessoryData.Tab tab = model.get(i);
view.addTabAt(i, tab.getIcon(), tab.getContentDescription()); view.addTabAt(i, tab.getIcon(), tab.getContentDescription());
} }
view.applyColorFiltersAndDescriptions(colorFilters, tabDescriptions);
}
private ColorFilter[] getTabIconsColorFilters(KeyboardAccessoryTabLayoutView view) {
ColorFilter[] filters = new ColorFilter[view.getTabCount()];
for (int i = view.getTabCount() - 1; i >= 0; i--) {
TabLayout.Tab t = view.getTabAt(i);
filters[i] = t.getIcon().getColorFilter();
}
return filters;
}
private CharSequence[] getTabDescriptions(KeyboardAccessoryTabLayoutView view) {
CharSequence[] descriptions = new String[view.getTabCount()];
for (int i = view.getTabCount() - 1; i >= 0; i--) {
TabLayout.Tab t = view.getTabAt(i);
descriptions[i] = t.getContentDescription();
}
return descriptions;
} }
private void registerTabIconObservers( private void registerTabIconObservers(
......
...@@ -13,6 +13,9 @@ import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_componen ...@@ -13,6 +13,9 @@ import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_componen
import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS; import static org.chromium.chrome.browser.keyboard_accessory.tab_layout_component.KeyboardAccessoryTabLayoutProperties.TAB_SELECTION_CALLBACKS;
import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
...@@ -32,6 +35,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner; ...@@ -32,6 +35,7 @@ import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.ui.modelutil.ListModel; import org.chromium.ui.modelutil.ListModel;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.chromium.ui.test.util.DummyUiActivity; import org.chromium.ui.test.util.DummyUiActivity;
import org.chromium.ui.test.util.DummyUiActivityTestCase; import org.chromium.ui.test.util.DummyUiActivityTestCase;
...@@ -76,7 +80,8 @@ public class KeyboardAccessoryTabLayoutViewTest extends DummyUiActivityTestCase ...@@ -76,7 +80,8 @@ public class KeyboardAccessoryTabLayoutViewTest extends DummyUiActivityTestCase
mView = (KeyboardAccessoryTabLayoutView) ((FrameLayout) getActivity().findViewById( mView = (KeyboardAccessoryTabLayoutView) ((FrameLayout) getActivity().findViewById(
android.R.id.content)) android.R.id.content))
.getChildAt(0); .getChildAt(0);
KeyboardAccessoryTabLayoutCoordinator.createTabViewBinder(mModel, mView); PropertyModelChangeProcessor.create(
mModel, mView, KeyboardAccessoryTabLayoutViewBinder::bind);
}); });
} }
...@@ -120,4 +125,32 @@ public class KeyboardAccessoryTabLayoutViewTest extends DummyUiActivityTestCase ...@@ -120,4 +125,32 @@ public class KeyboardAccessoryTabLayoutViewTest extends DummyUiActivityTestCase
assertThat(getTabDescriptionAt(1), is("SecondTab")); assertThat(getTabDescriptionAt(1), is("SecondTab"));
assertThat(getTabDescriptionAt(2), is("ThirdTab")); assertThat(getTabDescriptionAt(2), is("ThirdTab"));
} }
@Test
@MediumTest
public void testTabSelectedAfterIconChange() {
runOnUiThreadBlocking(() -> {
mModel.get(TABS).set(new KeyboardAccessoryData.Tab[] {
createTestTab("FirstTab"), createTestTab("SecondTab")});
// Call |bind| so that the icon change observers are registered to the newly added tabs.
KeyboardAccessoryTabLayoutViewBinder.bind(mModel, mView, TABS);
mModel.set(ACTIVE_TAB, 0);
});
// Make sure that the tab is selected before changing the icon.
CriteriaHelper.pollUiThread(() -> mView.getTabAt(0).isSelected());
Drawable icon = getActivity().getResources().getDrawable(android.R.drawable.ic_menu_add);
runOnUiThreadBlocking(() -> mModel.get(TABS).get(0).setIcon(icon));
CriteriaHelper.pollUiThread(() -> mView.getTabAt(0).getIcon().equals(icon));
PorterDuffColorFilter expectedColorFilter = new PorterDuffColorFilter(
mView.getTabTextColors().getColorForState(new int[] {android.R.attr.state_selected},
mView.getTabTextColors().getDefaultColor()),
PorterDuff.Mode.SRC_IN);
assertThat(icon.getColorFilter(), is(expectedColorFilter));
}
} }
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