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