blob: b8d8d54515c075c91a66e35d68a35f99ce25e60c [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;
Daniel Sandler86daa3f2009-09-28 16:03:50 -040037import android.graphics.Canvas;
38import android.graphics.Paint;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070039import android.os.Binder;
Romain Guy41669fc2009-08-13 12:53:24 -070040import android.os.Bundle;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070041import android.os.IBinder;
42import android.os.ParcelFileDescriptor;
Romain Guy41669fc2009-08-13 12:53:24 -070043import android.os.RemoteException;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070044import android.os.SystemClock;
45import android.service.wallpaper.IWallpaperConnection;
46import android.service.wallpaper.IWallpaperEngine;
47import android.service.wallpaper.IWallpaperService;
Romain Guy41669fc2009-08-13 12:53:24 -070048import android.service.wallpaper.WallpaperService;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070049import android.service.wallpaper.WallpaperSettingsActivity;
Daniel Sandler8f141b42009-09-11 15:59:22 -040050import android.util.DisplayMetrics;
Romain Guy41669fc2009-08-13 12:53:24 -070051import android.util.Log;
Daniel Sandler86daa3f2009-09-28 16:03:50 -040052import android.view.Gravity;
Daniel Sandler86aea352009-09-11 15:59:22 -040053import android.view.LayoutInflater;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070054import android.view.View;
Daniel Sandler86aea352009-09-11 15:59:22 -040055import android.view.ViewGroup;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070056import android.view.WindowManager;
Daniel Sandler86aea352009-09-11 15:59:22 -040057import android.widget.AdapterView;
58import android.widget.BaseAdapter;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070059import android.widget.Button;
Daniel Sandler86aea352009-09-11 15:59:22 -040060import android.widget.Gallery;
61import android.widget.ImageView;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070062import android.widget.ListView;
Romain Guy41669fc2009-08-13 12:53:24 -070063
Dianne Hackborn83a5d382009-09-15 18:50:10 -070064import java.io.IOException;
Romain Guy41669fc2009-08-13 12:53:24 -070065import java.text.Collator;
66import java.util.List;
67import java.util.ArrayList;
68import java.util.Collections;
69import java.util.Comparator;
70
71/**
72 * Displays a list of live wallpapers, allowing the user to select one
73 * and make it the system global wallpaper.
74 */
Daniel Sandler86aea352009-09-11 15:59:22 -040075public class LiveWallpaperPickActivity
76 extends Activity
77 implements AdapterView.OnItemSelectedListener,
78 View.OnClickListener
79{
Romain Guy41669fc2009-08-13 12:53:24 -070080 private static final String TAG = "LiveWallpaperPickActivity";
81
82 private PackageManager mPackageManager;
83 private WallpaperManager mWallpaperManager;
84
Dianne Hackborn02e638e2009-08-20 19:33:42 -070085 Intent mSelectedIntent;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070086 WallpaperInfo mSelectedInfo;
Dianne Hackborn02e638e2009-08-20 19:33:42 -070087 WallpaperConnection mWallpaperConnection;
Daniel Sandler86aea352009-09-11 15:59:22 -040088
89 private Gallery mGallery;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070090 private Button mConfigureButton;
91
Daniel Sandler86aea352009-09-11 15:59:22 -040092 private ArrayList<Intent> mWallpaperIntents;
Dianne Hackborn83a5d382009-09-15 18:50:10 -070093 private ArrayList<WallpaperInfo> mWallpaperInfos;
Daniel Sandler86aea352009-09-11 15:59:22 -040094
Daniel Sandler8f141b42009-09-11 15:59:22 -040095 private ArrayList<Drawable> mThumbnails;
Daniel Sandler86aea352009-09-11 15:59:22 -040096
Dianne Hackborn02e638e2009-08-20 19:33:42 -070097 class WallpaperConnection extends IWallpaperConnection.Stub
98 implements ServiceConnection {
99 final Intent mIntent;
100 IWallpaperService mService;
101 IWallpaperEngine mEngine;
102 boolean mConnected;
103
104 public WallpaperConnection(Intent intent) {
105 mIntent = intent;
106 }
107
108 public boolean connect() {
109 synchronized (this) {
110 if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) {
111 return false;
112 }
113
114 mConnected = true;
115 return true;
116 }
117 }
118
119 public void disconnect() {
120 synchronized (this) {
121 mConnected = false;
122 if (mEngine != null) {
123 try {
124 mEngine.destroy();
125 } catch (RemoteException e) {
126 }
127 mEngine = null;
128 }
129 unbindService(this);
130 mService = null;
131 }
132 }
133
134 public void onServiceConnected(ComponentName name, IBinder service) {
135 if (mWallpaperConnection == this) {
136 mService = IWallpaperService.Stub.asInterface(service);
137 try {
138 View button = findViewById(R.id.set);
139 mService.attach(this, button.getWindowToken(),
140 WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA,
141 true,
142 button.getRootView().getWidth(),
143 button.getRootView().getHeight());
144 } catch (RemoteException e) {
145 Log.w(TAG, "Failed attaching wallpaper; clearing", e);
146 }
147 }
148 }
149
150 public void onServiceDisconnected(ComponentName name) {
151 mService = null;
152 mEngine = null;
153 if (mWallpaperConnection == this) {
154 Log.w(TAG, "Wallpaper service gone: " + name);
155 }
156 }
157
158 public void attachEngine(IWallpaperEngine engine) {
159 synchronized (this) {
160 if (mConnected) {
161 mEngine = engine;
Dianne Hackborn5237ccb2009-08-29 19:17:48 -0700162 try {
163 engine.setVisibility(true);
164 } catch (RemoteException e) {
165 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700166 } else {
167 try {
168 engine.destroy();
169 } catch (RemoteException e) {
170 }
171 }
172 }
173 }
174
175 public ParcelFileDescriptor setWallpaper(String name) {
176 return null;
177 }
178 }
Daniel Sandler86aea352009-09-11 15:59:22 -0400179
180 private class ImageAdapter extends BaseAdapter {
181 private LayoutInflater mLayoutInflater;
182
183 ImageAdapter(LiveWallpaperPickActivity context) {
184 mLayoutInflater = context.getLayoutInflater();
185 }
186
187 public int getCount() {
Daniel Sandler8f141b42009-09-11 15:59:22 -0400188 return mThumbnails.size();
Daniel Sandler86aea352009-09-11 15:59:22 -0400189 }
190
191 public Object getItem(int position) {
192 return position;
193 }
194
195 public long getItemId(int position) {
196 return position;
197 }
198
199 public View getView(int position, View convertView, ViewGroup parent) {
200 ImageView image;
201
202 if (convertView == null) {
203 image = (ImageView) mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
204 } else {
205 image = (ImageView) convertView;
206 }
207
Daniel Sandler8f141b42009-09-11 15:59:22 -0400208 image.setImageDrawable(mThumbnails.get(position));
Daniel Sandler86aea352009-09-11 15:59:22 -0400209 image.getDrawable().setDither(true);
Daniel Sandler8f141b42009-09-11 15:59:22 -0400210
211 image.setAdjustViewBounds(true);
212 image.setScaleType(ImageView.ScaleType.FIT_CENTER);
213 image.setLayoutParams(new Gallery.LayoutParams(
214 ViewGroup.LayoutParams.WRAP_CONTENT,
215 ViewGroup.LayoutParams.FILL_PARENT));
216
Daniel Sandler86aea352009-09-11 15:59:22 -0400217 return image;
218 }
219 }
220
221
222 private void findLiveWallpapers() {
Daniel Sandler8f141b42009-09-11 15:59:22 -0400223 mThumbnails = new ArrayList<Drawable>(24);
Daniel Sandler86aea352009-09-11 15:59:22 -0400224 List<ResolveInfo> list =
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700225 mPackageManager.queryIntentServices(getTargetIntent(),
226 PackageManager.GET_META_DATA);
Daniel Sandler86aea352009-09-11 15:59:22 -0400227
228 mWallpaperIntents = new ArrayList<Intent>(list.size());
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700229 mWallpaperInfos = new ArrayList<WallpaperInfo>(list.size());
Daniel Sandler86aea352009-09-11 15:59:22 -0400230
231 int listSize = list.size();
Daniel Sandler8f141b42009-09-11 15:59:22 -0400232 DisplayMetrics metrics = new DisplayMetrics();
233 getWindowManager().getDefaultDisplay().getMetrics(metrics);
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400234
235 Drawable galleryIcon = this.getResources().getDrawable(
236 R.drawable.livewallpaper_placeholder);
237 int galleryIconW = galleryIcon.getIntrinsicWidth();
238 int galleryIconH = galleryIcon.getIntrinsicHeight();
Daniel Sandler8f141b42009-09-11 15:59:22 -0400239
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400240 Paint pt = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG);
241 pt.setTextAlign(Paint.Align.CENTER);
242
Daniel Sandler86aea352009-09-11 15:59:22 -0400243 for (int i = 0; i < listSize; i++) {
244 ResolveInfo resolveInfo = list.get(i);
245 ComponentInfo ci = resolveInfo.serviceInfo;
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700246 WallpaperInfo winfo;
247 try {
248 winfo = new WallpaperInfo(this, resolveInfo);
249 } catch (XmlPullParserException e) {
250 Log.w(TAG, "Skipping wallpaper " + ci, e);
251 continue;
252 } catch (IOException e) {
253 Log.w(TAG, "Skipping wallpaper " + ci, e);
254 continue;
255 }
Daniel Sandler8f141b42009-09-11 15:59:22 -0400256
257 String packageName = winfo.getPackageName();
258 String className = winfo.getServiceName();
Daniel Sandler86aea352009-09-11 15:59:22 -0400259 Intent intent = new Intent(getTargetIntent());
260 intent.setClassName(packageName, className);
261 mWallpaperIntents.add(intent);
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700262 mWallpaperInfos.add(winfo);
Daniel Sandler86aea352009-09-11 15:59:22 -0400263
Daniel Sandler8f141b42009-09-11 15:59:22 -0400264 Drawable thumb = winfo.loadThumbnail(mPackageManager);
265 if (null == thumb) {
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400266 final int thumbWidth = (int)(180 * metrics.density);
267 final int thumbHeight = (int)(160 * metrics.density);
Daniel Sandler8f141b42009-09-11 15:59:22 -0400268 Bitmap thumbBit = Bitmap.createBitmap(
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400269 thumbWidth, thumbHeight,
Daniel Sandler8f141b42009-09-11 15:59:22 -0400270 Bitmap.Config.ARGB_8888);
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400271 Canvas can = new Canvas(thumbBit);
272 pt.setARGB(204,102,102,102);
Daniel Sandler8f141b42009-09-11 15:59:22 -0400273 can.drawPaint(pt);
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400274
275 galleryIcon.setBounds(0,0,thumbWidth,thumbHeight);
276 ((BitmapDrawable)galleryIcon).setGravity(Gravity.CENTER);
277 galleryIcon.draw(can);
278
Daniel Sandler8f141b42009-09-11 15:59:22 -0400279 pt.setARGB(255, 255, 255, 255);
Daniel Sandler86daa3f2009-09-28 16:03:50 -0400280 pt.setTextSize(20 * metrics.density);
281 can.drawText(className.substring(className.lastIndexOf('.')+1),
282 (int)(thumbWidth*0.5),
283 (int)(thumbHeight-22*metrics.density),
Daniel Sandler8f141b42009-09-11 15:59:22 -0400284 pt);
285 thumb = new BitmapDrawable(thumbBit);
286 }
287 mThumbnails.add(thumb);
Daniel Sandler86aea352009-09-11 15:59:22 -0400288 }
289
290
291 }
292
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700293
Romain Guy41669fc2009-08-13 12:53:24 -0700294 @Override
295 public void onCreate(Bundle icicle) {
Daniel Sandler86aea352009-09-11 15:59:22 -0400296 super.onCreate(icicle);
297
Romain Guy41669fc2009-08-13 12:53:24 -0700298 mPackageManager = getPackageManager();
299 mWallpaperManager = WallpaperManager.getInstance(this);
300
Daniel Sandler86aea352009-09-11 15:59:22 -0400301 findLiveWallpapers();
302
303 setContentView(R.layout.live_wallpaper_content);
Romain Guy41669fc2009-08-13 12:53:24 -0700304
Daniel Sandler86aea352009-09-11 15:59:22 -0400305 mGallery = (Gallery) findViewById(R.id.gallery);
306 mGallery.setAdapter(new ImageAdapter(this));
307 mGallery.setOnItemSelectedListener(this);
308 mGallery.setCallbackDuringFling(false);
309
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700310 View button = findViewById(R.id.set);
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700311 button.setOnClickListener(this);
312
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700313 mConfigureButton = (Button)findViewById(R.id.configure);
314 mConfigureButton.setEnabled(false);
315 mConfigureButton.setOnClickListener(this);
316
Romain Guy41669fc2009-08-13 12:53:24 -0700317 // Set default return data
318 setResult(RESULT_CANCELED);
319 }
320
Romain Guy41669fc2009-08-13 12:53:24 -0700321 @Override
Dianne Hackborn5237ccb2009-08-29 19:17:48 -0700322 public void onResume() {
323 super.onResume();
324 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) {
325 try {
326 mWallpaperConnection.mEngine.setVisibility(true);
327 } catch (RemoteException e) {
328 }
329 }
330 }
331
332 @Override
333 public void onPause() {
334 super.onPause();
335 if (mWallpaperConnection != null && mWallpaperConnection.mEngine != null) {
336 try {
337 mWallpaperConnection.mEngine.setVisibility(false);
338 } catch (RemoteException e) {
339 }
340 }
341 }
342
343 @Override
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700344 public void onDetachedFromWindow() {
345 super.onDetachedFromWindow();
346 if (mWallpaperConnection != null) {
347 mWallpaperConnection.disconnect();
Romain Guy41669fc2009-08-13 12:53:24 -0700348 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700349 mWallpaperConnection = null;
Romain Guy41669fc2009-08-13 12:53:24 -0700350 }
351
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700352 protected Intent getTargetIntent() {
353 return new Intent(WallpaperService.SERVICE_INTERFACE);
354 }
355
Daniel Sandler86aea352009-09-11 15:59:22 -0400356 public void onItemSelected(AdapterView parent, View v, int position, long id) {
Daniel Sandler86aea352009-09-11 15:59:22 -0400357 mSelectedIntent = mWallpaperIntents.get(position);
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700358 mSelectedInfo = mWallpaperInfos.get(position);
359 mConfigureButton.setEnabled(mSelectedInfo != null
360 && mSelectedInfo.getSettingsActivity() != null);
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700361 findViewById(R.id.set).setEnabled(true);
362
363 WallpaperConnection conn = new WallpaperConnection(mSelectedIntent);
364 if (conn.connect()) {
365 if (mWallpaperConnection != null) {
366 mWallpaperConnection.disconnect();
367 }
368 mWallpaperConnection = conn;
369 }
370 }
371
Daniel Sandler86aea352009-09-11 15:59:22 -0400372 public void onClick(View v) { // "Set" button
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700373 if (v.getId() == R.id.set) {
374 if (mSelectedIntent != null) {
375 try {
376 mWallpaperManager.getIWallpaperManager().setWallpaperComponent(
377 mSelectedIntent.getComponent());
378 this.setResult(RESULT_OK);
379 } catch (RemoteException e) {
380 // do nothing
381 } catch (RuntimeException e) {
382 Log.w(TAG, "Failure setting wallpaper", e);
383 }
384 finish();
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700385 }
Dianne Hackborn83a5d382009-09-15 18:50:10 -0700386 } else if (v.getId() == R.id.configure) {
387 if (mSelectedInfo != null && mSelectedInfo.getSettingsActivity() != null) {
388 Intent intent = new Intent();
389 intent.setComponent(new ComponentName(mSelectedInfo.getPackageName(),
390 mSelectedInfo.getSettingsActivity()));
391 intent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true);
392 startActivity(intent);
393 }
Dianne Hackborn02e638e2009-08-20 19:33:42 -0700394 }
Romain Guy41669fc2009-08-13 12:53:24 -0700395 }
Daniel Sandler86aea352009-09-11 15:59:22 -0400396
397 public void onNothingSelected(AdapterView parent) {
398 }
399
Romain Guy41669fc2009-08-13 12:53:24 -0700400}