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.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 public Intent intent; 131 } 132 133 private class ViewHolder { 134 TextView title; 135 ImageView thumbnail; 136 } 137 138 private class LiveWallpaperEnumerator extends 139 AsyncTask<List<ResolveInfo>, LiveWallpaperInfo, Void> { 140 private Context mContext; 141 private int mWallpaperPosition; 142 143 public LiveWallpaperEnumerator(Context context) { 144 super(); 145 mContext = context; 146 mWallpaperPosition = 0; 147 } 148 149 @Override 150 protected Void doInBackground(List<ResolveInfo>... params) { 151 final PackageManager packageManager = mContext.getPackageManager(); 152 153 List<ResolveInfo> list = params[0]; 154 155 final Resources res = mContext.getResources(); 156 BitmapDrawable galleryIcon = (BitmapDrawable) res.getDrawable( 157 R.drawable.livewallpaper_placeholder); 158 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG); 159 paint.setTextAlign(Paint.Align.CENTER); 160 Canvas canvas = new Canvas(); 161 162 Collections.sort(list, new Comparator<ResolveInfo>() { 163 final Collator mCollator; 164 165 { 166 mCollator = Collator.getInstance(); 167 } 168 169 public int compare(ResolveInfo info1, ResolveInfo info2) { 170 return mCollator.compare(info1.loadLabel(packageManager), 171 info2.loadLabel(packageManager)); 172 } 173 }); 174 175 for (ResolveInfo resolveInfo : list) { 176 WallpaperInfo info = null; 177 try { 178 info = new WallpaperInfo(mContext, resolveInfo); 179 } catch (XmlPullParserException e) { 180 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 181 continue; 182 } catch (IOException e) { 183 Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e); 184 continue; 185 } 186 187 LiveWallpaperInfo wallpaper = new LiveWallpaperInfo(); 188 wallpaper.intent = new Intent(WallpaperService.SERVICE_INTERFACE); 189 wallpaper.intent.setClassName(info.getPackageName(), info.getServiceName()); 190 wallpaper.info = info; 191 192 Drawable thumb = info.loadThumbnail(packageManager); 193 if (thumb == null) { 194 int thumbWidth = res.getDimensionPixelSize( 195 R.dimen.live_wallpaper_thumbnail_width); 196 int thumbHeight = res.getDimensionPixelSize( 197 R.dimen.live_wallpaper_thumbnail_height); 198 199 Bitmap thumbnail = Bitmap.createBitmap(thumbWidth, thumbHeight, 200 Bitmap.Config.ARGB_8888); 201 202 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_background)); 203 canvas.setBitmap(thumbnail); 204 canvas.drawPaint(paint); 205 206 galleryIcon.setBounds(0, 0, thumbWidth, thumbHeight); 207 galleryIcon.setGravity(Gravity.CENTER); 208 galleryIcon.draw(canvas); 209 210 String title = info.loadLabel(packageManager).toString(); 211 212 paint.setColor(res.getColor(R.color.live_wallpaper_thumbnail_text_color)); 213 paint.setTextSize( 214 res.getDimensionPixelSize(R.dimen.live_wallpaper_thumbnail_text_size)); 215 216 canvas.drawText(title, (int) (thumbWidth * 0.5), 217 thumbHeight - res.getDimensionPixelSize( 218 R.dimen.live_wallpaper_thumbnail_text_offset), paint); 219 220 thumb = new BitmapDrawable(res, thumbnail); 221 } 222 wallpaper.thumbnail = thumb; 223 publishProgress(wallpaper); 224 } 225 226 return null; 227 } 228 229 @Override 230 protected void onProgressUpdate(LiveWallpaperInfo...infos) { 231 for (LiveWallpaperInfo info : infos) { 232 info.thumbnail.setDither(true); 233 if (mWallpaperPosition < mWallpapers.size()) { 234 mWallpapers.set(mWallpaperPosition, info); 235 } else { 236 mWallpapers.add(info); 237 } 238 mWallpaperPosition++; 239 LiveWallpaperListAdapter.this.notifyDataSetChanged(); 240 } 241 } 242 } 243} 244