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