TextListItemTest.java revision 3737d1dff953969c27652b49b010ea9902b3da4f
1e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing/*
2e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Copyright 2017 The Android Open Source Project
3e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
4e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Licensed under the Apache License, Version 2.0 (the "License");
5e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * you may not use this file except in compliance with the License.
6e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * You may obtain a copy of the License at
7e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
8e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *      http://www.apache.org/licenses/LICENSE-2.0
9e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing *
10e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * Unless required by applicable law or agreed to in writing, software
11e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * distributed under the License is distributed on an "AS IS" BASIS,
12e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * See the License for the specific language governing permissions and
14e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing * limitations under the License.
15e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing */
16e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
17e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingpackage androidx.car.widget;
18e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
19e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.Espresso.onView;
20e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.action.ViewActions.click;
21e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
22e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.contrib.RecyclerViewActions.scrollToPosition;
23e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static android.support.test.espresso.matcher.ViewMatchers.withId;
24e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
25a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxingimport static org.hamcrest.CoreMatchers.not;
26e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.Matchers.greaterThanOrEqualTo;
273737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport static org.hamcrest.Matchers.lessThan;
28e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.core.Is.is;
29e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.core.IsEqual.equalTo;
30e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.hamcrest.number.IsCloseTo.closeTo;
31fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikasimport static org.junit.Assert.assertFalse;
32e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.junit.Assert.assertThat;
33e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport static org.junit.Assert.assertTrue;
34e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
353737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport android.content.pm.PackageManager;
36e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.graphics.drawable.Drawable;
37e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.InstrumentationRegistry;
38e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.espresso.UiController;
39e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.espresso.ViewAction;
40e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.filters.SmallTest;
41e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.rule.ActivityTestRule;
42e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.support.test.runner.AndroidJUnit4;
43b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chenimport android.support.v7.widget.LinearLayoutManager;
443737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport android.text.InputFilter;
4520e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxingimport android.text.TextUtils;
46e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.view.View;
47e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport android.view.ViewGroup;
48a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxingimport android.widget.RelativeLayout;
49e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
50e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.hamcrest.Matcher;
513737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport org.junit.Assume;
52e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Before;
53e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Rule;
54e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.Test;
55e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport org.junit.runner.RunWith;
56e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
57e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.ArrayList;
58e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.Arrays;
59e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport java.util.List;
603737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport java.util.Locale;
61e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
62e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxingimport androidx.car.test.R;
633737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxingimport androidx.car.utils.CarUxRestrictionsTestUtils;
64e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
65e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing/**
664e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing* Tests the layout configuration in {@link TextListItem}.
67e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing */
68e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing@RunWith(AndroidJUnit4.class)
69e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing@SmallTest
704e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxingpublic class TextListItemTest {
71e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
72e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Rule
73e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public ActivityTestRule<PagedListViewTestActivity> mActivityRule =
74e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            new ActivityTestRule<>(PagedListViewTestActivity.class);
75e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
76e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private PagedListViewTestActivity mActivity;
77e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private PagedListView mPagedListView;
78a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    private ListItemAdapter mAdapter;
79e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
803737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    private boolean isAutoDevice() {
813737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        PackageManager packageManager = mActivityRule.getActivity().getPackageManager();
823737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        return packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
833737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    }
843737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
85e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Before
86e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void setUp() {
873737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        Assume.assumeTrue(isAutoDevice());
883737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
89e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        mActivity = mActivityRule.getActivity();
90e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        mPagedListView = mActivity.findViewById(R.id.paged_list_view);
91e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
92e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
933737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    private void refreshUi() {
943737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        try {
953737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing            mActivityRule.runOnUiThread(() -> {
963737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing                mAdapter.notifyDataSetChanged();
973737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing            });
983737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        } catch (Throwable throwable) {
993737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing            throwable.printStackTrace();
1003737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing            throw new RuntimeException(throwable);
1013737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        }
1023737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        // Wait for paged list view to layout by using espresso to scroll to a position.
1033737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        onView(withId(R.id.recycler_view)).perform(scrollToPosition(0));
1043737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    }
1053737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
1064e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing    private void setupPagedListView(List<TextListItem> items) {
107e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        ListItemProvider provider = new ListItemProvider.ListProvider(
108e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                new ArrayList<>(items));
109e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        try {
110a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing            mAdapter = new ListItemAdapter(mActivity, provider);
111e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            mActivityRule.runOnUiThread(() -> {
112a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing                mPagedListView.setAdapter(mAdapter);
113e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            });
114e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        } catch (Throwable throwable) {
115e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            throwable.printStackTrace();
116e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            throw new RuntimeException(throwable);
117e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
1183737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
1193737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
120e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
121e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
122e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private static void verifyViewIsHidden(View view) {
123e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        if (view instanceof ViewGroup) {
124e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            ViewGroup viewGroup = (ViewGroup) view;
125e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            final int childCount = viewGroup.getChildCount();
126e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            for (int i = 0; i < childCount; i++) {
127e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                verifyViewIsHidden(viewGroup.getChildAt(i));
128e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
129e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        } else {
130e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(view.getVisibility(), is(equalTo(View.GONE)));
131e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
132e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
133e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
1344e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing    private TextListItem.ViewHolder getViewHolderAtPosition(int position) {
1354e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        return (TextListItem.ViewHolder) mPagedListView.getRecyclerView()
136e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .findViewHolderForAdapterPosition(
137e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                position);
138e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
139e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
140e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
141e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testEmptyItemHidesAllViews() {
142172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item = new TextListItem(mActivity);
143e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(Arrays.asList(item));
144b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen        verifyViewIsHidden(mPagedListView.getRecyclerView().getLayoutManager().getChildAt(0));
145e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
146e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
147e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
148e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testPrimaryActionVisible() {
149172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
150172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true);
151172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
152172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
153172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
154172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
155172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1);
156e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
157e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
158e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(0).getPrimaryIcon().getVisibility(),
159e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
160e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(1).getPrimaryIcon().getVisibility(),
161e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
162e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
163e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
164e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
165e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testTextVisible() {
166172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
167172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setTitle("title");
168172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
169172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
170172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setBody("body");
171172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
172172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1);
173e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
174e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
175e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(0).getTitle().getVisibility(),
176e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
177e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(getViewHolderAtPosition(1).getBody().getVisibility(),
178e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
179e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
180e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
181e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
182e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSupplementalActionVisible() {
183172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
184172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
185172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
186172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
187172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setAction("text", true, v -> { /* Do nothing. */ });
188172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
189172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
190172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
191172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setActions("text", true, v -> { /* Do nothing. */ },
192172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing                        "text", true, v -> { /* Do nothing. */ });
193172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
194172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2);
195e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
196e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
1974e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
198e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIcon().getVisibility(), is(equalTo(View.VISIBLE)));
199e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIconDivider().getVisibility(),
200e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.VISIBLE)));
201e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
202e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(1);
203e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
204e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.VISIBLE)));
205e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
206e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(2);
207e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
208e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.VISIBLE)));
209e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2().getVisibility(), is(equalTo(View.VISIBLE)));
210e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2Divider().getVisibility(), is(equalTo(View.VISIBLE)));
211e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
212e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
213e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
21422037e659c30185f51f522e1761236f780334c9dYao, Yuxing    public void testSwitchVisibleAndCheckedState() {
215172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
216172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSwitch(true, true, null);
217172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
218172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
219172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setSwitch(false, true, null);
220172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
221172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1);
22222037e659c30185f51f522e1761236f780334c9dYao, Yuxing        setupPagedListView(items);
22322037e659c30185f51f522e1761236f780334c9dYao, Yuxing
2244e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
22522037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitch().getVisibility(), is(equalTo(View.VISIBLE)));
22622037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitch().isChecked(), is(equalTo(true)));
22722037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitchDivider().getVisibility(), is(equalTo(View.VISIBLE)));
22822037e659c30185f51f522e1761236f780334c9dYao, Yuxing
22922037e659c30185f51f522e1761236f780334c9dYao, Yuxing        viewHolder = getViewHolderAtPosition(1);
23022037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitch().getVisibility(), is(equalTo(View.VISIBLE)));
23122037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitch().isChecked(), is(equalTo(false)));
23222037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitchDivider().getVisibility(), is(equalTo(View.VISIBLE)));
23322037e659c30185f51f522e1761236f780334c9dYao, Yuxing    }
234a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
235a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    @Test
236a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    public void testSetSwitchState() {
237a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
238a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        item0.setSwitch(true, true, null);
239a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
240a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        setupPagedListView(Arrays.asList(item0));
241a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
242a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        item0.setSwitchState(false);
2433737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
2443737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
245a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
246a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
247a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        assertThat(viewHolder.getSwitch().getVisibility(), is(equalTo(View.VISIBLE)));
248a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        assertThat(viewHolder.getSwitch().isChecked(), is(equalTo(false)));
249a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    }
250a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
251a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    @Test
252a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    public void testSetSwitchStateHasNoEffectIfSwitchIsNotEnabled() {
253a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
254a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        setupPagedListView(Arrays.asList(item0));
255a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
256a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        item0.setSwitchState(false);
2573737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
2583737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
259a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing
260a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
261a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing        assertThat(viewHolder.getSwitch().getVisibility(), is(not(equalTo(View.VISIBLE))));
262a92a509e61fef9b8065f4c5aeeb8727f3724202eYao, Yuxing    }
26322037e659c30185f51f522e1761236f780334c9dYao, Yuxing
26422037e659c30185f51f522e1761236f780334c9dYao, Yuxing    @Test
265e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testDividersAreOptional() {
266172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
267172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, false);
268172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
269172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
270172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setAction("text", false, v -> { /* Do nothing. */ });
271172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
272172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
273172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setActions("text", false, v -> { /* Do nothing. */ },
274172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing                "text", false, v -> { /* Do nothing. */ });
275172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
276172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item3 = new TextListItem(mActivity);
277172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item3.setSwitch(true, false, null);
278172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
279172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2, item3);
280e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
281e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
2824e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
283e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIcon().getVisibility(), is(equalTo(View.VISIBLE)));
284e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getSupplementalIconDivider().getVisibility(),
285e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(View.GONE)));
286e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
287e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(1);
288e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
289e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.GONE)));
290e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
291e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        viewHolder = getViewHolderAtPosition(2);
292e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1().getVisibility(), is(equalTo(View.VISIBLE)));
293e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction1Divider().getVisibility(), is(equalTo(View.GONE)));
294e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2().getVisibility(), is(equalTo(View.VISIBLE)));
295e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getAction2Divider().getVisibility(), is(equalTo(View.GONE)));
29622037e659c30185f51f522e1761236f780334c9dYao, Yuxing
29722037e659c30185f51f522e1761236f780334c9dYao, Yuxing        viewHolder = getViewHolderAtPosition(3);
29822037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitch().getVisibility(), is(equalTo(View.VISIBLE)));
29922037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertThat(viewHolder.getSwitchDivider().getVisibility(), is(equalTo(View.GONE)));
300e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
301e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
302e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
303172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing    public void testTextStartMarginMatchesPrimaryActionType() {
304172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
305172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true);
3069b0ebd7c98d4c0d73c101851014ecc5f4b70471aJovana
307172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
308172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
3099b0ebd7c98d4c0d73c101851014ecc5f4b70471aJovana
310172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
311172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setPrimaryActionEmptyIcon();
3129b0ebd7c98d4c0d73c101851014ecc5f4b70471aJovana
313172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item3 = new TextListItem(mActivity);
314172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item3.setPrimaryActionNoIcon();
315172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
316172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2, item3);
317e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        List<Integer> expectedStartMargin = Arrays.asList(R.dimen.car_keyline_4,
318e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_keyline_3, R.dimen.car_keyline_3, R.dimen.car_keyline_1);
319e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
320e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
321e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
3224e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing            TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(i);
323e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
324e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            int expected = InstrumentationRegistry.getContext().getResources()
325e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getDimensionPixelSize(expectedStartMargin.get(i));
326e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getTitle().getLayoutParams())
327e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getMarginStart(), is(equalTo(expected)));
328e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getBody().getLayoutParams())
329e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    .getMarginStart(), is(equalTo(expected)));
330e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
331e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
332e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
333e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
334e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testItemWithOnlyTitleIsSingleLine() {
335172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Only space.
336172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
337172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setTitle(" ");
338172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
339172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Underscore.
340172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
341172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setTitle("______");
342172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
343172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
344172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setTitle("ALL UPPER CASE");
345172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
346172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // String wouldn't fit in one line.
347172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item3 = new TextListItem(mActivity);
348172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item3.setTitle(InstrumentationRegistry.getContext().getResources().getString(
3493737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing                R.string.over_uxr_text_length_limit));
350172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
351172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2, item3);
352e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
353e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
354e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        double singleLineHeight = InstrumentationRegistry.getContext().getResources().getDimension(
355e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_single_line_list_item_height);
356e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
357b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen        LinearLayoutManager layoutManager =
358b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen                (LinearLayoutManager) mPagedListView.getRecyclerView().getLayoutManager();
359e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
360b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen            assertThat((double) layoutManager.findViewByPosition(i).getHeight(),
361e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    is(closeTo(singleLineHeight, 1.0d)));
362e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
363e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
364e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
365e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
366e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testItemWithBodyTextIsAtLeastDoubleLine() {
367172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Only space.
368172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
369172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setBody(" ");
370172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
371172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Underscore.
372172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
373172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setBody("____");
374172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
375172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // String wouldn't fit in one line.
376172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
377172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setBody(InstrumentationRegistry.getContext().getResources().getString(
3783737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing                R.string.over_uxr_text_length_limit));
379172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
380172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2);
381e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
382e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
383e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final int doubleLineHeight =
384e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                (int) InstrumentationRegistry.getContext().getResources().getDimension(
385e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        R.dimen.car_double_line_list_item_height);
386e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
387b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen        LinearLayoutManager layoutManager =
388b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen                (LinearLayoutManager) mPagedListView.getRecyclerView().getLayoutManager();
389e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        for (int i = 0; i < items.size(); i++) {
390b226d4dcc396fe8837876dfa113143702dd23c26Anthony Chen            assertThat(layoutManager.findViewByPosition(i).getHeight(),
391e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                    is(greaterThanOrEqualTo(doubleLineHeight)));
392e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        }
393e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
394e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
395e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
396e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testPrimaryIconDrawable() {
397e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        Drawable drawable = InstrumentationRegistry.getContext().getResources().getDrawable(
398e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                android.R.drawable.sym_def_app_icon, null);
399172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
400172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
401172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(drawable, true);
402172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
403172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
404e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
405e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
406e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(getViewHolderAtPosition(0).getPrimaryIcon().getDrawable().getConstantState()
407e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .equals(drawable.getConstantState()));
408e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
409e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
410e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
411e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testLargePrimaryIconHasNoStartMargin() {
412172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
413172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true);
414172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
415172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
416e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
417e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
4184e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
419e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getPrimaryIcon().getLayoutParams())
420e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .getMarginStart(), is(equalTo(0)));
421e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
422e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
423e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
424e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSmallPrimaryIconStartMargin() {
425172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
426172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
427172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
428172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
429e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
430e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
431e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        int expected = InstrumentationRegistry.getContext().getResources().getDimensionPixelSize(
432e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                R.dimen.car_keyline_1);
433e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
4344e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
435e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(((ViewGroup.MarginLayoutParams) viewHolder.getPrimaryIcon().getLayoutParams())
436e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                .getMarginStart(), is(equalTo(expected)));
437e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
438e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
439e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
4405dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing    public void testSmallPrimaryIconTopMarginRemainsTheSameRegardlessOfTextLength() {
4415dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing        final String longText = InstrumentationRegistry.getContext().getResources().getString(
4423737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing                R.string.over_uxr_text_length_limit);
443172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
444172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Single line item.
445172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
446172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
447172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setTitle("one line text");
448172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
449172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Double line item with one line text.
450172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
451172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
452172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setTitle("one line text");
453172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setBody("one line text");
454172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
455172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Double line item with long text.
456172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item2 = new TextListItem(mActivity);
457172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
458172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setTitle("one line text");
459172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item2.setBody(longText);
460172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
461172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Body text only - long text.
462172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item3 = new TextListItem(mActivity);
463172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item3.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
464172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item3.setBody(longText);
465172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
466172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        // Body text only - one line text.
467172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item4 = new TextListItem(mActivity);
468172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item4.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
469172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item4.setBody("one line text");
470172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
471172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1, item2, item3, item4);
4725dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing        setupPagedListView(items);
4735dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing
4745dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing        for (int i = 1; i < items.size(); i++) {
4755dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing            onView(withId(R.id.recycler_view)).perform(scrollToPosition(i));
4765dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing            // Implementation uses integer division so it may be off by 1 vs centered vertically.
4775dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing            assertThat((double) getViewHolderAtPosition(i - 1).getPrimaryIcon().getTop(),
4785dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing                    is(closeTo(
4795dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing                    (double) getViewHolderAtPosition(i).getPrimaryIcon().getTop(), 1.0d)));
4805dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing        }
4815dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing    }
4825dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing
4835dbc4a83b9c6ea77dd85720a40de7dfc200ee872Yao, Yuxing    @Test
484e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingPrimaryActionIsSeparateFromSupplementalAction() {
485e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false, false};
486172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
487172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
488172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setOnClickListener(v -> clicked[0] = true);
489172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true,
490172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing                v -> clicked[1] = true);
491172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
492172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
493e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
494e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
495e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(actionOnItemAtPosition(0, click()));
496e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
497e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertFalse(clicked[1]);
498e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
499e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
500e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.supplemental_icon)));
501e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[1]);
502e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
503e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
504e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
505e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingSupplementalIcon() {
506e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false};
507172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
508172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
509172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true,
510172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing                v -> clicked[0] = true);
511172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
512172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
513e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
514e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
515e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
516e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.supplemental_icon)));
517e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
518e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
519e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
520e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
521439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    public void testSupplementalIconWithoutClickListenerIsNotClickable() {
522172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
523172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSupplementalIcon(android.R.drawable.sym_def_app_icon, true);
524172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
525172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
526439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        setupPagedListView(items);
527439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing
5284e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
529439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing        assertFalse(viewHolder.getSupplementalIcon().isClickable());
530439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    }
531439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing
532439968fcab76ed121a8c514ae904840cac9b2076Yao, Yuxing    @Test
53322037e659c30185f51f522e1761236f780334c9dYao, Yuxing    public void testCheckingSwitch() {
53422037e659c30185f51f522e1761236f780334c9dYao, Yuxing        final boolean[] clicked = {false, false};
535172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
536172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
537172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setSwitch(false, false, (button, isChecked) -> {
538172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            // Initial value is false.
539172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            assertTrue(isChecked);
540172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            clicked[0] = true;
541172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        });
542172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
543172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
544172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setSwitch(true, false, (button, isChecked) -> {
545172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            // Initial value is true.
546172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            assertFalse(isChecked);
547172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing            clicked[1] = true;
548172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        });
549172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
550172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1);
55122037e659c30185f51f522e1761236f780334c9dYao, Yuxing        setupPagedListView(items);
55222037e659c30185f51f522e1761236f780334c9dYao, Yuxing
55322037e659c30185f51f522e1761236f780334c9dYao, Yuxing        onView(withId(R.id.recycler_view)).perform(
55422037e659c30185f51f522e1761236f780334c9dYao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.switch_widget)));
55522037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertTrue(clicked[0]);
55622037e659c30185f51f522e1761236f780334c9dYao, Yuxing
55722037e659c30185f51f522e1761236f780334c9dYao, Yuxing        onView(withId(R.id.recycler_view)).perform(
55822037e659c30185f51f522e1761236f780334c9dYao, Yuxing                actionOnItemAtPosition(1, clickChildViewWithId(R.id.switch_widget)));
55922037e659c30185f51f522e1761236f780334c9dYao, Yuxing        assertTrue(clicked[1]);
56022037e659c30185f51f522e1761236f780334c9dYao, Yuxing    }
56122037e659c30185f51f522e1761236f780334c9dYao, Yuxing
56222037e659c30185f51f522e1761236f780334c9dYao, Yuxing    @Test
563e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingSupplementalAction() {
564e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false};
565172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
566172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
567172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setAction("action", true, v -> clicked[0] = true);
568172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
569172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
570e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
571e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
572e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
573e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action1)));
574e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
575e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
576e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
577e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
578e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testClickingBothSupplementalActions() {
579e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final boolean[] clicked = {false, false};
580172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
581172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
582172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setActions("action 1", true, v -> clicked[0] = true,
583172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing                        "action 2", true, v -> clicked[1] = true);
584172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
585172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
586e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
587e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
588e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
589e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action1)));
590e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[0]);
591e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertFalse(clicked[1]);
592e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
593e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        onView(withId(R.id.recycler_view)).perform(
594e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                actionOnItemAtPosition(0, clickChildViewWithId(R.id.action2)));
595e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertTrue(clicked[1]);
596e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
597e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
598e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
599172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing    public void testCustomViewBinderBindsLast() {
600e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        final String updatedTitle = "updated title";
601172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
602172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
603172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setTitle("original title");
604172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.addViewBinder((viewHolder) -> viewHolder.getTitle().setText(updatedTitle));
605172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
606172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
607e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
608e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
6094e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
610e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getTitle().getText(), is(equalTo(updatedTitle)));
611e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
612e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
613e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
614e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testCustomViewBinderOnUnusedViewsHasNoEffect() {
615172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
616172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.addViewBinder((viewHolder) -> viewHolder.getBody().setText("text"));
617172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
618172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
619e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
620e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
6214e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
622e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(viewHolder.getBody().getVisibility(), is(equalTo(View.GONE)));
623e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Custom binder interacts with body but has no effect.
624e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Expect card height to remain single line.
625e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat((double) viewHolder.itemView.getHeight(), is(closeTo(
626e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                InstrumentationRegistry.getContext().getResources().getDimension(
627e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                        R.dimen.car_single_line_list_item_height), 1.0d)));
628e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
629e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
630e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    @Test
63120e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    public void testRevertingViewBinder() throws Throwable {
63220e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
63320e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        item0.setBody("one item");
63420e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        item0.addViewBinder(
63520e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing                (viewHolder) -> viewHolder.getBody().setEllipsize(TextUtils.TruncateAt.END),
63620e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing                (viewHolder -> viewHolder.getBody().setEllipsize(null)));
63720e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
63820e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
63920e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        setupPagedListView(items);
64020e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
64120e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
64220e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
64320e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        // Bind view holder to a new item - the customization made by item0 should be reverted.
64420e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
64520e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        item1.setBody("new item");
64620e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        mActivityRule.runOnUiThread(() -> item1.bind(viewHolder));
64720e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
64820e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        assertThat(viewHolder.getBody().getEllipsize(), is(equalTo(null)));
64920e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    }
65020e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
65120e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    @Test
65220e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    public void testRemovingViewBinder() {
65320e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
65420e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        item0.setBody("one item");
65520e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        ListItem.ViewBinder<TextListItem.ViewHolder> binder =
65620e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing                (viewHolder) -> viewHolder.getTitle().setEllipsize(TextUtils.TruncateAt.END);
65720e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        item0.addViewBinder(binder);
65820e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
65920e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        assertTrue(item0.removeViewBinder(binder));
66020e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
66120e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        List<TextListItem> items = Arrays.asList(item0);
66220e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        setupPagedListView(items);
66320e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
66420e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing        assertThat(getViewHolderAtPosition(0).getBody().getEllipsize(), is(equalTo(null)));
66520e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    }
66620e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing
66720e9f85df9325d7dc79750be2527bd8dd1c38fcbYao, Yuxing    @Test
668e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    public void testSettingTitleOrBodyAsPrimaryText() {
669e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // Create 2 items, one with Title as primary (default) and one with Body.
670e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        // The primary text, regardless of view, should have consistent look (as primary).
671172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item0 = new TextListItem(mActivity);
672172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setTitle("title");
673172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item0.setBody("body");
674172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
675172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item1 = new TextListItem(mActivity);
676172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setTitle("title");
677172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item1.setBody("body", true);
678172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
679172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        List<TextListItem> items = Arrays.asList(item0, item1);
680e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        setupPagedListView(items);
681e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
6824e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder titlePrimary = getViewHolderAtPosition(0);
6834e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder bodyPrimary = getViewHolderAtPosition(1);
684e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(titlePrimary.getTitle().getTextSize(),
685e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(bodyPrimary.getBody().getTextSize())));
686e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        assertThat(titlePrimary.getTitle().getTextColors(),
687e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                is(equalTo(bodyPrimary.getBody().getTextColors())));
688e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
689e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
690a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    @Test
691a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    public void testNoCarriedOverLayoutParamsForTextView() throws Throwable {
692172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem singleLine = new TextListItem(mActivity);
693172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        singleLine.setTitle("title");
694172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
695a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        setupPagedListView(Arrays.asList(singleLine));
696a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
697a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        // Manually rebind the view holder of a single line item to a double line item.
698172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem doubleLine = new TextListItem(mActivity);
699172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        doubleLine.setTitle("title");
700172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        doubleLine.setBody("body");
7014e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
702a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        mActivityRule.runOnUiThread(() -> doubleLine.bind(viewHolder));
703a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
704a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams titleLayoutParams =
705a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getTitle().getLayoutParams();
706a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams bodyLayoutParams =
707a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getTitle().getLayoutParams();
708a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(titleLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL), is(equalTo(0)));
709a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(bodyLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL), is(equalTo(0)));
710a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    }
711a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
712a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    @Test
713a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    public void testNoCarriedOverLayoutParamsForPrimaryIcon() throws Throwable {
714172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem smallIcon = new TextListItem(mActivity);
715172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        smallIcon.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, false);
716172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        smallIcon.setBody("body");  // Small icon of items with body text should use top margin.
717a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        setupPagedListView(Arrays.asList(smallIcon));
718a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
719a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        // Manually rebind the view holder.
720172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem largeIcon = new TextListItem(mActivity);
721172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        largeIcon.setPrimaryActionIcon(android.R.drawable.sym_def_app_icon, true);
7224e832ea4269fff1780e0726c16bc37584957ba10Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
723a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        mActivityRule.runOnUiThread(() -> largeIcon.bind(viewHolder));
724a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
725a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        RelativeLayout.LayoutParams iconLayoutParams =
726a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                (RelativeLayout.LayoutParams) viewHolder.getPrimaryIcon().getLayoutParams();
727a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(iconLayoutParams.getRule(RelativeLayout.CENTER_VERTICAL),
728a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing                is(equalTo(RelativeLayout.TRUE)));
729a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing        assertThat(iconLayoutParams.topMargin, is(equalTo(0)));
730a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing    }
731a565726ba2ad8cba4d28e206495dafc1d4eebdd5Yao, Yuxing
732172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing    @Test
733172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing    public void testUpdateItem() throws Throwable {
734172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem item = new TextListItem(mActivity);
735172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        setupPagedListView(Arrays.asList(item));
736172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
737172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        String title = "updated title";
738172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        item.setTitle(title);
739172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
7403737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
741172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
742172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
743172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing        assertThat(viewHolder.getTitle().getText(), is(equalTo(title)));
744172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing    }
745172425512285f6da3c69b9405738df1f064336c1Yao, Yuxing
7463737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    @Test
7473737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    public void testUxRestrictionsChange() throws Throwable {
7483737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        String longText = mActivity.getString(R.string.over_uxr_text_length_limit);
7493737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        TextListItem item = new TextListItem(mActivity);
7503737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        item.setBody(longText);
7513737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7523737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        setupPagedListView(Arrays.asList(item));
7533737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7543737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
7553737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        // Default behavior without UXR is unrestricted.
7563737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        assertThat(viewHolder.getBody().getText(), is(equalTo(longText)));
7573737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7583737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        viewHolder.complyWithUxRestrictions(CarUxRestrictionsTestUtils.getFullyRestricted());
7593737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7603737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
7613737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7623737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        // Verify that the body text length is limited.
7633737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        assertThat(viewHolder.getBody().getText().length(), is(lessThan(longText.length())));
7643737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    }
7653737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7663737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    @Test
7673737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    public void testUxRestrictionsChangesDoNotAlterExistingInputFilters() {
7683737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        InputFilter filter = new InputFilter.AllCaps(Locale.US);
7693737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        String bodyText = "bodytext";
7703737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        TextListItem item = new TextListItem(mActivity);
7713737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        item.setBody(bodyText);
7723737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        item.addViewBinder(vh -> vh.getBody().setFilters(new InputFilter[] {filter}));
7733737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7743737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        setupPagedListView(Arrays.asList(item));
7753737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7763737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        TextListItem.ViewHolder viewHolder = getViewHolderAtPosition(0);
7773737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7783737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        // Toggle UX restrictions between fully restricted and unrestricted should not affect
7793737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        // existing filters.
7803737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        viewHolder.complyWithUxRestrictions(CarUxRestrictionsTestUtils.getFullyRestricted());
7813737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
7823737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        assertTrue(Arrays.asList(viewHolder.getBody().getFilters()).contains(filter));
7833737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
7843737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        viewHolder.complyWithUxRestrictions(CarUxRestrictionsTestUtils.getUnrestricted());
7853737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        refreshUi();
7863737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing        assertTrue(Arrays.asList(viewHolder.getBody().getFilters()).contains(filter));
7873737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing    }
7883737d1dff953969c27652b49b010ea9902b3da4fYao, Yuxing
789e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    private static ViewAction clickChildViewWithId(final int id) {
790e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        return new ViewAction() {
791e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
792e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public Matcher<View> getConstraints() {
793e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                return null;
794e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
795e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
796e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
797e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public String getDescription() {
798e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                return "Click on a child view with specific id.";
799e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
800e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing
801e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            @Override
802e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            public void perform(UiController uiController, View view) {
803e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                View v = view.findViewById(id);
804e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing                v.performClick();
805e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing            }
806e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing        };
807e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing    }
808e048d0d3137fbee6430d3481aaa7269d221a7d45Yao, Yuxing}
809