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.internal.app;
18 
19 import android.annotation.Nullable;
20 import android.content.Context;
21 import android.os.UserHandle;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.view.ViewGroup;
25 
26 import com.android.internal.R;
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.internal.widget.GridLayoutManager;
29 import com.android.internal.widget.PagerAdapter;
30 import com.android.internal.widget.RecyclerView;
31 
32 /**
33  * A {@link PagerAdapter} which describes the work and personal profile share sheet screens.
34  */
35 @VisibleForTesting
36 public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAdapter {
37     private static final int SINGLE_CELL_SPAN_SIZE = 1;
38 
39     private final ChooserProfileDescriptor[] mItems;
40     private final boolean mIsSendAction;
41     private int mBottomOffset;
42 
ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter adapter, UserHandle personalProfileUserHandle, UserHandle workProfileUserHandle, boolean isSendAction)43     ChooserMultiProfilePagerAdapter(Context context,
44             ChooserActivity.ChooserGridAdapter adapter,
45             UserHandle personalProfileUserHandle,
46             UserHandle workProfileUserHandle,
47             boolean isSendAction) {
48         super(context, /* currentPage */ 0, personalProfileUserHandle, workProfileUserHandle);
49         mItems = new ChooserProfileDescriptor[] {
50                 createProfileDescriptor(adapter)
51         };
52         mIsSendAction = isSendAction;
53     }
54 
ChooserMultiProfilePagerAdapter(Context context, ChooserActivity.ChooserGridAdapter personalAdapter, ChooserActivity.ChooserGridAdapter workAdapter, @Profile int defaultProfile, UserHandle personalProfileUserHandle, UserHandle workProfileUserHandle, boolean isSendAction)55     ChooserMultiProfilePagerAdapter(Context context,
56             ChooserActivity.ChooserGridAdapter personalAdapter,
57             ChooserActivity.ChooserGridAdapter workAdapter,
58             @Profile int defaultProfile,
59             UserHandle personalProfileUserHandle,
60             UserHandle workProfileUserHandle,
61             boolean isSendAction) {
62         super(context, /* currentPage */ defaultProfile, personalProfileUserHandle,
63                 workProfileUserHandle);
64         mItems = new ChooserProfileDescriptor[] {
65                 createProfileDescriptor(personalAdapter),
66                 createProfileDescriptor(workAdapter)
67         };
68         mIsSendAction = isSendAction;
69     }
70 
createProfileDescriptor( ChooserActivity.ChooserGridAdapter adapter)71     private ChooserProfileDescriptor createProfileDescriptor(
72             ChooserActivity.ChooserGridAdapter adapter) {
73         final LayoutInflater inflater = LayoutInflater.from(getContext());
74         final ViewGroup rootView =
75                 (ViewGroup) inflater.inflate(R.layout.chooser_list_per_profile, null, false);
76         return new ChooserProfileDescriptor(rootView, adapter);
77     }
78 
getListViewForIndex(int index)79     RecyclerView getListViewForIndex(int index) {
80         return getItem(index).recyclerView;
81     }
82 
83     @Override
getItem(int pageIndex)84     ChooserProfileDescriptor getItem(int pageIndex) {
85         return mItems[pageIndex];
86     }
87 
88     @Override
getItemCount()89     int getItemCount() {
90         return mItems.length;
91     }
92 
93     @Override
94     @VisibleForTesting
getAdapterForIndex(int pageIndex)95     public ChooserActivity.ChooserGridAdapter getAdapterForIndex(int pageIndex) {
96         return mItems[pageIndex].chooserGridAdapter;
97     }
98 
99     @Override
100     @Nullable
getListAdapterForUserHandle(UserHandle userHandle)101     ChooserListAdapter getListAdapterForUserHandle(UserHandle userHandle) {
102         if (getActiveListAdapter().getUserHandle().equals(userHandle)) {
103             return getActiveListAdapter();
104         } else if (getInactiveListAdapter() != null
105                 && getInactiveListAdapter().getUserHandle().equals(userHandle)) {
106             return getInactiveListAdapter();
107         }
108         return null;
109     }
110 
111     @Override
setupListAdapter(int pageIndex)112     void setupListAdapter(int pageIndex) {
113         final RecyclerView recyclerView = getItem(pageIndex).recyclerView;
114         ChooserActivity.ChooserGridAdapter chooserGridAdapter =
115                 getItem(pageIndex).chooserGridAdapter;
116         GridLayoutManager glm = (GridLayoutManager) recyclerView.getLayoutManager();
117         glm.setSpanCount(chooserGridAdapter.getMaxTargetsPerRow());
118         glm.setSpanSizeLookup(
119                 new GridLayoutManager.SpanSizeLookup() {
120                     @Override
121                     public int getSpanSize(int position) {
122                         return chooserGridAdapter.shouldCellSpan(position)
123                                 ? SINGLE_CELL_SPAN_SIZE
124                                 : glm.getSpanCount();
125                     }
126                 });
127     }
128 
129     @Override
130     @VisibleForTesting
getActiveListAdapter()131     public ChooserListAdapter getActiveListAdapter() {
132         return getAdapterForIndex(getCurrentPage()).getListAdapter();
133     }
134 
135     @Override
136     @VisibleForTesting
getInactiveListAdapter()137     public ChooserListAdapter getInactiveListAdapter() {
138         if (getCount() == 1) {
139             return null;
140         }
141         return getAdapterForIndex(1 - getCurrentPage()).getListAdapter();
142     }
143 
144     @Override
getPersonalListAdapter()145     public ResolverListAdapter getPersonalListAdapter() {
146         return getAdapterForIndex(PROFILE_PERSONAL).getListAdapter();
147     }
148 
149     @Override
150     @Nullable
getWorkListAdapter()151     public ResolverListAdapter getWorkListAdapter() {
152         return getAdapterForIndex(PROFILE_WORK).getListAdapter();
153     }
154 
155     @Override
getCurrentRootAdapter()156     ChooserActivity.ChooserGridAdapter getCurrentRootAdapter() {
157         return getAdapterForIndex(getCurrentPage());
158     }
159 
160     @Override
getActiveAdapterView()161     RecyclerView getActiveAdapterView() {
162         return getListViewForIndex(getCurrentPage());
163     }
164 
165     @Override
166     @Nullable
getInactiveAdapterView()167     RecyclerView getInactiveAdapterView() {
168         if (getCount() == 1) {
169             return null;
170         }
171         return getListViewForIndex(1 - getCurrentPage());
172     }
173 
174     @Override
getMetricsCategory()175     String getMetricsCategory() {
176         return ResolverActivity.METRICS_CATEGORY_CHOOSER;
177     }
178 
179     @Override
showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter, View.OnClickListener listener)180     protected void showWorkProfileOffEmptyState(ResolverListAdapter activeListAdapter,
181             View.OnClickListener listener) {
182         showEmptyState(activeListAdapter,
183                 R.drawable.ic_work_apps_off,
184                 R.string.resolver_turn_on_work_apps,
185                 /* subtitleRes */ 0,
186                 listener);
187     }
188 
189     @Override
showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter)190     protected void showNoPersonalToWorkIntentsEmptyState(ResolverListAdapter activeListAdapter) {
191         if (mIsSendAction) {
192             showEmptyState(activeListAdapter,
193                     R.drawable.ic_sharing_disabled,
194                     R.string.resolver_cant_share_with_work_apps,
195                     R.string.resolver_cant_share_with_work_apps_explanation);
196         } else {
197             showEmptyState(activeListAdapter,
198                     R.drawable.ic_sharing_disabled,
199                     R.string.resolver_cant_access_work_apps,
200                     R.string.resolver_cant_access_work_apps_explanation);
201         }
202     }
203 
204     @Override
showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter)205     protected void showNoWorkToPersonalIntentsEmptyState(ResolverListAdapter activeListAdapter) {
206         if (mIsSendAction) {
207             showEmptyState(activeListAdapter,
208                     R.drawable.ic_sharing_disabled,
209                     R.string.resolver_cant_share_with_personal_apps,
210                     R.string.resolver_cant_share_with_personal_apps_explanation);
211         } else {
212             showEmptyState(activeListAdapter,
213                     R.drawable.ic_sharing_disabled,
214                     R.string.resolver_cant_access_personal_apps,
215                     R.string.resolver_cant_access_personal_apps_explanation);
216         }
217     }
218 
219     @Override
showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter)220     protected void showNoPersonalAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
221         if (mIsSendAction) {
222             showEmptyState(listAdapter,
223                     R.drawable.ic_no_apps,
224                     R.string.resolver_no_personal_apps_available_share,
225                     /* subtitleRes */ 0);
226         } else {
227             showEmptyState(listAdapter,
228                     R.drawable.ic_no_apps,
229                     R.string.resolver_no_personal_apps_available_resolve,
230                     /* subtitleRes */ 0);
231         }
232     }
233 
234     @Override
showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter)235     protected void showNoWorkAppsAvailableEmptyState(ResolverListAdapter listAdapter) {
236         if (mIsSendAction) {
237             showEmptyState(listAdapter,
238                     R.drawable.ic_no_apps,
239                     R.string.resolver_no_work_apps_available_share,
240                     /* subtitleRes */ 0);
241         } else {
242             showEmptyState(listAdapter,
243                     R.drawable.ic_no_apps,
244                     R.string.resolver_no_work_apps_available_resolve,
245                     /* subtitleRes */ 0);
246         }
247     }
248 
setEmptyStateBottomOffset(int bottomOffset)249     void setEmptyStateBottomOffset(int bottomOffset) {
250         mBottomOffset = bottomOffset;
251     }
252 
253     @Override
setupContainerPadding(View container)254     protected void setupContainerPadding(View container) {
255         container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
256                 container.getPaddingRight(), container.getPaddingBottom() + mBottomOffset);
257     }
258 
259     class ChooserProfileDescriptor extends ProfileDescriptor {
260         private ChooserActivity.ChooserGridAdapter chooserGridAdapter;
261         private RecyclerView recyclerView;
ChooserProfileDescriptor(ViewGroup rootView, ChooserActivity.ChooserGridAdapter adapter)262         ChooserProfileDescriptor(ViewGroup rootView, ChooserActivity.ChooserGridAdapter adapter) {
263             super(rootView);
264             chooserGridAdapter = adapter;
265             recyclerView = rootView.findViewById(R.id.resolver_list);
266         }
267     }
268 }
269