|  | /* | 
|  | * Copyright (C) 2008 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | package com.android.launcher; | 
|  |  | 
|  | import android.widget.CursorAdapter; | 
|  | import android.widget.TextView; | 
|  | import android.widget.ImageView; | 
|  | import android.content.Context; | 
|  | import android.content.Intent; | 
|  | import android.content.res.Resources; | 
|  | import android.content.pm.PackageManager; | 
|  | import android.view.View; | 
|  | import android.view.ViewGroup; | 
|  | import android.view.LayoutInflater; | 
|  | import android.database.Cursor; | 
|  | import android.provider.LiveFolders; | 
|  | import android.graphics.drawable.Drawable; | 
|  | import android.graphics.BitmapFactory; | 
|  | import android.graphics.Bitmap; | 
|  |  | 
|  | import java.net.URISyntaxException; | 
|  | import java.util.HashMap; | 
|  | import java.lang.ref.SoftReference; | 
|  |  | 
|  | class LiveFolderAdapter extends CursorAdapter { | 
|  | private boolean mIsList; | 
|  | private LayoutInflater mInflater; | 
|  |  | 
|  | private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>(); | 
|  | private final HashMap<Long, SoftReference<Drawable>> mCustomIcons = | 
|  | new HashMap<Long, SoftReference<Drawable>>(); | 
|  | private final Launcher mLauncher; | 
|  |  | 
|  | LiveFolderAdapter(Launcher launcher, LiveFolderInfo info, Cursor cursor) { | 
|  | super(launcher, cursor, true); | 
|  | mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST; | 
|  | mInflater = LayoutInflater.from(launcher); | 
|  | mLauncher = launcher; | 
|  |  | 
|  | mLauncher.startManagingCursor(getCursor()); | 
|  | } | 
|  |  | 
|  | static Cursor query(Context context, LiveFolderInfo info) { | 
|  | return context.getContentResolver().query(info.uri, null, null, | 
|  | null, LiveFolders.NAME + " ASC"); | 
|  | } | 
|  |  | 
|  | public View newView(Context context, Cursor cursor, ViewGroup parent) { | 
|  | View view; | 
|  | final ViewHolder holder = new ViewHolder(); | 
|  |  | 
|  | if (!mIsList) { | 
|  | view = mInflater.inflate(R.layout.application_boxed, parent, false); | 
|  | } else { | 
|  | view = mInflater.inflate(R.layout.application_list, parent, false); | 
|  | holder.description = (TextView) view.findViewById(R.id.description); | 
|  | holder.icon = (ImageView) view.findViewById(R.id.icon); | 
|  | } | 
|  |  | 
|  | holder.name = (TextView) view.findViewById(R.id.name); | 
|  |  | 
|  | holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID); | 
|  | holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME); | 
|  | holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION); | 
|  | holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT); | 
|  | holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP); | 
|  | holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE); | 
|  | holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE); | 
|  |  | 
|  | view.setTag(holder); | 
|  |  | 
|  | return view; | 
|  | } | 
|  |  | 
|  | public void bindView(View view, Context context, Cursor cursor) { | 
|  | final ViewHolder holder = (ViewHolder) view.getTag(); | 
|  |  | 
|  | holder.id = cursor.getLong(holder.idIndex); | 
|  | final Drawable icon = loadIcon(context, cursor, holder); | 
|  |  | 
|  | holder.name.setText(cursor.getString(holder.nameIndex)); | 
|  |  | 
|  | if (!mIsList) { | 
|  | holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null); | 
|  | } else { | 
|  | final boolean hasIcon = icon != null; | 
|  | holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE); | 
|  | if (hasIcon) holder.icon.setImageDrawable(icon); | 
|  |  | 
|  | if (holder.descriptionIndex != -1) { | 
|  | final String description = cursor.getString(holder.descriptionIndex); | 
|  | if (description != null) { | 
|  | holder.description.setText(description); | 
|  | holder.description.setVisibility(View.VISIBLE); | 
|  | } else { | 
|  | holder.description.setVisibility(View.GONE); | 
|  | } | 
|  | } else { | 
|  | holder.description.setVisibility(View.GONE); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (holder.intentIndex != -1) { | 
|  | try { | 
|  | holder.intent = Intent.parseUri(cursor.getString(holder.intentIndex), 0); | 
|  | } catch (URISyntaxException e) { | 
|  | // Ignore | 
|  | } | 
|  | } else { | 
|  | holder.useBaseIntent = true; | 
|  | } | 
|  | } | 
|  |  | 
|  | private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) { | 
|  | Drawable icon = null; | 
|  | byte[] data = null; | 
|  |  | 
|  | if (holder.iconBitmapIndex != -1) { | 
|  | data = cursor.getBlob(holder.iconBitmapIndex); | 
|  | } | 
|  |  | 
|  | if (data != null) { | 
|  | final SoftReference<Drawable> reference = mCustomIcons.get(holder.id); | 
|  | if (reference != null) { | 
|  | icon = reference.get(); | 
|  | } | 
|  |  | 
|  | if (icon == null) { | 
|  | final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); | 
|  | icon = new FastBitmapDrawable(Utilities.createBitmapThumbnail(bitmap, mContext)); | 
|  | mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon)); | 
|  | } | 
|  | } else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) { | 
|  | final String resource = cursor.getString(holder.iconResourceIndex); | 
|  | icon = mIcons.get(resource); | 
|  | if (icon == null) { | 
|  | try { | 
|  | final PackageManager packageManager = context.getPackageManager(); | 
|  | Resources resources = packageManager.getResourcesForApplication( | 
|  | cursor.getString(holder.iconPackageIndex)); | 
|  | final int id = resources.getIdentifier(resource, | 
|  | null, null); | 
|  | icon = Utilities.createIconThumbnail(resources.getDrawable(id), mContext); | 
|  | mIcons.put(resource, icon); | 
|  | } catch (Exception e) { | 
|  | // Ignore | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return icon; | 
|  | } | 
|  |  | 
|  | void cleanup() { | 
|  | for (Drawable icon : mIcons.values()) { | 
|  | icon.setCallback(null); | 
|  | } | 
|  | mIcons.clear(); | 
|  |  | 
|  | for (SoftReference<Drawable> icon : mCustomIcons.values()) { | 
|  | final Drawable drawable = icon.get(); | 
|  | if (drawable != null) { | 
|  | drawable.setCallback(null); | 
|  | } | 
|  | } | 
|  | mCustomIcons.clear(); | 
|  |  | 
|  | final Cursor cursor = getCursor(); | 
|  | if (cursor != null) { | 
|  | try { | 
|  | cursor.close(); | 
|  | } finally { | 
|  | mLauncher.stopManagingCursor(cursor); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | static class ViewHolder { | 
|  | TextView name; | 
|  | TextView description; | 
|  | ImageView icon; | 
|  |  | 
|  | Intent intent; | 
|  | long id; | 
|  | boolean useBaseIntent; | 
|  |  | 
|  | int idIndex; | 
|  | int nameIndex; | 
|  | int descriptionIndex = -1; | 
|  | int intentIndex = -1; | 
|  | int iconBitmapIndex = -1; | 
|  | int iconResourceIndex = -1; | 
|  | int iconPackageIndex = -1; | 
|  | } | 
|  | } |