Home | History | Annotate | Download | only in launcher2
      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