1 /* 2 * Copyright (C) 2016 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 package com.android.support.car.lenspicker; 17 18 import android.content.ComponentName; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.ActivityInfo; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ResolveInfo; 25 import android.graphics.drawable.Drawable; 26 import android.os.AsyncTask; 27 import android.util.Log; 28 import android.view.LayoutInflater; 29 import android.view.ViewGroup; 30 31 import androidx.car.widget.PagedListView; 32 import androidx.recyclerview.widget.RecyclerView; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 /** 38 * An adapter that binds each of the rows within the {@link LensResolverActivity}. 39 */ 40 public class ResolverAdapter extends RecyclerView.Adapter<ResolverListRow> 41 implements PagedListView.ItemCap { 42 private static final String TAG = "ResolverAdapter"; 43 44 private final Context mContext; 45 private final List<ResolveInfo> mResolveInfos; 46 private final List<LensPickerItem> mItems = new ArrayList<>(); 47 private ResolverListRow.ResolverSelectionHandler mHandler; 48 ResolverAdapter(Context context, List<ResolveInfo> resolveInfos)49 public ResolverAdapter(Context context, List<ResolveInfo> resolveInfos) { 50 mContext = context; 51 mResolveInfos = resolveInfos; 52 53 new LoadTask().execute(null, null, null); 54 } 55 setSelectionHandler(ResolverListRow.ResolverSelectionHandler handler)56 public void setSelectionHandler(ResolverListRow.ResolverSelectionHandler handler) { 57 mHandler = handler; 58 } 59 60 @Override onCreateViewHolder(ViewGroup parent, int viewType)61 public ResolverListRow onCreateViewHolder(ViewGroup parent, int viewType) { 62 LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 63 return new ResolverListRow( 64 inflater.inflate(R.layout.car_list_item_1_card, parent, false)); 65 } 66 67 @Override onBindViewHolder(ResolverListRow holder, int position)68 public void onBindViewHolder(ResolverListRow holder, int position) { 69 holder.bind(mContext, mResolveInfos.get(position), mItems.get(position), mHandler); 70 } 71 72 @Override getItemCount()73 public int getItemCount() { 74 return mItems == null ? 0 : mItems.size(); 75 } 76 77 @Override setMaxItems(int maxItems)78 public void setMaxItems(int maxItems) { 79 // No-op, but method override is needed for PagedListView. 80 } 81 82 /** 83 * An {@link AsyncTask} that will construct the corresponding launch Intents for each of the 84 * activities represented by {@link #mResolveInfos}. Upon completion, that information is 85 * packaged into a {@link LensPickerItem} and stored within {@link #mItems}. 86 */ 87 private class LoadTask extends AsyncTask<Void, Void, List<LensPickerItem>> { 88 @Override doInBackground(Void... unused)89 protected List<LensPickerItem> doInBackground(Void... unused) { 90 List<LensPickerItem> items = new ArrayList<>(); 91 92 PackageManager packageManager = mContext.getPackageManager(); 93 94 for (ResolveInfo info : mResolveInfos) { 95 String packageName = LensPickerUtils.getPackageName(info); 96 97 try { 98 ApplicationInfo aInfo = packageManager.getApplicationInfo(packageName, 0); 99 String displayName = ""; 100 if (LensPickerUtils.isMediaService(info)) { 101 // For media services we take the service tag instead of the package name. 102 // This is done to avoid Bluetooth showing Bluetooth Share as the package 103 // name. 104 displayName = info.loadLabel(packageManager).toString(); 105 if (Log.isLoggable(TAG, Log.DEBUG)) { 106 Log.d(TAG, "Media service label set to: " + displayName); 107 } 108 } 109 110 // If we found an empty label for above case or if we did not hit the above if 111 // block then simply set this string to package name. 112 if (displayName.equals("")) { 113 displayName = getComponentLabel(packageManager, aInfo); 114 } 115 116 Intent intent; 117 if (LensPickerUtils.isMediaService(info)) { 118 intent = LensPickerUtils.getMediaLaunchIntent(packageManager, packageName, 119 info.serviceInfo.name); 120 } else { 121 intent = new Intent(); 122 ActivityInfo activity = info.activityInfo; 123 intent.setComponent( 124 new ComponentName(activity.applicationInfo.packageName, 125 activity.name)); 126 } 127 128 items.add(new LensPickerItem(displayName, 129 getComponentIcon(packageManager, aInfo), intent, 130 null /* facetId */)); 131 } catch (PackageManager.NameNotFoundException e) { 132 // skip this package. 133 } 134 } 135 136 return items; 137 } 138 139 @Override onPostExecute(List<LensPickerItem> items)140 protected void onPostExecute(List<LensPickerItem> items) { 141 mItems.addAll(items); 142 notifyDataSetChanged(); 143 } 144 145 /** 146 * Returns the icon for the application represented by the given parameters. 147 */ getComponentIcon(PackageManager packageManager, ApplicationInfo info)148 private Drawable getComponentIcon(PackageManager packageManager, ApplicationInfo info) { 149 return packageManager.getApplicationIcon(info); 150 } 151 152 /** 153 * Returns the name of the application represented by the given parameters. 154 */ getComponentLabel(PackageManager packageManager, ApplicationInfo info)155 private String getComponentLabel(PackageManager packageManager, ApplicationInfo info) { 156 CharSequence appLabel = packageManager.getApplicationLabel(info); 157 158 if (appLabel == null) { 159 return null; 160 } 161 162 return appLabel.toString(); 163 } 164 } 165 166 167 } 168