1 /* 2 * Copyright (C) 2015 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.Context; 19 import android.content.Intent; 20 import android.content.SharedPreferences; 21 import android.content.pm.ApplicationInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 import android.graphics.drawable.Drawable; 25 import android.os.AsyncTask; 26 import android.support.v7.widget.RecyclerView; 27 import android.util.Log; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 32 import com.android.car.view.PagedListView; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 /** 38 * Lens picker adapter that provides the data fed into lens picker list. 39 * 40 */ 41 public class LensPickerAdapter extends RecyclerView.Adapter<LensPickerRow> 42 implements PagedListView.ItemCap{ 43 private static final String TAG = "LensPickerAdapter"; 44 45 private final Context mContext; 46 private final LensPickerSelectionHandler mSelectionHandler; 47 private final List<LensPickerItem> mItems = new ArrayList<>(); 48 49 private LoadTask mLoader; 50 private PackageManager mPackageManager; 51 private SharedPreferences mSharedPrefs; 52 private List<ResolveInfo> mResolveInfos; 53 private String mFacetId; 54 55 public LensPickerAdapter(Context context, List<ResolveInfo> rInfo, String facetId, 56 LensPickerSelectionHandler selectionHandler) { 57 mContext = context; 58 mSelectionHandler = selectionHandler; 59 mPackageManager = context.getPackageManager(); 60 mSharedPrefs = LensPickerUtils.getFacetSharedPrefs(context); 61 mResolveInfos = rInfo; 62 mFacetId = facetId; 63 mLoader = new LoadTask(); 64 mLoader.execute(null, null, null); 65 } 66 67 @Override 68 public LensPickerRow onCreateViewHolder(ViewGroup parent, int viewType) { 69 LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 70 View view = inflater.inflate(R.layout.car_list_item_1_card, parent, false); 71 return new LensPickerRow(view); 72 } 73 74 @Override 75 public void onBindViewHolder(LensPickerRow holder, int position) { 76 holder.bind(mContext, mItems.get(position), mSelectionHandler); 77 } 78 79 @Override 80 public int getItemCount() { 81 return mItems.size(); 82 } 83 84 @Override 85 public void setMaxItems(int maxItems) { 86 // Ignore maxItems 87 } 88 89 private class LoadTask extends AsyncTask<Void, Void, Void> { 90 private List<LensPickerItem> mLoadedItems = new ArrayList<LensPickerItem>(); 91 92 @Override 93 protected Void doInBackground(Void... unused) { 94 for (int i = 0; i < mResolveInfos.size(); i++) { 95 ResolveInfo rInfo = mResolveInfos.get(i); 96 String packageName = LensPickerUtils.getPackageName(rInfo); 97 Intent launchIntent = LensPickerUtils.getLaunchIntent(packageName, rInfo, 98 mPackageManager); 99 if (launchIntent == null) { 100 Log.w(TAG, "No launch intent for package " + packageName + " skipping."); 101 continue; 102 } 103 104 try { 105 ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0); 106 String displayName = ""; 107 if (LensPickerUtils.isMediaService(rInfo)) { 108 // For media services we take the service tag instead of the package name. 109 // This is done to avoid Bluetooth showing Bluetooth Share as the package 110 // name. 111 displayName = rInfo.loadLabel(mPackageManager).toString(); 112 if (Log.isLoggable(TAG, Log.DEBUG)) { 113 Log.d(TAG, "Media service label set to: " + displayName); 114 } 115 } 116 117 // If we found an empty label for above case or if we did not hit the above if 118 // block then simply set this string to package name. 119 if (displayName.equals("")) { 120 displayName = getComponentLabel(aInfo); 121 } 122 mLoadedItems.add( 123 new LensPickerItem( 124 displayName, 125 getComponentIcon(aInfo), 126 launchIntent, 127 mFacetId)); 128 } catch (PackageManager.NameNotFoundException e) { 129 // skip this package. 130 } 131 132 if (i % 2 == 0) { 133 publishProgress(); 134 } 135 } 136 return null; 137 } 138 139 @Override 140 protected void onProgressUpdate(Void... unused) { 141 appendAndNotify(); 142 } 143 144 @Override 145 protected void onPostExecute(Void unused) { 146 appendAndNotify(); 147 } 148 149 private void appendAndNotify() { 150 int oldSize = mItems.size(); 151 for (int i = oldSize; i < mLoadedItems.size(); i++) { 152 mItems.add(mLoadedItems.get(i)); 153 } 154 notifyItemRangeInserted(oldSize, mItems.size()); 155 } 156 157 private Drawable getComponentIcon(ApplicationInfo aInfo) { 158 return mPackageManager.getApplicationIcon(aInfo); 159 } 160 161 private String getComponentLabel(ApplicationInfo aInfo) { 162 CharSequence appLabel = mPackageManager.getApplicationLabel(aInfo); 163 if (appLabel != null) { 164 return appLabel.toString(); 165 } 166 return null; 167 } 168 }; 169 } 170