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 17package com.android.wallpaper.livepicker; 18 19import android.app.WallpaperInfo; 20import android.content.Context; 21import android.content.Intent; 22import android.content.pm.PackageManager; 23import android.content.pm.ResolveInfo; 24import android.content.res.Resources; 25import android.graphics.Bitmap; 26import android.graphics.Canvas; 27import android.graphics.Paint; 28import android.graphics.drawable.BitmapDrawable; 29import android.graphics.drawable.Drawable; 30import android.os.AsyncTask; 31import android.service.wallpaper.WallpaperService; 32import android.text.Html; 33import android.util.Log; 34import android.view.Gravity; 35import android.view.LayoutInflater; 36import android.view.View; 37import android.view.ViewGroup; 38import android.widget.BaseAdapter; 39import android.widget.ImageView; 40import android.widget.ListAdapter; 41import android.widget.TextView; 42 43import org.xmlpull.v1.XmlPullParserException; 44 45import java.io.IOException; 46import java.text.Collator; 47import java.util.ArrayList; 48import java.util.Collections; 49import java.util.Comparator; 50import java.util.List; 51 52public 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.description = (TextView) convertView.findViewById(R.id.description); 106 holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail); 107 convertView.setTag(holder); 108 } else { 109 holder = (ViewHolder) convertView.getTag(); 110 } 111 112 LiveWallpaperInfo wallpaperInfo = mWallpapers.get(position); 113 if (holder.thumbnail != null) { 114 holder.thumbnail.setImageDrawable(wallpaperInfo.thumbnail); 115 } 116 117 if (holder.title != null && wallpaperInfo.info != null) { 118 holder.title.setText(wallpaperInfo.info.loadLabel(mPackageManager)); 119 if (holder.thumbnail == null) { 120 holder.title.setCompoundDrawablesWithIntrinsicBounds(null, wallpaperInfo.thumbnail, 121 null, null); 122 } 123 } 124 125 if (holder.description != null && wallpaperInfo.info != null) { 126 try { 127 holder.description.setVisibility(View.VISIBLE); 128 holder.description.setText(Html.fromHtml( 129 wallpaperInfo.info.loadDescription(mPackageManager).toString())); 130 } catch (Resources.NotFoundException e) { 131 holder.description.setVisibility(View.GONE); 132 } 133 } 134 135 return convertView; 136 } 137 138 public class LiveWallpaperInfo { 139 public Drawable thumbnail; 140 public WallpaperInfo info; 141 public Intent intent; 142 } 143 144 private class ViewHolder { 145 TextView title; 146 TextView description; 147 ImageView thumbnail; 148 } 149 150 private class LiveWallpaperEnumerator extends 151 AsyncTask<List<ResolveInfo>, LiveWallpaperInfo, Void> { 152 private Context mContext; 153 private int mWallpaperPosition; 154 155 public LiveWallpaperEnumerator(Context context) { 156 super(); 157 mContext = context; 158 mWallpaperPosition = 0; 159 } 160 161 @Override 162 protected Void doInBackground(List<ResolveInfo>... params) { 163 final PackageManager packageManager = mContext.getPackageManager(); 164 165 List<ResolveInfo> list = params[0]; 166 167 final Resources res = mContext.getResources(); 168 BitmapDrawable galleryIcon = (BitmapDrawable) res.getDrawable( 169 R.drawable.livewallpaper_placeholder); 170 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 171 paint.setTextAlign(Paint.Align.CENTER); 172 Canvas canvas = new Canvas(); 173 174 Collections.sort(list, new Comparator<ResolveInfo>() { 175 final Collator mCollator; 176 177 { 178 mCollator = Collator.getInstance(); 179 } 180 181 public int compare(ResolveInfo info1, ResolveInfo info2) { 182 return mCollator.compare(info1.loadLabel(packageManager), 183 info2.loadLabel(packageManager)); 184 } 185 }); 186 187 for (ResolveInfo resolveInfo : list) { 188 WallpaperInfo info = null; 189 try { 190 info = new WallpaperInfo(mContext, resolveInfo); 191 } catch (XmlPullParserException e) { 192 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 193 continue; 194 } catch (IOException e) { 195 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 196 continue; 197 } 198 199 LiveWallpaperInfo wallpaper = new LiveWallpaperInfo(); 200 wallpaper.intent = new Intent(WallpaperService.SERVICE_INTERFACE); 201 wallpaper.intent.setClassName(info.getPackageName(), info.getServiceName()); 202 wallpaper.info = info; 203 204 Drawable thumb = info.loadThumbnail(packageManager); 205 if (thumb == null) { 206 int thumbWidth = res.getDimensionPixelSize( 207 R.dimen.live_wallpaper_thumbnail_width); 208 int thumbHeight = res.getDimensionPixelSize( 209 R.dimen.live_wallpaper_thumbnail_height); 210 211 Bitmap thumbnail = Bitmap.createBitmap(thumbWidth, thumbHeight, 212 Bitmap.Config.ARGB_8888); 213 214 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_background)); 215 canvas.setBitmap(thumbnail); 216 canvas.drawPaint(paint); 217 218 galleryIcon.setBounds(0, 0, thumbWidth, thumbHeight); 219 galleryIcon.setGravity(Gravity.CENTER); 220 galleryIcon.draw(canvas); 221 222 String title = info.loadLabel(packageManager).toString(); 223 224 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_text_color)); 225 paint.setTextSize( 226 res.getDimensionPixelSize(R.dimen.live_wallpaper_thumbnail_text_size)); 227 228 canvas.drawText(title, (int) (thumbWidth * 0.5), 229 thumbHeight - res.getDimensionPixelSize( 230 R.dimen.live_wallpaper_thumbnail_text_offset), paint); 231 232 thumb = new BitmapDrawable(res, thumbnail); 233 } 234 wallpaper.thumbnail = thumb; 235 publishProgress(wallpaper); 236 } 237 238 return null; 239 } 240 241 @Override 242 protected void onProgressUpdate(LiveWallpaperInfo...infos) { 243 for (LiveWallpaperInfo info : infos) { 244 info.thumbnail.setDither(true); 245 if (mWallpaperPosition < mWallpapers.size()) { 246 mWallpapers.set(mWallpaperPosition, info); 247 } else { 248 mWallpapers.add(info); 249 } 250 mWallpaperPosition++; 251 LiveWallpaperListAdapter.this.notifyDataSetChanged(); 252 } 253 } 254 } 255} 256