1 /* 2 * Copyright (C) 2010 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.wallpaper.livepicker; 18 19 import android.app.WallpaperInfo; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 import android.content.res.Resources; 25 import android.graphics.Bitmap; 26 import android.graphics.Canvas; 27 import android.graphics.Paint; 28 import android.graphics.drawable.BitmapDrawable; 29 import android.graphics.drawable.Drawable; 30 import android.os.AsyncTask; 31 import android.service.wallpaper.WallpaperService; 32 import android.text.Html; 33 import android.util.Log; 34 import android.view.Gravity; 35 import android.view.LayoutInflater; 36 import android.view.View; 37 import android.view.ViewGroup; 38 import android.widget.BaseAdapter; 39 import android.widget.ImageView; 40 import android.widget.ListAdapter; 41 import android.widget.TextView; 42 43 import org.xmlpull.v1.XmlPullParserException; 44 45 import java.io.IOException; 46 import java.text.Collator; 47 import java.util.ArrayList; 48 import java.util.Collections; 49 import java.util.Comparator; 50 import java.util.List; 51 52 public class LiveWallpaperListAdapter extends BaseAdapter implements ListAdapter { 53 private static final String LOG_TAG = "LiveWallpaperListAdapter"; 54 55 private final LayoutInflater mInflater; 56 private final PackageManager mPackageManager; 57 58 private List<LiveWallpaperInfo> mWallpapers; 59 60 @SuppressWarnings("unchecked") 61 public LiveWallpaperListAdapter(Context context) { 62 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 63 mPackageManager = context.getPackageManager(); 64 65 List<ResolveInfo> list = mPackageManager.queryIntentServices( 66 new Intent(WallpaperService.SERVICE_INTERFACE), 67 PackageManager.GET_META_DATA); 68 69 mWallpapers = generatePlaceholderViews(list.size()); 70 71 new LiveWallpaperEnumerator(context).execute(list); 72 } 73 74 private List<LiveWallpaperInfo> generatePlaceholderViews(int amount) { 75 ArrayList<LiveWallpaperInfo> list = new ArrayList<LiveWallpaperInfo>(amount); 76 for (int i = 0; i < amount; i++) { 77 LiveWallpaperInfo info = new LiveWallpaperInfo(); 78 list.add(info); 79 } 80 return list; 81 } 82 83 public int getCount() { 84 if (mWallpapers == null) { 85 return 0; 86 } 87 return mWallpapers.size(); 88 } 89 90 public Object getItem(int position) { 91 return mWallpapers.get(position); 92 } 93 94 public long getItemId(int position) { 95 return position; 96 } 97 98 public View getView(int position, View convertView, ViewGroup parent) { 99 ViewHolder holder; 100 if (convertView == null) { 101 convertView = mInflater.inflate(R.layout.live_wallpaper_entry, parent, false); 102 103 holder = new ViewHolder(); 104 holder.title = (TextView) convertView.findViewById(R.id.title); 105 holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail); 106 convertView.setTag(holder); 107 } else { 108 holder = (ViewHolder) convertView.getTag(); 109 } 110 111 LiveWallpaperInfo wallpaperInfo = mWallpapers.get(position); 112 if (holder.thumbnail != null) { 113 holder.thumbnail.setImageDrawable(wallpaperInfo.thumbnail); 114 } 115 116 if (holder.title != null && wallpaperInfo.info != null) { 117 holder.title.setText(wallpaperInfo.info.loadLabel(mPackageManager)); 118 if (holder.thumbnail == null) { 119 holder.title.setCompoundDrawablesWithIntrinsicBounds(null, wallpaperInfo.thumbnail, 120 null, null); 121 } 122 } 123 124 return convertView; 125 } 126 127 public class LiveWallpaperInfo { 128 public Drawable thumbnail; 129 public WallpaperInfo info; 130 } 131 132 private class ViewHolder { 133 TextView title; 134 ImageView thumbnail; 135 } 136 137 private class LiveWallpaperEnumerator extends 138 AsyncTask<List<ResolveInfo>, LiveWallpaperInfo, Void> { 139 private Context mContext; 140 private int mWallpaperPosition; 141 142 public LiveWallpaperEnumerator(Context context) { 143 super(); 144 mContext = context; 145 mWallpaperPosition = 0; 146 } 147 148 @Override 149 protected Void doInBackground(List<ResolveInfo>... params) { 150 final PackageManager packageManager = mContext.getPackageManager(); 151 152 List<ResolveInfo> list = params[0]; 153 154 final Resources res = mContext.getResources(); 155 BitmapDrawable galleryIcon = (BitmapDrawable) res.getDrawable( 156 R.drawable.livewallpaper_placeholder); 157 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 158 paint.setTextAlign(Paint.Align.CENTER); 159 Canvas canvas = new Canvas(); 160 161 Collections.sort(list, new Comparator<ResolveInfo>() { 162 final Collator mCollator; 163 164 { 165 mCollator = Collator.getInstance(); 166 } 167 168 public int compare(ResolveInfo info1, ResolveInfo info2) { 169 return mCollator.compare(info1.loadLabel(packageManager), 170 info2.loadLabel(packageManager)); 171 } 172 }); 173 174 for (ResolveInfo resolveInfo : list) { 175 WallpaperInfo info = null; 176 try { 177 info = new WallpaperInfo(mContext, resolveInfo); 178 } catch (XmlPullParserException e) { 179 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 180 continue; 181 } catch (IOException e) { 182 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 183 continue; 184 } 185 186 LiveWallpaperInfo wallpaper = new LiveWallpaperInfo(); 187 wallpaper.info = info; 188 189 Drawable thumb = info.loadThumbnail(packageManager); 190 if (thumb == null) { 191 int thumbWidth = res.getDimensionPixelSize( 192 R.dimen.live_wallpaper_thumbnail_width); 193 int thumbHeight = res.getDimensionPixelSize( 194 R.dimen.live_wallpaper_thumbnail_height); 195 196 Bitmap thumbnail = Bitmap.createBitmap(thumbWidth, thumbHeight, 197 Bitmap.Config.ARGB_8888); 198 199 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_background)); 200 canvas.setBitmap(thumbnail); 201 canvas.drawPaint(paint); 202 203 galleryIcon.setBounds(0, 0, thumbWidth, thumbHeight); 204 galleryIcon.setGravity(Gravity.CENTER); 205 galleryIcon.draw(canvas); 206 207 String title = info.loadLabel(packageManager).toString(); 208 209 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_text_color)); 210 paint.setTextSize( 211 res.getDimensionPixelSize(R.dimen.live_wallpaper_thumbnail_text_size)); 212 213 canvas.drawText(title, (int) (thumbWidth * 0.5), 214 thumbHeight - res.getDimensionPixelSize( 215 R.dimen.live_wallpaper_thumbnail_text_offset), paint); 216 217 thumb = new BitmapDrawable(res, thumbnail); 218 } 219 wallpaper.thumbnail = thumb; 220 publishProgress(wallpaper); 221 } 222 223 return null; 224 } 225 226 @Override 227 protected void onProgressUpdate(LiveWallpaperInfo...infos) { 228 for (LiveWallpaperInfo info : infos) { 229 info.thumbnail.setDither(true); 230 if (mWallpaperPosition < mWallpapers.size()) { 231 mWallpapers.set(mWallpaperPosition, info); 232 } else { 233 mWallpapers.add(info); 234 } 235 mWallpaperPosition++; 236 LiveWallpaperListAdapter.this.notifyDataSetChanged(); 237 } 238 } 239 } 240 } 241