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