blob: fc61af8402e7703d750a07282b297a541ddce2d6 [file] [log] [blame]
Romain Guy41669fc2009-08-13 12:53:24 -07001/*
2 * Copyright (C) 2009 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.launcher2;
18
Dianne Hackborn83a5d382009-09-15 18:50:10 -070019import org.xmlpull.v1.XmlPullParserException;
20
Daniel Sandler86aea352009-09-11 15:59:22 -040021import android.app.Activity;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070022import android.app.ListActivity;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070023import android.app.WallpaperInfo;
Romain Guy41669fc2009-08-13 12:53:24 -070024import android.app.WallpaperManager;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070025import android.content.ComponentName;
26import android.content.Context;
Romain Guy41669fc2009-08-13 12:53:24 -070027import android.content.DialogInterface;
28import android.content.Intent;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070029import android.content.ServiceConnection;
Daniel Sandler86aea352009-09-11 15:59:22 -040030import android.content.pm.ComponentInfo;
Romain Guy41669fc2009-08-13 12:53:24 -070031import android.content.pm.PackageManager;
32import android.content.pm.ResolveInfo;
33import android.content.pm.ServiceInfo;
34import android.graphics.drawable.Drawable;
Daniel Sandler8f141b42009-09-11 15:59:22 -040035import android.graphics.drawable.BitmapDrawable;
Daniel Sandler86aea352009-09-11 15:59:22 -040036import android.graphics.Bitmap;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070037import android.os.Binder;
Romain Guy41669fc2009-08-13 12:53:24 -070038import android.os.Bundle;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070039import android.os.IBinder;
40import android.os.ParcelFileDescriptor;
Romain Guy41669fc2009-08-13 12:53:24 -070041import android.os.RemoteException;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070042import android.os.SystemClock;
43import android.service.wallpaper.IWallpaperConnection;
44import android.service.wallpaper.IWallpaperEngine;
45import android.service.wallpaper.IWallpaperService;
Romain Guy41669fc2009-08-13 12:53:24 -070046import android.service.wallpaper.WallpaperService;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070047import android.service.wallpaper.WallpaperSettingsActivity;
Daniel Sandler8f141b42009-09-11 15:59:22 -040048import android.util.DisplayMetrics;
Romain Guy41669fc2009-08-13 12:53:24 -070049import android.util.Log;
Daniel Sandler86aea352009-09-11 15:59:22 -040050import android.view.LayoutInflater;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070051import android.view.View;
Daniel Sandler86aea352009-09-11 15:59:22 -040052import android.view.ViewGroup;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070053import android.view.WindowManager;
Daniel Sandler86aea352009-09-11 15:59:22 -040054import android.widget.AdapterView;
55import android.widget.BaseAdapter;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070056import android.widget.Button;
Daniel Sandler86aea352009-09-11 15:59:22 -040057import android.widget.Gallery;
58import android.widget.ImageView;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070059import android.widget.ListView;
Romain Guy41669fc2009-08-13 12:53:24 -070060
Dianne Hackborn83a5d382009-09-15 18:50:10 -070061import java.io.IOException;
Romain Guy41669fc2009-08-13 12:53:24 -070062import java.text.Collator;
63import java.util.List;
64import java.util.ArrayList;
65import java.util.Collections;
66import java.util.Comparator;
67
68/**
69 * Displays a list of live wallpapers, allowing the user to select one
70 * and make it the system global wallpaper.
71 */
Daniel Sandler86aea352009-09-11 15:59:22 -040072public class LiveWallpaperPickActivity
73 extends Activity
74 implements AdapterView.OnItemSelectedListener,
75 View.OnClickListener
76{
Romain Guy41669fc2009-08-13 12:53:24 -070077 private static final String TAG = "LiveWallpaperPickActivity";
78
79 private PackageManager mPackageManager;
80 private WallpaperManager mWallpaperManager;
81
Dianne Hackborn02e638e2009-08-20 19:33:42 -070082 Intent mSelectedIntent;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070083 WallpaperInfo mSelectedInfo;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070084 WallpaperConnection mWallpaperConnection;
Daniel Sandler86aea352009-09-11 15:59:22 -040085
86 private Gallery mGallery;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070087 private Button mConfigureButton;
88
Daniel Sandler86aea352009-09-11 15:59:22 -040089 private ArrayList<Intent> mWallpaperIntents;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070090 private ArrayList<WallpaperInfo> mWallpaperInfos;
Daniel Sandler86aea352009-09-11 15:59:22 -040091
Daniel Sandler8f141b42009-09-11 15:59:22 -040092 private ArrayList<Drawable> mThumbnails;
Daniel Sandler86aea352009-09-11 15:59:22 -040093
Dianne Hackborn02e638e2009-08-20 19:33:42 -070094 class WallpaperConnection extends IWallpaperConnection.Stub
95 implements ServiceConnection {
96 final Intent mIntent;
97 IWallpaperService mService;
98 IWallpaperEngine mEngine;
99 boolean mConnected;
100
101 public WallpaperConnection(Intent intent) {
102 mIntent = intent;
103 }
104
105 public boolean connect() {
106 synchronized (this) {
107 if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) {
108 return false;
109 }
110
111 mConnected = true;
112 return true;
113 }
114 }
115
116 public void disconnect() {
117 synchronized (this) {
118 mConnected = false;
119 if (mEngine != null) {
120 try {
121 mEngine.destroy();
122 } catch (RemoteException e) {
123 }
124 mEngine = null;
125 }
126 unbindService(this);
127 mService = null;
128 }
129 }
130
131 public void onServiceConnected(ComponentName name, IBinder service) {
132 if (mWallpaperConnection == this) {
133 mService = IWallpaperService.Stub.asInterface(service);
134 try {
135 View button = findViewById(R.id.set);
136 mService.attach(this, button.getWindowToken(),
137 WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA,
138 true,
139 button.getRootView().getWidth(),
140 button.getRootView().getHeight());
141 } catch (RemoteException e) {
142 Log.w(TAG, "Failed attaching wallpaper; clearing", e);
143 }
144 }
145 }
146
147 public void onServiceDisconnected(ComponentName name) {
148 mService = null;
149 mEngine = null;
150 if (mWallpaperConnection == this) {
151 Log.w(TAG, "Wallpaper service gone: " + name);
152 }
153 }
154
155 public void attachEngine(IWallpaperEngine engine) {
156 synchronized (this) {
157 if (mConnected) {
158 mEngine = engine;
Dianne Hackborn5237ccb2009-08-29 19:17:48 -0700159 try {
160 engine.setVisibility(true);
161 } catch (RemoteException e) {
162 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700163 } else {
164 try {
165 engine.destroy();
166 } catch (RemoteException e) {
167 }
168 }
169 }
170 }
171
172 public ParcelFileDescriptor setWallpaper(String name) {
173 return null;
174 }
175 }
Daniel Sandler86aea352009-09-11 15:59:22 -0400176
177 private class ImageAdapter extends BaseAdapter {
178 private LayoutInflater mLayoutInflater;
179
180 ImageAdapter(LiveWallpaperPickActivity context) {
181 mLayoutInflater = context.getLayoutInflater();
182 }
183
184 public int getCount() {
Daniel Sandler8f141b42009-09-11 15:59:22 -0400185 return mThumbnails.size();
Daniel Sandler86aea352009-09-11 15:59:22 -0400186 }
187
188 public Object getItem(int position) {
189 return position;
190 }
191
192 public long getItemId(int position) {
193 return position;
194 }
195
196 public View getView(int position, View convertView, ViewGroup parent) {
197 ImageView image;
198
199 if (convertView == null) {
200 image = (ImageView) mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
201 } else {
202 image = (ImageView) convertView;
203 }
204
Daniel Sandler8f141b42009-09-11 15:59:22 -0400205 image.setImageDrawable(mThumbnails.get(position));
Daniel Sandler86aea352009-09-11 15:59:22 -0400206 image.getDrawable().setDither(true);
Daniel Sandler8f141b42009-09-11 15:59:22 -0400207
208 image.setAdjustViewBounds(true);
209 image.setScaleType(ImageView.ScaleType.FIT_CENTER);
210 image.setLayoutParams(new Gallery.LayoutParams(
211 ViewGroup.LayoutParams.WRAP_CONTENT,
212 ViewGroup.LayoutParams.FILL_PARENT));
213
Daniel Sandler86aea352009-09-11 15:59:22 -0400214 return image;
215 }
216 }
217
218
219 private void findLiveWallpapers() {
Daniel Sandler8f141b42009-09-11 15:59:22 -0400220 mThumbnails = new ArrayList<Drawable>(24);
Daniel Sandler86aea352009-09-11 15:59:22 -0400221 List<ResolveInfo> list =
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700222 mPackageManager.queryIntentServices(getTargetIntent(),
223 PackageManager.GET_META_DATA);
Daniel Sandler86aea352009-09-11 15:59:22 -0400224
225 mWallpaperIntents = new ArrayList<Intent>(list.size());
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700226 mWallpaperInfos = new ArrayList<WallpaperInfo>(list.size());
Daniel Sandler86aea352009-09-11 15:59:22 -0400227
228 int listSize = list.size();
Daniel Sandler8f141b42009-09-11 15:59:22 -0400229 DisplayMetrics metrics = new DisplayMetrics();
230 getWindowManager().getDefaultDisplay().getMetrics(metrics);
231
Daniel Sandler86aea352009-09-11 15:59:22 -0400232 for (int i = 0; i < listSize; i++) {
233 ResolveInfo resolveInfo = list.get(i);
234 ComponentInfo ci = resolveInfo.serviceInfo;
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700235 WallpaperInfo winfo;
236 try {
237 winfo = new WallpaperInfo(this, resolveInfo);
238 } catch (XmlPullParserException e) {
239 Log.w(TAG, "Skipping wallpaper " + ci, e);
240 continue;
241 } catch (IOException e) {
242 Log.w(TAG, "Skipping wallpaper " + ci, e);
243 continue;
244 }
Daniel Sandler8f141b42009-09-11 15:59:22 -0400245
246 String packageName = winfo.getPackageName();
247 String className = winfo.getServiceName();
Daniel Sandler86aea352009-09-11 15:59:22 -0400248 Intent intent = new Intent(getTargetIntent());
249 intent.setClassName(packageName, className);
250 mWallpaperIntents.add(intent);
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700251 mWallpaperInfos.add(winfo);
Daniel Sandler86aea352009-09-11 15:59:22 -0400252
Daniel Sandler8f141b42009-09-11 15:59:22 -0400253 Drawable thumb = winfo.loadThumbnail(mPackageManager);
254 if (null == thumb) {
255 // TODO dsandler: replace with pretty placeholder
256 Bitmap thumbBit = Bitmap.createBitmap(
257 (int)(240 * metrics.density),
258 (int)(240 * metrics.density),
259 Bitmap.Config.ARGB_8888);
260 android.graphics.Canvas can = new android.graphics.Canvas(thumbBit);
261 android.graphics.Paint pt = new android.graphics.Paint(android.graphics.Paint.ANTI_ALIAS_FLAG|android.graphics.Paint.DITHER_FLAG);
262 pt.setARGB(255, 0, 0, 255);
263 can.drawPaint(pt);
264 pt.setARGB(255, 255, 255, 255);
265 pt.setTextSize(12 * metrics.density);
266 can.drawText(className,
267 (int)(12 * metrics.density),
268 (int)(thumbBit.getHeight()-12 * metrics.density),
269 pt);
270 pt.setTextSize(100 * metrics.density);
271 can.drawText(String.format("#%d", i),
272 (int)(thumbBit.getWidth()*0.3),
273 (int)(thumbBit.getHeight()*0.5),
274 pt);
275 thumb = new BitmapDrawable(thumbBit);
276 }
277 mThumbnails.add(thumb);
Daniel Sandler86aea352009-09-11 15:59:22 -0400278 }
279
280
281 }
282
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700283
Romain Guy41669fc2009-08-13 12:53:24 -0700284 @Override
285 public void onCreate(Bundle icicle) {
Daniel Sandler86aea352009-09-11 15:59:22 -0400286 super.onCreate(icicle);
287
Romain Guy41669fc2009-08-13 12:53:24 -0700288 mPackageManager = getPackageManager();
289 mWallpaperManager = WallpaperManager.getInstance(this);
290
Daniel Sandler86aea352009-09-11 15:59:22 -0400291 findLiveWallpapers();
292
293 setContentView(R.layout.live_wallpaper_content);
Romain Guy41669fc2009-08-13 12:53:24 -0700294
Daniel Sandler86aea352009-09-11 15:59:22 -0400295 mGallery = (Gallery) findViewById(R.id.gallery);
296 mGallery.setAdapter(new ImageAdapter(this));
297 mGallery.setOnItemSelectedListener(this);
298 mGallery.setCallbackDuringFling(false);
299
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700300 View button = findViewById(R.id.set);
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700301 button.setOnClickListener(this);
302
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700303 mConfigureButton = (Button)findViewById(R.id.configure);
304 mConfigureButton.setEnabled(false);
305 mConfigureButton.setOnClickListener(this);
306
Romain Guy41669fc2009-08-13 12:53:24 -0700307 // Set default return data
308 setResult(RESULT_CANCELED);
309 }
310
Romain Guy41669fc2009-08-13 12:53:24 -0700311 @Override
Dianne Hackborn5237ccb2009-08-29 19:17:48 -0700312 public void onResume() {
313 super.onResume();
314 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) {
315 try {
316 mWallpaperConnection.mEngine.setVisibility(true);
317 } catch (RemoteException e) {
318 }
319 }
320 }
321
322 @Override
323 public void onPause() {
324 super.onPause();
325 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) {
326 try {
327 mWallpaperConnection.mEngine.setVisibility(false);
328 } catch (RemoteException e) {
329 }
330 }
331 }
332
333 @Override
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700334 public void onDetachedFromWindow() {
335 super.onDetachedFromWindow();
336 if (mWallpaperConnection != null) {
337 mWallpaperConnection.disconnect();
Romain Guy41669fc2009-08-13 12:53:24 -0700338 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700339 mWallpaperConnection = null;
Romain Guy41669fc2009-08-13 12:53:24 -0700340 }
341
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700342 protected Intent getTargetIntent() {
343 return new Intent(WallpaperService.SERVICE_INTERFACE);
344 }
345
Daniel Sandler86aea352009-09-11 15:59:22 -0400346 public void onItemSelected(AdapterView parent, View v, int position, long id) {
Daniel Sandler86aea352009-09-11 15:59:22 -0400347 mSelectedIntent = mWallpaperIntents.get(position);
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700348 mSelectedInfo = mWallpaperInfos.get(position);
349 mConfigureButton.setEnabled(mSelectedInfo != null
350 && mSelectedInfo.getSettingsActivity() != null);
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700351 findViewById(R.id.set).setEnabled(true);
352
353 WallpaperConnection conn = new WallpaperConnection(mSelectedIntent);
354 if (conn.connect()) {
355 if (mWallpaperConnection != null) {
356 mWallpaperConnection.disconnect();
357 }
358 mWallpaperConnection = conn;
359 }
360 }
361
Daniel Sandler86aea352009-09-11 15:59:22 -0400362 public void onClick(View v) { // "Set" button
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700363 if (v.getId() == R.id.set) {
364 if (mSelectedIntent != null) {
365 try {
366 mWallpaperManager.getIWallpaperManager().setWallpaperComponent(
367 mSelectedIntent.getComponent());
368 this.setResult(RESULT_OK);
369 } catch (RemoteException e) {
370 // do nothing
371 } catch (RuntimeException e) {
372 Log.w(TAG, "Failure setting wallpaper", e);
373 }
374 finish();
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700375 }
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700376 } else if (v.getId() == R.id.configure) {
377 if (mSelectedInfo != null && mSelectedInfo.getSettingsActivity() != null) {
378 Intent intent = new Intent();
379 intent.setComponent(new ComponentName(mSelectedInfo.getPackageName(),
380 mSelectedInfo.getSettingsActivity()));
381 intent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true);
382 startActivity(intent);
383 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700384 }
Romain Guy41669fc2009-08-13 12:53:24 -0700385 }
Daniel Sandler86aea352009-09-11 15:59:22 -0400386
387 public void onNothingSelected(AdapterView parent) {
388 }
389
Romain Guy41669fc2009-08-13 12:53:24 -0700390}