Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ce195e91 authored by Shamali Patwa's avatar Shamali Patwa
Browse files

Propagate the light background flag in RemoteCollectionItemsAdapter

Currently CTS test fails with `android.appwidget.flags.remote_adapter_conversion` flag on.

In the old adapter, it propagated EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND param in intent.
The RemoteCollectionItemsAdapter however doesn't know about it and causes the items to be inflated without the `FLAG_USE_LIGHT_BACKGROUND_LAYOUT` flag (even if the parent container has that flag).

Bug: 369181454
Test: atest FrameworksCoreTests:android.widget.RemoteViewsTest -- --abi arm64-v8a
Flag: EXEMPT testfix
Change-Id: I988dd8427b13003b56e60712e3211920a51add13
parent c6c31d3b
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -40,13 +40,15 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
    private RemoteCollectionItems mItems;
    private InteractionHandler mInteractionHandler;
    private ColorResources mColorResources;
    private boolean mOnLightBackground;

    private SparseIntArray mLayoutIdToViewType;

    RemoteCollectionItemsAdapter(
            @NonNull RemoteCollectionItems items,
            @NonNull InteractionHandler interactionHandler,
            @NonNull ColorResources colorResources) {
            @NonNull ColorResources colorResources,
            boolean onLightBackground) {
        // View type count can never increase after an adapter has been set on a ListView.
        // Additionally, decreasing it could inhibit view recycling if the count were to back and
        // forth between 3-2-3-2 for example. Therefore, the view type count, should be fixed for
@@ -56,6 +58,7 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
        mItems = items;
        mInteractionHandler = interactionHandler;
        mColorResources = colorResources;
        mOnLightBackground = onLightBackground;

        initLayoutIdToViewType();
    }
