diff options
Diffstat (limited to 'java/src')
5 files changed, 391 insertions, 265 deletions
| diff --git a/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java index 8b0b10b0..17dbb8f2 100644 --- a/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/AbstractMultiProfilePagerAdapter.java @@ -16,8 +16,8 @@  package com.android.intentresolver;  import android.annotation.IntDef; -import android.annotation.Nullable;  import android.annotation.NonNull; +import android.annotation.Nullable;  import android.annotation.UserIdInt;  import android.app.AppGlobals;  import android.content.ContentResolver; @@ -173,6 +173,10 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {       */      abstract ProfileDescriptor getItem(int pageIndex); +    protected ViewGroup getEmptyStateView(int pageIndex) { +        return getItem(pageIndex).getEmptyStateView(); +    } +      /**       * Returns the number of {@link ProfileDescriptor} objects.       * <p>For a normal consumer device with only one user returns <code>1</code>. @@ -432,7 +436,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {                      && isQuietModeEnabled(mWorkProfileUserHandle));      } -    protected class ProfileDescriptor { +    protected static class ProfileDescriptor {          final ViewGroup rootView;          private final ViewGroup mEmptyStateView;          ProfileDescriptor(ViewGroup rootView) { diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java index 4682ec50..295d5b70 100644 --- a/java/src/com/android/intentresolver/ChooserActivity.java +++ b/java/src/com/android/intentresolver/ChooserActivity.java @@ -1923,7 +1923,7 @@ public class ChooserActivity extends ResolverActivity implements      private ViewGroup getActiveEmptyStateView() {          int currentPage = mChooserMultiProfilePagerAdapter.getCurrentPage(); -        return mChooserMultiProfilePagerAdapter.getItem(currentPage).getEmptyStateView(); +        return mChooserMultiProfilePagerAdapter.getEmptyStateView(currentPage);      }      @Override // ResolverListCommunicator diff --git a/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java index 93daa299..39d1fab0 100644 --- a/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/ChooserMultiProfilePagerAdapter.java @@ -16,11 +16,9 @@  package com.android.intentresolver; -import android.annotation.Nullable;  import android.content.Context;  import android.os.UserHandle;  import android.view.LayoutInflater; -import android.view.View;  import android.view.ViewGroup;  import androidx.recyclerview.widget.GridLayoutManager; @@ -30,16 +28,21 @@ import androidx.viewpager.widget.PagerAdapter;  import com.android.intentresolver.grid.ChooserGridAdapter;  import com.android.internal.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; + +import java.util.Optional; +import java.util.function.Supplier; +  /**   * A {@link PagerAdapter} which describes the work and personal profile share sheet screens.   */  @VisibleForTesting -public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAdapter { +public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAdapter< +        RecyclerView, ChooserGridAdapter, ChooserListAdapter> {      private static final int SINGLE_CELL_SPAN_SIZE = 1; -    private final ChooserProfileDescriptor[] mItems; -    private int mBottomOffset; -    private int mMaxTargetsPerRow; +    private final ChooserProfileAdapterBinder mAdapterBinder; +    private final BottomPaddingOverrideSupplier mBottomPaddingOverrideSupplier;      ChooserMultiProfilePagerAdapter(              Context context, @@ -48,12 +51,15 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd              QuietModeManager quietModeManager,              UserHandle workProfileUserHandle,              int maxTargetsPerRow) { -        super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, -                workProfileUserHandle); -        mItems = new ChooserProfileDescriptor[] { -                createProfileDescriptor(adapter) -        }; -        mMaxTargetsPerRow = maxTargetsPerRow; +        this( +                context, +                new ChooserProfileAdapterBinder(maxTargetsPerRow), +                ImmutableList.of(adapter), +                emptyStateProvider, +                quietModeManager, +                /* defaultProfile= */ 0, +                workProfileUserHandle, +                new BottomPaddingOverrideSupplier(context));      }      ChooserMultiProfilePagerAdapter( @@ -65,143 +71,104 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd              @Profile int defaultProfile,              UserHandle workProfileUserHandle,              int maxTargetsPerRow) { -        super(context, /* currentPage */ defaultProfile, emptyStateProvider, -                quietModeManager, workProfileUserHandle); -        mItems = new ChooserProfileDescriptor[] { -                createProfileDescriptor(personalAdapter), -                createProfileDescriptor(workAdapter) -        }; -        mMaxTargetsPerRow = maxTargetsPerRow; -    } - -    private ChooserProfileDescriptor createProfileDescriptor(ChooserGridAdapter adapter) { -        final LayoutInflater inflater = LayoutInflater.from(getContext()); -        final ViewGroup rootView = -                (ViewGroup) inflater.inflate(R.layout.chooser_list_per_profile, null, false); -        ChooserProfileDescriptor profileDescriptor = -                new ChooserProfileDescriptor(rootView, adapter); -        profileDescriptor.recyclerView.setAccessibilityDelegateCompat( -                new ChooserRecyclerViewAccessibilityDelegate(profileDescriptor.recyclerView)); -        return profileDescriptor; +        this( +                context, +                new ChooserProfileAdapterBinder(maxTargetsPerRow), +                ImmutableList.of(personalAdapter, workAdapter), +                emptyStateProvider, +                quietModeManager, +                defaultProfile, +                workProfileUserHandle, +                new BottomPaddingOverrideSupplier(context)); +    } + +    private ChooserMultiProfilePagerAdapter( +            Context context, +            ChooserProfileAdapterBinder adapterBinder, +            ImmutableList<ChooserGridAdapter> gridAdapters, +            EmptyStateProvider emptyStateProvider, +            QuietModeManager quietModeManager, +            @Profile int defaultProfile, +            UserHandle workProfileUserHandle, +            BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier) { +        super( +                context, +                        gridAdapter -> gridAdapter.getListAdapter(), +                adapterBinder, +                gridAdapters, +                emptyStateProvider, +                quietModeManager, +                defaultProfile, +                workProfileUserHandle, +                        () -> makeProfileView(context), +                bottomPaddingOverrideSupplier); +        mAdapterBinder = adapterBinder; +        mBottomPaddingOverrideSupplier = bottomPaddingOverrideSupplier;      }      public void setMaxTargetsPerRow(int maxTargetsPerRow) { -        mMaxTargetsPerRow = maxTargetsPerRow; -    } - -    RecyclerView getListViewForIndex(int index) { -        return getItem(index).recyclerView; +        mAdapterBinder.setMaxTargetsPerRow(maxTargetsPerRow);      } -    @Override -    ChooserProfileDescriptor getItem(int pageIndex) { -        return mItems[pageIndex]; +    public void setEmptyStateBottomOffset(int bottomOffset) { +        mBottomPaddingOverrideSupplier.setEmptyStateBottomOffset(bottomOffset);      } -    @Override -    int getItemCount() { -        return mItems.length; +    private static ViewGroup makeProfileView(Context context) { +        LayoutInflater inflater = LayoutInflater.from(context); +        ViewGroup rootView = (ViewGroup) inflater.inflate( +                R.layout.chooser_list_per_profile, null, false); +        RecyclerView recyclerView = rootView.findViewById(com.android.internal.R.id.resolver_list); +        recyclerView.setAccessibilityDelegateCompat( +                new ChooserRecyclerViewAccessibilityDelegate(recyclerView)); +        return rootView;      } -    @Override -    @VisibleForTesting -    public ChooserGridAdapter getAdapterForIndex(int pageIndex) { -        return mItems[pageIndex].chooserGridAdapter; -    } +    private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> { +        private final Context mContext; +        private int mBottomOffset; -    @Override -    @Nullable -    ChooserListAdapter getListAdapterForUserHandle(UserHandle userHandle) { -        if (getActiveListAdapter().getUserHandle().equals(userHandle)) { -            return getActiveListAdapter(); -        } else if (getInactiveListAdapter() != null -                && getInactiveListAdapter().getUserHandle().equals(userHandle)) { -            return getInactiveListAdapter(); +        BottomPaddingOverrideSupplier(Context context) { +            mContext = context;          } -        return null; -    } - -    @Override -    void setupListAdapter(int pageIndex) { -        final RecyclerView recyclerView = getItem(pageIndex).recyclerView; -        ChooserGridAdapter chooserGridAdapter = getItem(pageIndex).chooserGridAdapter; -        GridLayoutManager glm = (GridLayoutManager) recyclerView.getLayoutManager(); -        glm.setSpanCount(mMaxTargetsPerRow); -        glm.setSpanSizeLookup( -                new GridLayoutManager.SpanSizeLookup() { -                    @Override -                    public int getSpanSize(int position) { -                        return chooserGridAdapter.shouldCellSpan(position) -                                ? SINGLE_CELL_SPAN_SIZE -                                : glm.getSpanCount(); -                    } -                }); -    } -    @Override -    @VisibleForTesting -    public ChooserListAdapter getActiveListAdapter() { -        return getAdapterForIndex(getCurrentPage()).getListAdapter(); -    } - -    @Override -    @VisibleForTesting -    public ChooserListAdapter getInactiveListAdapter() { -        if (getCount() == 1) { -            return null; +        public void setEmptyStateBottomOffset(int bottomOffset) { +            mBottomOffset = bottomOffset;          } -        return getAdapterForIndex(1 - getCurrentPage()).getListAdapter(); -    } - -    @Override -    public ResolverListAdapter getPersonalListAdapter() { -        return getAdapterForIndex(PROFILE_PERSONAL).getListAdapter(); -    } - -    @Override -    @Nullable -    public ResolverListAdapter getWorkListAdapter() { -        return getAdapterForIndex(PROFILE_WORK).getListAdapter(); -    } -    @Override -    ChooserGridAdapter getCurrentRootAdapter() { -        return getAdapterForIndex(getCurrentPage()); +        public Optional<Integer> get() { +            int initialBottomPadding = mContext.getResources().getDimensionPixelSize( +                    R.dimen.resolver_empty_state_container_padding_bottom); +            return Optional.of(initialBottomPadding + mBottomOffset); +        }      } -    @Override -    RecyclerView getActiveAdapterView() { -        return getListViewForIndex(getCurrentPage()); -    } +    private static class ChooserProfileAdapterBinder implements +            AdapterBinder<RecyclerView, ChooserGridAdapter> { +        private int mMaxTargetsPerRow; -    @Override -    @Nullable -    RecyclerView getInactiveAdapterView() { -        if (getCount() == 1) { -            return null; +        ChooserProfileAdapterBinder(int maxTargetsPerRow) { +            mMaxTargetsPerRow = maxTargetsPerRow;          } -        return getListViewForIndex(1 - getCurrentPage()); -    } -    void setEmptyStateBottomOffset(int bottomOffset) { -        mBottomOffset = bottomOffset; -    } - -    @Override -    protected void setupContainerPadding(View container) { -        int initialBottomPadding = getContext().getResources().getDimensionPixelSize( -                R.dimen.resolver_empty_state_container_padding_bottom); -        container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), -                container.getPaddingRight(), initialBottomPadding + mBottomOffset); -    } +        public void setMaxTargetsPerRow(int maxTargetsPerRow) { +            mMaxTargetsPerRow = maxTargetsPerRow; +        } -    class ChooserProfileDescriptor extends ProfileDescriptor { -        private ChooserGridAdapter chooserGridAdapter; -        private RecyclerView recyclerView; -        ChooserProfileDescriptor(ViewGroup rootView, ChooserGridAdapter adapter) { -            super(rootView); -            chooserGridAdapter = adapter; -            recyclerView = rootView.findViewById(com.android.internal.R.id.resolver_list); +        @Override +        public void bind( +                RecyclerView recyclerView, ChooserGridAdapter chooserGridAdapter) { +            GridLayoutManager glm = (GridLayoutManager) recyclerView.getLayoutManager(); +            glm.setSpanCount(mMaxTargetsPerRow); +            glm.setSpanSizeLookup( +                    new GridLayoutManager.SpanSizeLookup() { +                        @Override +                        public int getSpanSize(int position) { +                            return chooserGridAdapter.shouldCellSpan(position) +                                    ? SINGLE_CELL_SPAN_SIZE +                                    : glm.getSpanCount(); +                        } +                    });          }      }  } diff --git a/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java new file mode 100644 index 00000000..9bbdf7c7 --- /dev/null +++ b/java/src/com/android/intentresolver/GenericMultiProfilePagerAdapter.java @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.intentresolver; + +import android.annotation.Nullable; +import android.content.Context; +import android.os.UserHandle; +import android.view.View; +import android.view.ViewGroup; + +import com.android.internal.annotations.VisibleForTesting; + +import com.google.common.collect.ImmutableList; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * Implementation of {@link AbstractMultiProfilePagerAdapter} that consolidates the variation in + * existing implementations; most overrides were only to vary type signatures (which are better + * represented via generic types), and a few minor behavioral customizations are now implemented + * through small injectable delegate classes. + * TODO: now that the existing implementations are shown to be expressible in terms of this new + * generic type, merge up into the base class and simplify the public APIs. + * TODO: attempt to further restrict visibility in the methods we expose. + * TODO: deprecate and audit/fix usages of any methods that refer to the "active" or "inactive" + * adapters; these were marked {@link VisibleForTesting} and their usage seems like an accident + * waiting to happen since clients seem to make assumptions about which adapter will be "active" in + * a particular context, and more explicit APIs would make sure those were valid. + * TODO: consider renaming legacy methods (e.g. why do we know it's a "list", not just a "page"?) + * + * @param <PageViewT> the type of the widget that represents the contents of a page in this adapter + * @param <SinglePageAdapterT> the type of a "root" adapter class to be instantiated and included in + * the per-profile records. + * @param <ListAdapterT> the concrete type of a {@link ResolverListAdapter} implementation to + * control the contents of a given per-profile list. This is provided for convenience, since it must + * be possible to get the list adapter from the page adapter via our {@link mListAdapterExtractor}. + * + * TODO: this class doesn't make any explicit usage of the {@link ResolverListAdapter} API, so the + * type constraint can probably be dropped once the API is merged upwards and cleaned. + */ +class GenericMultiProfilePagerAdapter< +        PageViewT extends ViewGroup, +        SinglePageAdapterT, +        ListAdapterT extends ResolverListAdapter> extends AbstractMultiProfilePagerAdapter { + +    /** Delegate to set up a given adapter and page view to be used together. */ +    public interface AdapterBinder<PageViewT, SinglePageAdapterT> { +        /** +         * The given {@code view} will be associated with the given {@code adapter}. Do any work +         * necessary to configure them compatibly, introduce them to each other, etc. +         */ +        void bind(PageViewT view, SinglePageAdapterT adapter); +    } + +    private final Function<SinglePageAdapterT, ListAdapterT> mListAdapterExtractor; +    private final AdapterBinder<PageViewT, SinglePageAdapterT> mAdapterBinder; +    private final Supplier<ViewGroup> mPageViewInflater; +    private final Supplier<Optional<Integer>> mContainerBottomPaddingOverrideSupplier; + +    private final ImmutableList<GenericProfileDescriptor<PageViewT, SinglePageAdapterT>> mItems; + +    GenericMultiProfilePagerAdapter( +            Context context, +            Function<SinglePageAdapterT, ListAdapterT> listAdapterExtractor, +            AdapterBinder<PageViewT, SinglePageAdapterT> adapterBinder, +            ImmutableList<SinglePageAdapterT> adapters, +            EmptyStateProvider emptyStateProvider, +            QuietModeManager quietModeManager, +            @Profile int defaultProfile, +            UserHandle workProfileUserHandle, +            Supplier<ViewGroup> pageViewInflater, +            Supplier<Optional<Integer>> containerBottomPaddingOverrideSupplier) { +        super( +                context, +                /* currentPage= */ defaultProfile, +                emptyStateProvider, +                quietModeManager, +                workProfileUserHandle); + +        mListAdapterExtractor = listAdapterExtractor; +        mAdapterBinder = adapterBinder; +        mPageViewInflater = pageViewInflater; +        mContainerBottomPaddingOverrideSupplier = containerBottomPaddingOverrideSupplier; + +        ImmutableList.Builder<GenericProfileDescriptor<PageViewT, SinglePageAdapterT>> items = +                new ImmutableList.Builder<>(); +        for (SinglePageAdapterT adapter : adapters) { +            items.add(createProfileDescriptor(adapter)); +        } +        mItems = items.build(); +    } + +    private GenericProfileDescriptor<PageViewT, SinglePageAdapterT> +            createProfileDescriptor(SinglePageAdapterT adapter) { +        return new GenericProfileDescriptor<>(mPageViewInflater.get(), adapter); +    } + +    @Override +    protected GenericProfileDescriptor<PageViewT, SinglePageAdapterT> getItem(int pageIndex) { +        return mItems.get(pageIndex); +    } + +    @Override +    public int getItemCount() { +        return mItems.size(); +    } + +    public PageViewT getListViewForIndex(int index) { +        return getItem(index).mView; +    } + +    @Override +    @VisibleForTesting +    public SinglePageAdapterT getAdapterForIndex(int index) { +        return getItem(index).mAdapter; +    } + +    @Override +    protected void setupListAdapter(int pageIndex) { +        mAdapterBinder.bind(getListViewForIndex(pageIndex), getAdapterForIndex(pageIndex)); +    } + +    @Override +    public ViewGroup instantiateItem(ViewGroup container, int position) { +        setupListAdapter(position); +        return super.instantiateItem(container, position); +    } + +    @Override +    @Nullable +    protected ListAdapterT getListAdapterForUserHandle(UserHandle userHandle) { +        if (getActiveListAdapter().getUserHandle().equals(userHandle)) { +            return getActiveListAdapter(); +        } +        if ((getInactiveListAdapter() != null) && getInactiveListAdapter().getUserHandle().equals( +                userHandle)) { +            return getInactiveListAdapter(); +        } +        return null; +    } + +    @Override +    @VisibleForTesting +    public ListAdapterT getActiveListAdapter() { +        return mListAdapterExtractor.apply(getAdapterForIndex(getCurrentPage())); +    } + +    @Override +    @VisibleForTesting +    public ListAdapterT getInactiveListAdapter() { +        if (getCount() < 2) { +            return null; +        } +        return mListAdapterExtractor.apply(getAdapterForIndex(1 - getCurrentPage())); +    } + +    @Override +    public ListAdapterT getPersonalListAdapter() { +        return mListAdapterExtractor.apply(getAdapterForIndex(PROFILE_PERSONAL)); +    } + +    @Override +    public ListAdapterT getWorkListAdapter() { +        return mListAdapterExtractor.apply(getAdapterForIndex(PROFILE_WORK)); +    } + +    @Override +    protected SinglePageAdapterT getCurrentRootAdapter() { +        return getAdapterForIndex(getCurrentPage()); +    } + +    @Override +    protected PageViewT getActiveAdapterView() { +        return getListViewForIndex(getCurrentPage()); +    } + +    @Override +    protected PageViewT getInactiveAdapterView() { +        if (getCount() < 2) { +            return null; +        } +        return getListViewForIndex(1 - getCurrentPage()); +    } + +    @Override +    protected void setupContainerPadding(View container) { +        Optional<Integer> bottomPaddingOverride = mContainerBottomPaddingOverrideSupplier.get(); +        bottomPaddingOverride.ifPresent(paddingBottom -> +                container.setPadding( +                    container.getPaddingLeft(), +                    container.getPaddingTop(), +                    container.getPaddingRight(), +                    paddingBottom)); +    } + +    // TODO: `ChooserActivity` also has a per-profile record type. Maybe the "multi-profile pager" +    // should be the owner of all per-profile data (especially now that the API is generic)? +    private static class GenericProfileDescriptor<PageViewT, SinglePageAdapterT> extends +            ProfileDescriptor { +        private final SinglePageAdapterT mAdapter; +        private final PageViewT mView; + +        GenericProfileDescriptor(ViewGroup rootView, SinglePageAdapterT adapter) { +            super(rootView); +            mAdapter = adapter; +            mView = (PageViewT) rootView.findViewById(com.android.internal.R.id.resolver_list); +        } +    } +} diff --git a/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java index 8cf65529..65de9409 100644 --- a/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/ResolverMultiProfilePagerAdapter.java @@ -16,11 +16,9 @@  package com.android.intentresolver; -import android.annotation.Nullable;  import android.content.Context;  import android.os.UserHandle;  import android.view.LayoutInflater; -import android.view.View;  import android.view.ViewGroup;  import android.widget.ListView; @@ -28,25 +26,33 @@ import androidx.viewpager.widget.PagerAdapter;  import com.android.internal.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; + +import java.util.Optional; +import java.util.function.Supplier; +  /**   * A {@link PagerAdapter} which describes the work and personal profile intent resolver screens.   */  @VisibleForTesting -public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerAdapter { - -    private final ResolverProfileDescriptor[] mItems; -    private boolean mUseLayoutWithDefault; +public class ResolverMultiProfilePagerAdapter extends +        GenericMultiProfilePagerAdapter<ListView, ResolverListAdapter, ResolverListAdapter> { +    private final BottomPaddingOverrideSupplier mBottomPaddingOverrideSupplier; -    ResolverMultiProfilePagerAdapter(Context context, +    ResolverMultiProfilePagerAdapter( +            Context context,              ResolverListAdapter adapter,              EmptyStateProvider emptyStateProvider,              QuietModeManager quietModeManager,              UserHandle workProfileUserHandle) { -        super(context, /* currentPage */ 0, emptyStateProvider, quietModeManager, -                workProfileUserHandle); -        mItems = new ResolverProfileDescriptor[] { -                createProfileDescriptor(adapter) -        }; +        this( +                context, +                ImmutableList.of(adapter), +                emptyStateProvider, +                quietModeManager, +                /* defaultProfile= */ 0, +                workProfileUserHandle, +                new BottomPaddingOverrideSupplier());      }      ResolverMultiProfilePagerAdapter(Context context, @@ -56,129 +62,53 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA              QuietModeManager quietModeManager,              @Profile int defaultProfile,              UserHandle workProfileUserHandle) { -        super(context, /* currentPage */ defaultProfile, emptyStateProvider, quietModeManager, -                workProfileUserHandle); -        mItems = new ResolverProfileDescriptor[] { -                createProfileDescriptor(personalAdapter), -                createProfileDescriptor(workAdapter) -        }; -    } - -    private ResolverProfileDescriptor createProfileDescriptor( -            ResolverListAdapter adapter) { -        final LayoutInflater inflater = LayoutInflater.from(getContext()); -        final ViewGroup rootView = -                (ViewGroup) inflater.inflate(R.layout.resolver_list_per_profile, null, false); -        return new ResolverProfileDescriptor(rootView, adapter); -    } - -    ListView getListViewForIndex(int index) { -        return getItem(index).listView; -    } - -    @Override -    ResolverProfileDescriptor getItem(int pageIndex) { -        return mItems[pageIndex]; -    } - -    @Override -    int getItemCount() { -        return mItems.length; -    } - -    @Override -    void setupListAdapter(int pageIndex) { -        final ListView listView = getItem(pageIndex).listView; -        listView.setAdapter(getItem(pageIndex).resolverListAdapter); -    } - -    @Override -    @VisibleForTesting -    public ResolverListAdapter getAdapterForIndex(int pageIndex) { -        return mItems[pageIndex].resolverListAdapter; -    } - -    @Override -    public ViewGroup instantiateItem(ViewGroup container, int position) { -        setupListAdapter(position); -        return super.instantiateItem(container, position); -    } - -    @Override -    @Nullable -    ResolverListAdapter getListAdapterForUserHandle(UserHandle userHandle) { -        if (getActiveListAdapter().getUserHandle().equals(userHandle)) { -            return getActiveListAdapter(); -        } else if (getInactiveListAdapter() != null -                && getInactiveListAdapter().getUserHandle().equals(userHandle)) { -            return getInactiveListAdapter(); -        } -        return null; -    } - -    @Override -    @VisibleForTesting -    public ResolverListAdapter getActiveListAdapter() { -        return getAdapterForIndex(getCurrentPage()); -    } - -    @Override -    @VisibleForTesting -    public ResolverListAdapter getInactiveListAdapter() { -        if (getCount() == 1) { -            return null; -        } -        return getAdapterForIndex(1 - getCurrentPage()); -    } - -    @Override -    public ResolverListAdapter getPersonalListAdapter() { -        return getAdapterForIndex(PROFILE_PERSONAL); -    } - -    @Override -    @Nullable -    public ResolverListAdapter getWorkListAdapter() { -        return getAdapterForIndex(PROFILE_WORK); -    } - -    @Override -    ResolverListAdapter getCurrentRootAdapter() { -        return getActiveListAdapter(); -    } - -    @Override -    ListView getActiveAdapterView() { -        return getListViewForIndex(getCurrentPage()); -    } - -    @Override -    @Nullable -    ViewGroup getInactiveAdapterView() { -        if (getCount() == 1) { -            return null; +        this( +                context, +                ImmutableList.of(personalAdapter, workAdapter), +                emptyStateProvider, +                quietModeManager, +                defaultProfile, +                workProfileUserHandle, +                new BottomPaddingOverrideSupplier()); +    } + +    private ResolverMultiProfilePagerAdapter( +            Context context, +            ImmutableList<ResolverListAdapter> listAdapters, +            EmptyStateProvider emptyStateProvider, +            QuietModeManager quietModeManager, +            @Profile int defaultProfile, +            UserHandle workProfileUserHandle, +            BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier) { +        super( +                context, +                        listAdapter -> listAdapter, +                        (listView, bindAdapter) -> listView.setAdapter(bindAdapter), +                listAdapters, +                emptyStateProvider, +                quietModeManager, +                defaultProfile, +                workProfileUserHandle, +                        () -> (ViewGroup) LayoutInflater.from(context).inflate( +                                R.layout.resolver_list_per_profile, null, false), +                bottomPaddingOverrideSupplier); +        mBottomPaddingOverrideSupplier = bottomPaddingOverrideSupplier; +    } + +    public void setUseLayoutWithDefault(boolean useLayoutWithDefault) { +        mBottomPaddingOverrideSupplier.setUseLayoutWithDefault(useLayoutWithDefault); +    } + +    private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> { +        private boolean mUseLayoutWithDefault; + +        public void setUseLayoutWithDefault(boolean useLayoutWithDefault) { +            mUseLayoutWithDefault = useLayoutWithDefault;          } -        return getListViewForIndex(1 - getCurrentPage()); -    } - -    void setUseLayoutWithDefault(boolean useLayoutWithDefault) { -        mUseLayoutWithDefault = useLayoutWithDefault; -    } - -    @Override -    protected void setupContainerPadding(View container) { -        int bottom = mUseLayoutWithDefault ? container.getPaddingBottom() : 0; -        container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), -                container.getPaddingRight(), bottom); -    } -    class ResolverProfileDescriptor extends ProfileDescriptor { -        private ResolverListAdapter resolverListAdapter; -        final ListView listView; -        ResolverProfileDescriptor(ViewGroup rootView, ResolverListAdapter adapter) { -            super(rootView); -            resolverListAdapter = adapter; -            listView = rootView.findViewById(com.android.internal.R.id.resolver_list); +        @Override +        public Optional<Integer> get() { +            return mUseLayoutWithDefault ? Optional.empty() : Optional.of(0);          }      }  } |