• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.intentresolver;
18 
19 import android.content.Context;
20 import android.os.UserHandle;
21 import android.view.LayoutInflater;
22 import android.view.ViewGroup;
23 
24 import androidx.recyclerview.widget.GridLayoutManager;
25 import androidx.recyclerview.widget.RecyclerView;
26 import androidx.viewpager.widget.PagerAdapter;
27 
28 import com.android.intentresolver.grid.ChooserGridAdapter;
29 import com.android.intentresolver.measurements.Tracer;
30 import com.android.internal.annotations.VisibleForTesting;
31 
32 import com.google.common.collect.ImmutableList;
33 
34 import java.util.Optional;
35 import java.util.function.Supplier;
36 
37 /**
38  * A {@link PagerAdapter} which describes the work and personal profile share sheet screens.
39  */
40 @VisibleForTesting
41 public class ChooserMultiProfilePagerAdapter extends GenericMultiProfilePagerAdapter<
42         RecyclerView, ChooserGridAdapter, ChooserListAdapter> {
43     private static final int SINGLE_CELL_SPAN_SIZE = 1;
44 
45     private final ChooserProfileAdapterBinder mAdapterBinder;
46     private final BottomPaddingOverrideSupplier mBottomPaddingOverrideSupplier;
47 
ChooserMultiProfilePagerAdapter( Context context, ChooserGridAdapter adapter, EmptyStateProvider emptyStateProvider, Supplier<Boolean> workProfileQuietModeChecker, UserHandle workProfileUserHandle, UserHandle cloneProfileUserHandle, int maxTargetsPerRow)48     ChooserMultiProfilePagerAdapter(
49             Context context,
50             ChooserGridAdapter adapter,
51             EmptyStateProvider emptyStateProvider,
52             Supplier<Boolean> workProfileQuietModeChecker,
53             UserHandle workProfileUserHandle,
54             UserHandle cloneProfileUserHandle,
55             int maxTargetsPerRow) {
56         this(
57                 context,
58                 new ChooserProfileAdapterBinder(maxTargetsPerRow),
59                 ImmutableList.of(adapter),
60                 emptyStateProvider,
61                 workProfileQuietModeChecker,
62                 /* defaultProfile= */ 0,
63                 workProfileUserHandle,
64                 cloneProfileUserHandle,
65                 new BottomPaddingOverrideSupplier(context));
66     }
67 
ChooserMultiProfilePagerAdapter( Context context, ChooserGridAdapter personalAdapter, ChooserGridAdapter workAdapter, EmptyStateProvider emptyStateProvider, Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, UserHandle cloneProfileUserHandle, int maxTargetsPerRow)68     ChooserMultiProfilePagerAdapter(
69             Context context,
70             ChooserGridAdapter personalAdapter,
71             ChooserGridAdapter workAdapter,
72             EmptyStateProvider emptyStateProvider,
73             Supplier<Boolean> workProfileQuietModeChecker,
74             @Profile int defaultProfile,
75             UserHandle workProfileUserHandle,
76             UserHandle cloneProfileUserHandle,
77             int maxTargetsPerRow) {
78         this(
79                 context,
80                 new ChooserProfileAdapterBinder(maxTargetsPerRow),
81                 ImmutableList.of(personalAdapter, workAdapter),
82                 emptyStateProvider,
83                 workProfileQuietModeChecker,
84                 defaultProfile,
85                 workProfileUserHandle,
86                 cloneProfileUserHandle,
87                 new BottomPaddingOverrideSupplier(context));
88     }
89 
ChooserMultiProfilePagerAdapter( Context context, ChooserProfileAdapterBinder adapterBinder, ImmutableList<ChooserGridAdapter> gridAdapters, EmptyStateProvider emptyStateProvider, Supplier<Boolean> workProfileQuietModeChecker, @Profile int defaultProfile, UserHandle workProfileUserHandle, UserHandle cloneProfileUserHandle, BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier)90     private ChooserMultiProfilePagerAdapter(
91             Context context,
92             ChooserProfileAdapterBinder adapterBinder,
93             ImmutableList<ChooserGridAdapter> gridAdapters,
94             EmptyStateProvider emptyStateProvider,
95             Supplier<Boolean> workProfileQuietModeChecker,
96             @Profile int defaultProfile,
97             UserHandle workProfileUserHandle,
98             UserHandle cloneProfileUserHandle,
99             BottomPaddingOverrideSupplier bottomPaddingOverrideSupplier) {
100         super(
101                 context,
102                         gridAdapter -> gridAdapter.getListAdapter(),
103                 adapterBinder,
104                 gridAdapters,
105                 emptyStateProvider,
106                 workProfileQuietModeChecker,
107                 defaultProfile,
108                 workProfileUserHandle,
109                 cloneProfileUserHandle,
110                         () -> makeProfileView(context),
111                 bottomPaddingOverrideSupplier);
112         mAdapterBinder = adapterBinder;
113         mBottomPaddingOverrideSupplier = bottomPaddingOverrideSupplier;
114     }
115 
setMaxTargetsPerRow(int maxTargetsPerRow)116     public void setMaxTargetsPerRow(int maxTargetsPerRow) {
117         mAdapterBinder.setMaxTargetsPerRow(maxTargetsPerRow);
118     }
119 
setEmptyStateBottomOffset(int bottomOffset)120     public void setEmptyStateBottomOffset(int bottomOffset) {
121         mBottomPaddingOverrideSupplier.setEmptyStateBottomOffset(bottomOffset);
122     }
123 
124     /**
125      * Notify adapter about the drawer's collapse state. This will affect the app divider's
126      * visibility.
127      */
setIsCollapsed(boolean isCollapsed)128     public void setIsCollapsed(boolean isCollapsed) {
129         for (int i = 0, size = getItemCount(); i < size; i++) {
130             getAdapterForIndex(i).setAzLabelVisibility(!isCollapsed);
131         }
132     }
133 
makeProfileView(Context context)134     private static ViewGroup makeProfileView(Context context) {
135         LayoutInflater inflater = LayoutInflater.from(context);
136         ViewGroup rootView = (ViewGroup) inflater.inflate(
137                 R.layout.chooser_list_per_profile, null, false);
138         RecyclerView recyclerView = rootView.findViewById(com.android.internal.R.id.resolver_list);
139         recyclerView.setAccessibilityDelegateCompat(
140                 new ChooserRecyclerViewAccessibilityDelegate(recyclerView));
141         return rootView;
142     }
143 
144     @Override
rebuildActiveTab(boolean doPostProcessing)145     boolean rebuildActiveTab(boolean doPostProcessing) {
146         if (doPostProcessing) {
147             Tracer.INSTANCE.beginAppTargetLoadingSection(getActiveListAdapter().getUserHandle());
148         }
149         return super.rebuildActiveTab(doPostProcessing);
150     }
151 
152     @Override
rebuildInactiveTab(boolean doPostProcessing)153     boolean rebuildInactiveTab(boolean doPostProcessing) {
154         if (getItemCount() != 1 && doPostProcessing) {
155             Tracer.INSTANCE.beginAppTargetLoadingSection(getInactiveListAdapter().getUserHandle());
156         }
157         return super.rebuildInactiveTab(doPostProcessing);
158     }
159 
160     private static class BottomPaddingOverrideSupplier implements Supplier<Optional<Integer>> {
161         private final Context mContext;
162         private int mBottomOffset;
163 
BottomPaddingOverrideSupplier(Context context)164         BottomPaddingOverrideSupplier(Context context) {
165             mContext = context;
166         }
167 
setEmptyStateBottomOffset(int bottomOffset)168         public void setEmptyStateBottomOffset(int bottomOffset) {
169             mBottomOffset = bottomOffset;
170         }
171 
get()172         public Optional<Integer> get() {
173             int initialBottomPadding = mContext.getResources().getDimensionPixelSize(
174                     R.dimen.resolver_empty_state_container_padding_bottom);
175             return Optional.of(initialBottomPadding + mBottomOffset);
176         }
177     }
178 
179     private static class ChooserProfileAdapterBinder implements
180             AdapterBinder<RecyclerView, ChooserGridAdapter> {
181         private int mMaxTargetsPerRow;
182 
ChooserProfileAdapterBinder(int maxTargetsPerRow)183         ChooserProfileAdapterBinder(int maxTargetsPerRow) {
184             mMaxTargetsPerRow = maxTargetsPerRow;
185         }
186 
setMaxTargetsPerRow(int maxTargetsPerRow)187         public void setMaxTargetsPerRow(int maxTargetsPerRow) {
188             mMaxTargetsPerRow = maxTargetsPerRow;
189         }
190 
191         @Override
bind( RecyclerView recyclerView, ChooserGridAdapter chooserGridAdapter)192         public void bind(
193                 RecyclerView recyclerView, ChooserGridAdapter chooserGridAdapter) {
194             GridLayoutManager glm = (GridLayoutManager) recyclerView.getLayoutManager();
195             glm.setSpanCount(mMaxTargetsPerRow);
196             glm.setSpanSizeLookup(
197                     new GridLayoutManager.SpanSizeLookup() {
198                         @Override
199                         public int getSpanSize(int position) {
200                             return chooserGridAdapter.shouldCellSpan(position)
201                                     ? SINGLE_CELL_SPAN_SIZE
202                                     : glm.getSpanCount();
203                         }
204                     });
205         }
206     }
207 }
208