@@ -68,7 +71,8 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
    void setData(
            @NonNull RemoteCollectionItems items,
            @NonNull InteractionHandler interactionHandler,
            @NonNull ColorResources colorResources) {
            @NonNull ColorResources colorResources,
            boolean onLightBackground) {
        if (mViewTypeCount < items.getViewTypeCount()) {
            throw new IllegalArgumentException(
                    "RemoteCollectionItemsAdapter cannot increase view type count after creation");
@@ -77,6 +81,7 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
        mItems = items;
        mInteractionHandler = interactionHandler;
        mColorResources = colorResources;
        mOnLightBackground = onLightBackground;

        initLayoutIdToViewType();

@@ -184,6 +189,7 @@ class RemoteCollectionItemsAdapter extends BaseAdapter {
                : new AppWidgetHostView.AdapterChildHostView(parent.getContext());
        newView.setInteractionHandler(mInteractionHandler);
        newView.setColorResourcesNoReapply(mColorResources);
        newView.setOnLightBackground(mOnLightBackground);
        newView.updateAppWidget(item);
        return newView;
    }
+10 −4
Original line number Diff line number Diff line
@@ -1248,6 +1248,7 @@ public class RemoteViews implements Parcelable, Filter {

            AdapterView adapterView = (AdapterView) target;
            Adapter adapter = adapterView.getAdapter();
            boolean onLightBackground = hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT);
            // We can reuse the adapter if it's a RemoteCollectionItemsAdapter and the view type
            // count hasn't increased. Note that AbsListView allocates a fixed size array for view
            // recycling in setAdapter, so we must call setAdapter again if the number of view types
@@ -1255,8 +1256,12 @@ public class RemoteViews implements Parcelable, Filter {
            if (adapter instanceof RemoteCollectionItemsAdapter
                    && adapter.getViewTypeCount() >= items.getViewTypeCount()) {
                try {
                    ((RemoteCollectionItemsAdapter) adapter).setData(
                            items, params.handler, params.colorResources);
                    ((RemoteCollectionItemsAdapter) adapter)
                            .setData(
                                    items,
                                    params.handler,
                                    params.colorResources,
                                    onLightBackground);
                } catch (Throwable throwable) {
                    // setData should never failed with the validation in the items builder, but if
                    // it does, catch and rethrow.
@@ -1266,8 +1271,9 @@ public class RemoteViews implements Parcelable, Filter {
            }

            try {
                adapterView.setAdapter(new RemoteCollectionItemsAdapter(items,
                        params.handler, params.colorResources));
                adapterView.setAdapter(
                        new RemoteCollectionItemsAdapter(
                                items, params.handler, params.colorResources, onLightBackground));
            } catch (Throwable throwable) {
                // This could throw if the AdapterView somehow doesn't accept BaseAdapter due to
                // a type error.
+58 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.widget;

import static android.appwidget.flags.Flags.remoteAdapterConversion;

import static com.android.internal.R.id.pending_intent_tag;

import static org.junit.Assert.assertArrayEquals;
@@ -282,7 +284,10 @@ public class RemoteViewsTest {
        widget.addView(view);

        ListView listView = (ListView) view.findViewById(R.id.list);

        if (!remoteAdapterConversion()) {
            listView.onRemoteAdapterConnected();
        }
        assertNotNull(listView.getAdapter());

        top.reapply(mContext, view);
@@ -414,6 +419,58 @@ public class RemoteViewsTest {
        assertNotNull(view.findViewById(R.id.light_background_text));
    }

    @Test
    public void remoteCollectionItemsAdapter_lightBackgroundLayoutFlagSet() {
        AppWidgetHostView widget = new AppWidgetHostView(mContext);
        RemoteViews container = new RemoteViews(mPackage, R.layout.remote_view_host);
        RemoteViews listRemoteViews = new RemoteViews(mPackage, R.layout.remote_views_list);
        RemoteViews item = new RemoteViews(mPackage, R.layout.remote_views_text);
        item.setLightBackgroundLayoutId(R.layout.remote_views_light_background_text);
        listRemoteViews.setRemoteAdapter(
                R.id.list,
                new RemoteViews.RemoteCollectionItems.Builder().addItem(0, item).build());
        container.addView(R.id.container, listRemoteViews);

        widget.setOnLightBackground(true);
        widget.updateAppWidget(container);

        // Populate the list view
        ListView listView = (ListView) widget.findViewById(R.id.list);
        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);

        // Picks the light background layout id for the item
        assertNotNull(listView.getChildAt(0).findViewById(R.id.light_background_text));
        assertNull(listView.getChildAt(0).findViewById(R.id.text));
    }

    @Test
    public void remoteCollectionItemsAdapter_lightBackgroundLayoutFlagNotSet() {
        AppWidgetHostView widget = new AppWidgetHostView(mContext);
        RemoteViews container = new RemoteViews(mPackage, R.layout.remote_view_host);
        RemoteViews listRemoteViews = new RemoteViews(mPackage, R.layout.remote_views_list);
        RemoteViews item = new RemoteViews(mPackage, R.layout.remote_views_text);
        item.setLightBackgroundLayoutId(R.layout.remote_views_light_background_text);
        listRemoteViews.setRemoteAdapter(
                R.id.list,
                new RemoteViews.RemoteCollectionItems.Builder().addItem(0, item).build());
        container.addView(R.id.container, listRemoteViews);

        widget.setOnLightBackground(false);
        widget.updateAppWidget(container);

        // Populate the list view
        ListView listView = (ListView) widget.findViewById(R.id.list);
        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
        listView.measure(measureSpec, measureSpec);
        listView.layout(0, 0, 100, 100);

        // Does not pick the light background layout id for the item
        assertNotNull(listView.getChildAt(0).findViewById(R.id.text));
        assertNull(listView.getChildAt(0).findViewById(R.id.light_background_text));
    }

    private RemoteViews createViewChained(int depth, String... texts) {
        RemoteViews result = new RemoteViews(mPackage, R.layout.remote_view_host);