1 /* 2 * Copyright (C) 2008 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.launcher2; 18 19 import android.widget.CursorAdapter; 20 import android.widget.TextView; 21 import android.widget.ImageView; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.res.Resources; 25 import android.content.pm.PackageManager; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.view.LayoutInflater; 29 import android.database.Cursor; 30 import android.provider.LiveFolders; 31 import android.graphics.drawable.Drawable; 32 import android.graphics.BitmapFactory; 33 import android.graphics.Bitmap; 34 35 import java.net.URISyntaxException; 36 import java.util.HashMap; 37 import java.lang.ref.SoftReference; 38 39 import com.android.launcher.R; 40 41 class LiveFolderAdapter extends CursorAdapter { 42 private boolean mIsList; 43 private LayoutInflater mInflater; 44 45 private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>(); 46 private final HashMap<Long, SoftReference<Drawable>> mCustomIcons = 47 new HashMap<Long, SoftReference<Drawable>>(); 48 private final Launcher mLauncher; 49 50 LiveFolderAdapter(Launcher launcher, LiveFolderInfo info, Cursor cursor) { 51 super(launcher, cursor, true); 52 mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST; 53 mInflater = LayoutInflater.from(launcher); 54 mLauncher = launcher; 55 56 mLauncher.startManagingCursor(getCursor()); 57 } 58 59 static Cursor query(Context context, LiveFolderInfo info) { 60 return context.getContentResolver().query(info.uri, null, null, 61 null, LiveFolders.NAME + " ASC"); 62 } 63 64 public View newView(Context context, Cursor cursor, ViewGroup parent) { 65 View view; 66 final ViewHolder holder = new ViewHolder(); 67 68 if (!mIsList) { 69 view = mInflater.inflate(R.layout.application_boxed, parent, false); 70 } else { 71 view = mInflater.inflate(R.layout.application_list, parent, false); 72 holder.description = (TextView) view.findViewById(R.id.description); 73 holder.icon = (ImageView) view.findViewById(R.id.icon); 74 } 75 76 holder.name = (TextView) view.findViewById(R.id.name); 77 78 holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID); 79 holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME); 80 holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION); 81 holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT); 82 holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP); 83 holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE); 84 holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE); 85 86 view.setTag(holder); 87 88 return view; 89 } 90 91 public void bindView(View view, Context context, Cursor cursor) { 92 final ViewHolder holder = (ViewHolder) view.getTag(); 93 94 holder.id = cursor.getLong(holder.idIndex); 95 final Drawable icon = loadIcon(context, cursor, holder); 96 97 holder.name.setText(cursor.getString(holder.nameIndex)); 98 99 if (!mIsList) { 100 holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null); 101 } else { 102 final boolean hasIcon = icon != null; 103 holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE); 104 if (hasIcon) holder.icon.setImageDrawable(icon); 105 106 if (holder.descriptionIndex != -1) { 107 final String description = cursor.getString(holder.descriptionIndex); 108 if (description != null) { 109 holder.description.setText(description); 110 holder.description.setVisibility(View.VISIBLE); 111 } else { 112 holder.description.setVisibility(View.GONE); 113 } 114 } else { 115 holder.description.setVisibility(View.GONE); 116 } 117 } 118 119 if (holder.intentIndex != -1) { 120 try { 121 holder.intent = Intent.parseUri(cursor.getString(holder.intentIndex), 0); 122 } catch (URISyntaxException e) { 123 // Ignore 124 } 125 } else { 126 holder.useBaseIntent = true; 127 } 128 } 129 130 private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) { 131 Drawable icon = null; 132 byte[] data = null; 133 134 if (holder.iconBitmapIndex != -1) { 135 data = cursor.getBlob(holder.iconBitmapIndex); 136 } 137 138 if (data != null) { 139 final SoftReference<Drawable> reference = mCustomIcons.get(holder.id); 140 if (reference != null) { 141 icon = reference.get(); 142 } 143 144 if (icon == null) { 145 final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 146 final Bitmap resampled = Utilities.resampleIconBitmap(bitmap, mContext); 147 if (bitmap != resampled) { 148 // If we got back a different object, we don't need the old one any more. 149 bitmap.recycle(); 150 } 151 icon = new FastBitmapDrawable(resampled); 152 mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon)); 153 } 154 } else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) { 155 final String resource = cursor.getString(holder.iconResourceIndex); 156 icon = mIcons.get(resource); 157 if (icon == null) { 158 try { 159 final PackageManager packageManager = context.getPackageManager(); 160 Resources resources = packageManager.getResourcesForApplication( 161 cursor.getString(holder.iconPackageIndex)); 162 final int id = resources.getIdentifier(resource, 163 null, null); 164 icon = new FastBitmapDrawable( 165 Utilities.createIconBitmap(resources.getDrawable(id), mContext)); 166 mIcons.put(resource, icon); 167 } catch (Exception e) { 168 // Ignore 169 } 170 } 171 } 172 173 return icon; 174 } 175 176 void cleanup() { 177 for (Drawable icon : mIcons.values()) { 178 icon.setCallback(null); 179 } 180 mIcons.clear(); 181 182 for (SoftReference<Drawable> icon : mCustomIcons.values()) { 183 final Drawable drawable = icon.get(); 184 if (drawable != null) { 185 drawable.setCallback(null); 186 } 187 } 188 mCustomIcons.clear(); 189 190 final Cursor cursor = getCursor(); 191 if (cursor != null) { 192 try { 193 cursor.close(); 194 } finally { 195 mLauncher.stopManagingCursor(cursor); 196 } 197 } 198 } 199 200 static class ViewHolder { 201 TextView name; 202 TextView description; 203 ImageView icon; 204 205 Intent intent; 206 long id; 207 boolean useBaseIntent; 208 209 int idIndex; 210 int nameIndex; 211 int descriptionIndex = -1; 212 int intentIndex = -1; 213 int iconBitmapIndex = -1; 214 int iconResourceIndex = -1; 215 int iconPackageIndex = -1; 216 } 217 } 218