blob: 6d83f3090c4426c5b4217b342fc9ded2bfe01686 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 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.server;
18
19import static android.os.FileObserver.*;
20import static android.os.ParcelFileDescriptor.*;
Christopher Tate111bd4a2009-06-24 17:29:38 -070021
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070022import android.app.IWallpaperManager;
23import android.app.IWallpaperManagerCallback;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070024import android.app.PendingIntent;
Dianne Hackborneb034652009-09-07 00:49:58 -070025import android.app.WallpaperInfo;
Christopher Tate45281862010-03-05 15:46:30 -080026import android.app.backup.BackupManager;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080027import android.app.backup.WallpaperBackupHelper;
Amith Yamasani13593602012-03-22 16:16:17 -070028import android.content.BroadcastReceiver;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070029import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.content.Context;
31import android.content.Intent;
Amith Yamasani13593602012-03-22 16:16:17 -070032import android.content.IntentFilter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070033import android.content.ServiceConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.PackageManager;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070035import android.content.pm.ResolveInfo;
36import android.content.pm.ServiceInfo;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070037import android.content.pm.PackageManager.NameNotFoundException;
38import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.os.Binder;
Dianne Hackborn284ac932009-08-28 10:34:25 -070040import android.os.Bundle;
Amith Yamasani13593602012-03-22 16:16:17 -070041import android.os.Environment;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070042import android.os.FileUtils;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070043import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.RemoteException;
45import android.os.FileObserver;
46import android.os.ParcelFileDescriptor;
47import android.os.RemoteCallbackList;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070048import android.os.ServiceManager;
Dianne Hackborn0cd48872009-08-13 18:51:59 -070049import android.os.SystemClock;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080050import android.os.UserId;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070051import android.service.wallpaper.IWallpaperConnection;
52import android.service.wallpaper.IWallpaperEngine;
53import android.service.wallpaper.IWallpaperService;
54import android.service.wallpaper.WallpaperService;
Joe Onorato8a9b2202010-02-26 18:56:32 -080055import android.util.Slog;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080056import android.util.SparseArray;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070057import android.util.Xml;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070058import android.view.Display;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070059import android.view.IWindowManager;
60import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Dianne Hackborneb034652009-09-07 00:49:58 -070062import java.io.FileDescriptor;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070063import java.io.IOException;
64import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.File;
66import java.io.FileNotFoundException;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070067import java.io.FileInputStream;
68import java.io.FileOutputStream;
Dianne Hackborneb034652009-09-07 00:49:58 -070069import java.io.PrintWriter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070070import java.util.List;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070071
72import org.xmlpull.v1.XmlPullParser;
73import org.xmlpull.v1.XmlPullParserException;
74import org.xmlpull.v1.XmlSerializer;
75
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080076import com.android.internal.content.PackageMonitor;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080077import com.android.internal.util.FastXmlSerializer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070078import com.android.internal.util.JournaledFile;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080079import com.android.server.am.ActivityManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070081class WallpaperManagerService extends IWallpaperManager.Stub {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070082 static final String TAG = "WallpaperService";
Dianne Hackborncbf15042009-08-18 18:29:09 -070083 static final boolean DEBUG = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070084
Romain Guy407ec782011-08-24 17:06:58 -070085 final Object mLock = new Object[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086
Dianne Hackborn0cd48872009-08-13 18:51:59 -070087 /**
88 * Minimum time between crashes of a wallpaper service for us to consider
89 * restarting it vs. just reverting to the static wallpaper.
90 */
91 static final long MIN_WALLPAPER_CRASH_TIME = 10000;
92
Amith Yamasani37ce3a82012-02-06 12:04:42 -080093 static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
Dianne Hackborn0cd48872009-08-13 18:51:59 -070094 static final String WALLPAPER = "wallpaper";
Amith Yamasani37ce3a82012-02-06 12:04:42 -080095 static final String WALLPAPER_INFO = "wallpaper_info.xml";
Joe Onorato9bb8fd72009-07-28 18:24:51 -070096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 /**
98 * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
99 * that the wallpaper has changed. The CREATE is triggered when there is no
100 * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
101 * everytime the wallpaper is changed.
102 */
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800103 private class WallpaperObserver extends FileObserver {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700104
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800105 final WallpaperData mWallpaper;
106 final File mWallpaperDir;
107 final File mWallpaperFile;
108
109 public WallpaperObserver(WallpaperData wallpaper) {
110 super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
111 CLOSE_WRITE | DELETE | DELETE_SELF);
112 mWallpaperDir = getWallpaperDir(wallpaper.userId);
113 mWallpaper = wallpaper;
114 mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
115 }
116
117 @Override
118 public void onEvent(int event, String path) {
119 if (path == null) {
120 return;
121 }
122 synchronized (mLock) {
123 // changing the wallpaper means we'll need to back up the new one
124 long origId = Binder.clearCallingIdentity();
125 BackupManager bm = new BackupManager(mContext);
126 bm.dataChanged();
127 Binder.restoreCallingIdentity(origId);
128
129 File changedFile = new File(mWallpaperDir, path);
130 if (mWallpaperFile.equals(changedFile)) {
131 notifyCallbacksLocked(mWallpaper);
132 if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
133 || mWallpaper.imageWallpaperPending) {
134 if (event == CLOSE_WRITE) {
135 mWallpaper.imageWallpaperPending = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700136 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800137 bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
138 false, mWallpaper);
139 saveSettingsLocked(mWallpaper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 }
141 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800142 }
143 }
144 }
145
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700146 final Context mContext;
147 final IWindowManager mIWindowManager;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800148 final MyPackageMonitor mMonitor;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800149 WallpaperData mLastWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800151 SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
Dianne Hackborn07213e62011-08-24 20:05:39 -0700152
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800153 int mCurrentUserId;
Dianne Hackborn07213e62011-08-24 20:05:39 -0700154
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800155 static class WallpaperData {
156
157 int userId;
158
159 File wallpaperFile;
160
161 /**
162 * Client is currently writing a new image wallpaper.
163 */
164 boolean imageWallpaperPending;
165
166 /**
167 * Resource name if using a picture from the wallpaper gallery
168 */
169 String name = "";
170
171 /**
172 * The component name of the currently set live wallpaper.
173 */
174 ComponentName wallpaperComponent;
175
176 /**
177 * The component name of the wallpaper that should be set next.
178 */
179 ComponentName nextWallpaperComponent;
180
181 /**
182 * Name of the component used to display bitmap wallpapers from either the gallery or
183 * built-in wallpapers.
184 */
185 ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
186 "com.android.systemui.ImageWallpaper");
187
188 WallpaperConnection connection;
189 long lastDiedTime;
190 boolean wallpaperUpdating;
191 WallpaperObserver wallpaperObserver;
192
193 /**
194 * List of callbacks registered they should each be notified when the wallpaper is changed.
195 */
196 private RemoteCallbackList<IWallpaperManagerCallback> callbacks
197 = new RemoteCallbackList<IWallpaperManagerCallback>();
198
199 int width = -1;
200 int height = -1;
201
202 WallpaperData(int userId) {
203 this.userId = userId;
204 wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
205 }
206 }
207
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700208 class WallpaperConnection extends IWallpaperConnection.Stub
209 implements ServiceConnection {
Dianne Hackborneb034652009-09-07 00:49:58 -0700210 final WallpaperInfo mInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700211 final Binder mToken = new Binder();
212 IWallpaperService mService;
213 IWallpaperEngine mEngine;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800214 WallpaperData mWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800216 public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700217 mInfo = info;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800218 mWallpaper = wallpaper;
Dianne Hackborneb034652009-09-07 00:49:58 -0700219 }
220
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700221 public void onServiceConnected(ComponentName name, IBinder service) {
222 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800223 if (mWallpaper.connection == this) {
224 mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700225 mService = IWallpaperService.Stub.asInterface(service);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800226 attachServiceLocked(this, mWallpaper);
Dianne Hackborneb034652009-09-07 00:49:58 -0700227 // XXX should probably do saveSettingsLocked() later
228 // when we have an engine, but I'm not sure about
229 // locking there and anyway we always need to be able to
230 // recover if there is something wrong.
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800231 saveSettingsLocked(mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700232 }
233 }
234 }
235
236 public void onServiceDisconnected(ComponentName name) {
237 synchronized (mLock) {
238 mService = null;
239 mEngine = null;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800240 if (mWallpaper.connection == this) {
241 Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
242 if (!mWallpaper.wallpaperUpdating
243 && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
244 > SystemClock.uptimeMillis()
245 && mWallpaper.userId == mCurrentUserId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800246 Slog.w(TAG, "Reverting to built-in wallpaper!");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800247 clearWallpaperLocked(true, mWallpaper.userId);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700248 }
249 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700250 }
251 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800252
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700253 public void attachEngine(IWallpaperEngine engine) {
254 mEngine = engine;
255 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800256
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700257 public ParcelFileDescriptor setWallpaper(String name) {
258 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800259 if (mWallpaper.connection == this) {
260 return updateWallpaperBitmapLocked(name, mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700261 }
262 return null;
263 }
264 }
265 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800266
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800267 class MyPackageMonitor extends PackageMonitor {
268 @Override
269 public void onPackageUpdateFinished(String packageName, int uid) {
270 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800271 for (int i = 0; i < mWallpaperMap.size(); i++) {
272 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
273 if (wallpaper.wallpaperComponent != null
274 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
275 wallpaper.wallpaperUpdating = false;
276 ComponentName comp = wallpaper.wallpaperComponent;
277 clearWallpaperComponentLocked(wallpaper);
278 // Do this only for the current user's wallpaper
279 if (wallpaper.userId == mCurrentUserId
280 && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
281 Slog.w(TAG, "Wallpaper no longer available; reverting to default");
282 clearWallpaperLocked(false, wallpaper.userId);
283 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700284 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800285 }
286 }
287 }
288
289 @Override
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700290 public void onPackageModified(String packageName) {
291 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800292 for (int i = 0; i < mWallpaperMap.size(); i++) {
293 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
294 if (wallpaper.wallpaperComponent == null
295 || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
296 continue;
297 }
298 doPackagesChanged(true, wallpaper);
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700299 }
300 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700301 }
302
303 @Override
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800304 public void onPackageUpdateStarted(String packageName, int uid) {
305 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800306 for (int i = 0; i < mWallpaperMap.size(); i++) {
307 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
308 if (wallpaper.wallpaperComponent != null
309 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
310 wallpaper.wallpaperUpdating = true;
311 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800312 }
313 }
314 }
315
316 @Override
317 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800318 boolean changed = false;
319 for (int i = 0; i < mWallpaperMap.size(); i++) {
320 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
321 boolean res = doPackagesChanged(doit, wallpaper);
322 changed |= res;
323 }
324 return changed;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800325 }
326
327 @Override
328 public void onSomePackagesChanged() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800329 for (int i = 0; i < mWallpaperMap.size(); i++) {
330 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
331 doPackagesChanged(true, wallpaper);
332 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800333 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800334
335 boolean doPackagesChanged(boolean doit, WallpaperData wallpaper) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800336 boolean changed = false;
337 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800338 if (wallpaper.wallpaperComponent != null) {
339 int change = isPackageDisappearing(wallpaper.wallpaperComponent
340 .getPackageName());
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800341 if (change == PACKAGE_PERMANENT_CHANGE
342 || change == PACKAGE_TEMPORARY_CHANGE) {
343 changed = true;
344 if (doit) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800345 Slog.w(TAG, "Wallpaper uninstalled, removing: "
346 + wallpaper.wallpaperComponent);
347 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800348 }
349 }
350 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800351 if (wallpaper.nextWallpaperComponent != null) {
352 int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
353 .getPackageName());
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800354 if (change == PACKAGE_PERMANENT_CHANGE
355 || change == PACKAGE_TEMPORARY_CHANGE) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800356 wallpaper.nextWallpaperComponent = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800357 }
358 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800359 if (wallpaper.wallpaperComponent != null
360 && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800361 try {
362 mContext.getPackageManager().getServiceInfo(
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800363 wallpaper.wallpaperComponent, 0);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800364 } catch (NameNotFoundException e) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800365 Slog.w(TAG, "Wallpaper component gone, removing: "
366 + wallpaper.wallpaperComponent);
367 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800368 }
369 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800370 if (wallpaper.nextWallpaperComponent != null
371 && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800372 try {
373 mContext.getPackageManager().getServiceInfo(
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800374 wallpaper.nextWallpaperComponent, 0);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800375 } catch (NameNotFoundException e) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800376 wallpaper.nextWallpaperComponent = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800377 }
378 }
379 }
380 return changed;
381 }
382 }
383
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700384 public WallpaperManagerService(Context context) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800385 if (DEBUG) Slog.v(TAG, "WallpaperService startup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 mContext = context;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700387 mIWindowManager = IWindowManager.Stub.asInterface(
388 ServiceManager.getService(Context.WINDOW_SERVICE));
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800389 mMonitor = new MyPackageMonitor();
390 mMonitor.register(context, true);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800391 WALLPAPER_BASE_DIR.mkdirs();
392 loadSettingsLocked(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800395 private static File getWallpaperDir(int userId) {
396 return new File(WALLPAPER_BASE_DIR + "/" + userId);
397 }
398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 @Override
400 protected void finalize() throws Throwable {
401 super.finalize();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800402 for (int i = 0; i < mWallpaperMap.size(); i++) {
403 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
404 wallpaper.wallpaperObserver.stopWatching();
405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 }
Amith Yamasani13593602012-03-22 16:16:17 -0700407
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700408 public void systemReady() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800409 if (DEBUG) Slog.v(TAG, "systemReady");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800410 WallpaperData wallpaper = mWallpaperMap.get(0);
411 switchWallpaper(wallpaper);
412 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
413 wallpaper.wallpaperObserver.startWatching();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800414
Amith Yamasani13593602012-03-22 16:16:17 -0700415 IntentFilter userFilter = new IntentFilter();
416 userFilter.addAction(Intent.ACTION_USER_SWITCHED);
417 userFilter.addAction(Intent.ACTION_USER_REMOVED);
418 mContext.registerReceiver(new BroadcastReceiver() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800419 @Override
Amith Yamasani13593602012-03-22 16:16:17 -0700420 public void onReceive(Context context, Intent intent) {
421 String action = intent.getAction();
422 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
423 switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
424 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
425 removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
426 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800427 }
Amith Yamasani13593602012-03-22 16:16:17 -0700428 }, userFilter);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800429 }
430
431 String getName() {
432 return mWallpaperMap.get(0).name;
433 }
434
Amith Yamasani13593602012-03-22 16:16:17 -0700435 void removeUser(int userId) {
436 synchronized (mLock) {
437 WallpaperData wallpaper = mWallpaperMap.get(userId);
438 if (wallpaper != null) {
439 wallpaper.wallpaperObserver.stopWatching();
440 mWallpaperMap.remove(userId);
441 }
442 File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
443 wallpaperFile.delete();
444 File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
445 wallpaperInfoFile.delete();
446 }
447 }
448
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800449 void switchUser(int userId) {
450 synchronized (mLock) {
451 mCurrentUserId = userId;
452 WallpaperData wallpaper = mWallpaperMap.get(userId);
453 if (wallpaper == null) {
454 wallpaper = new WallpaperData(userId);
455 mWallpaperMap.put(userId, wallpaper);
456 loadSettingsLocked(userId);
457 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
458 wallpaper.wallpaperObserver.startWatching();
459 }
460 switchWallpaper(wallpaper);
461 }
462 }
463
464 void switchWallpaper(WallpaperData wallpaper) {
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700465 synchronized (mLock) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700466 RuntimeException e = null;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700467 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800468 ComponentName cname = wallpaper.wallpaperComponent != null ?
469 wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
470 if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700471 return;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700472 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700473 } catch (RuntimeException e1) {
474 e = e1;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700475 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700476 Slog.w(TAG, "Failure starting previous wallpaper", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800477 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800478 }
479 }
480
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800481 public void clearWallpaper() {
482 if (DEBUG) Slog.v(TAG, "clearWallpaper");
483 synchronized (mLock) {
484 clearWallpaperLocked(false, UserId.getCallingUserId());
485 }
486 }
487
488 void clearWallpaperLocked(boolean defaultFailed, int userId) {
489 WallpaperData wallpaper = mWallpaperMap.get(userId);
490 File f = new File(getWallpaperDir(userId), WALLPAPER);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800491 if (f.exists()) {
492 f.delete();
493 }
494 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700495 RuntimeException e = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800496 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800497 wallpaper.imageWallpaperPending = false;
498 if (userId != mCurrentUserId) return;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700499 if (bindWallpaperComponentLocked(defaultFailed
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800500 ? wallpaper.imageWallpaperComponent
501 : null, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700502 return;
503 }
504 } catch (IllegalArgumentException e1) {
505 e = e1;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800506 } finally {
507 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700509
510 // This can happen if the default wallpaper component doesn't
511 // exist. This should be a system configuration problem, but
512 // let's not let it crash the system and just live with no
513 // wallpaper.
514 Slog.e(TAG, "Default wallpaper component not found!", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800515 clearWallpaperComponentLocked(wallpaper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 }
517
518 public void setDimensionHints(int width, int height) throws RemoteException {
519 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
520
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800521 int userId = UserId.getCallingUserId();
522 WallpaperData wallpaper = mWallpaperMap.get(userId);
523 if (wallpaper == null) {
524 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 if (width <= 0 || height <= 0) {
527 throw new IllegalArgumentException("width and height must be > 0");
528 }
529
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700530 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800531 if (width != wallpaper.width || height != wallpaper.height) {
532 wallpaper.width = width;
533 wallpaper.height = height;
534 saveSettingsLocked(wallpaper);
535 if (mCurrentUserId != userId) return; // Don't change the properties now
536 if (wallpaper.connection != null) {
537 if (wallpaper.connection.mEngine != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700538 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800539 wallpaper.connection.mEngine.setDesiredSize(
Dianne Hackborn284ac932009-08-28 10:34:25 -0700540 width, height);
541 } catch (RemoteException e) {
542 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800543 notifyCallbacksLocked(wallpaper);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700544 }
545 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800547 }
548 }
549
550 public int getWidthHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700551 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800552 WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
553 return wallpaper.width;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 }
556
557 public int getHeightHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700558 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800559 WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
560 return wallpaper.height;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
563
Dianne Hackborn284ac932009-08-28 10:34:25 -0700564 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
565 Bundle outParams) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700566 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800567 // This returns the current user's wallpaper, if called by a system service. Else it
568 // returns the wallpaper for the calling user.
569 int callingUid = Binder.getCallingUid();
570 int wallpaperUserId = 0;
571 if (callingUid == android.os.Process.SYSTEM_UID) {
572 wallpaperUserId = mCurrentUserId;
573 } else {
574 wallpaperUserId = UserId.getUserId(callingUid);
575 }
576 WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700577 try {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700578 if (outParams != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800579 outParams.putInt("width", wallpaper.width);
580 outParams.putInt("height", wallpaper.height);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700581 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800582 wallpaper.callbacks.register(cb);
583 File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700584 if (!f.exists()) {
585 return null;
586 }
587 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
588 } catch (FileNotFoundException e) {
589 /* Shouldn't happen as we check to see if the file exists */
Joe Onorato8a9b2202010-02-26 18:56:32 -0800590 Slog.w(TAG, "Error getting wallpaper", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700592 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
Dianne Hackborneb034652009-09-07 00:49:58 -0700596 public WallpaperInfo getWallpaperInfo() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800597 int userId = UserId.getCallingUserId();
Dianne Hackborneb034652009-09-07 00:49:58 -0700598 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800599 WallpaperData wallpaper = mWallpaperMap.get(userId);
600 if (wallpaper.connection != null) {
601 return wallpaper.connection.mInfo;
Dianne Hackborneb034652009-09-07 00:49:58 -0700602 }
603 return null;
604 }
605 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800606
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700607 public ParcelFileDescriptor setWallpaper(String name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800608 if (DEBUG) Slog.v(TAG, "setWallpaper");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800609 int userId = UserId.getCallingUserId();
610 WallpaperData wallpaper = mWallpaperMap.get(userId);
611 if (wallpaper == null) {
612 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 checkPermission(android.Manifest.permission.SET_WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700615 synchronized (mLock) {
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700616 final long ident = Binder.clearCallingIdentity();
617 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800618 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700619 if (pfd != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800620 wallpaper.imageWallpaperPending = true;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700621 }
622 return pfd;
623 } finally {
624 Binder.restoreCallingIdentity(ident);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 }
627 }
628
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800629 ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700630 if (name == null) name = "";
631 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800632 File dir = getWallpaperDir(wallpaper.userId);
633 if (!dir.exists()) {
634 dir.mkdir();
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800635 FileUtils.setPermissions(
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800636 dir.getPath(),
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800637 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
638 -1, -1);
639 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800640 ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER),
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700641 MODE_CREATE|MODE_READ_WRITE);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800642 wallpaper.name = name;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700643 return fd;
644 } catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800645 Slog.w(TAG, "Error setting wallpaper", e);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700646 }
647 return null;
648 }
649
650 public void setWallpaperComponent(ComponentName name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800651 if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800652 int userId = UserId.getCallingUserId();
653 WallpaperData wallpaper = mWallpaperMap.get(userId);
654 if (wallpaper == null) {
655 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
656 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700657 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
658 synchronized (mLock) {
659 final long ident = Binder.clearCallingIdentity();
660 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800661 wallpaper.imageWallpaperPending = false;
662 bindWallpaperComponentLocked(name, false, true, wallpaper);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700663 } finally {
664 Binder.restoreCallingIdentity(ident);
665 }
666 }
667 }
668
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800669 boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
670 boolean fromUser, WallpaperData wallpaper) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800671 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700672 // Has the component changed?
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700673 if (!force) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800674 if (wallpaper.connection != null) {
675 if (wallpaper.wallpaperComponent == null) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700676 if (componentName == null) {
677 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
678 // Still using default wallpaper.
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700679 return true;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700680 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800681 } else if (wallpaper.wallpaperComponent.equals(componentName)) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700682 // Changing to same wallpaper.
683 if (DEBUG) Slog.v(TAG, "same wallpaper");
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700684 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700685 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700686 }
687 }
688
689 try {
Mike Clerona428b2c2009-11-15 22:53:08 -0800690 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800691 String defaultComponent =
692 mContext.getString(com.android.internal.R.string.default_wallpaper_component);
Mike Clerona428b2c2009-11-15 22:53:08 -0800693 if (defaultComponent != null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800694 // See if there is a default wallpaper component specified
Mike Clerona428b2c2009-11-15 22:53:08 -0800695 componentName = ComponentName.unflattenFromString(defaultComponent);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800696 if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
Mike Cleron322b6ee2009-11-12 07:45:47 -0800697 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800698 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800699 // Fall back to static image wallpaper
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800700 componentName = wallpaper.imageWallpaperComponent;
Mike Cleron322b6ee2009-11-12 07:45:47 -0800701 //clearWallpaperComponentLocked();
702 //return;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800703 if (DEBUG) Slog.v(TAG, "Using image wallpaper");
Mike Cleron322b6ee2009-11-12 07:45:47 -0800704 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700705 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800706 ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700707 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
708 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700709 String msg = "Selected service does not require "
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700710 + android.Manifest.permission.BIND_WALLPAPER
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700711 + ": " + componentName;
712 if (fromUser) {
713 throw new SecurityException(msg);
714 }
715 Slog.w(TAG, msg);
716 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700717 }
718
Dianne Hackborneb034652009-09-07 00:49:58 -0700719 WallpaperInfo wi = null;
720
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700721 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800722 if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700723 // Make sure the selected service is actually a wallpaper service.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700724 List<ResolveInfo> ris = mContext.getPackageManager()
Dianne Hackborneb034652009-09-07 00:49:58 -0700725 .queryIntentServices(intent, PackageManager.GET_META_DATA);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700726 for (int i=0; i<ris.size(); i++) {
727 ServiceInfo rsi = ris.get(i).serviceInfo;
728 if (rsi.name.equals(si.name) &&
729 rsi.packageName.equals(si.packageName)) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700730 try {
731 wi = new WallpaperInfo(mContext, ris.get(i));
732 } catch (XmlPullParserException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700733 if (fromUser) {
734 throw new IllegalArgumentException(e);
735 }
736 Slog.w(TAG, e);
737 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700738 } catch (IOException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700739 if (fromUser) {
740 throw new IllegalArgumentException(e);
741 }
742 Slog.w(TAG, e);
743 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700744 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700745 break;
746 }
747 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700748 if (wi == null) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700749 String msg = "Selected service is not a wallpaper: "
750 + componentName;
751 if (fromUser) {
752 throw new SecurityException(msg);
753 }
754 Slog.w(TAG, msg);
755 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700756 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700757 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700758
759 // Bind the service!
Joe Onorato8a9b2202010-02-26 18:56:32 -0800760 if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800761 WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -0800762 intent.setComponent(componentName);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800763 int serviceUserId = wallpaper.userId;
764 // Because the image wallpaper is running in the system ui
765 if (componentName.equals(wallpaper.imageWallpaperComponent)) {
766 serviceUserId = 0;
767 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -0700768 intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
769 com.android.internal.R.string.wallpaper_binding_label);
770 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
Dianne Hackborneb034652009-09-07 00:49:58 -0700771 mContext, 0,
772 Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
773 mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
774 0));
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800775 if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700776 String msg = "Unable to bind service: "
777 + componentName;
778 if (fromUser) {
779 throw new IllegalArgumentException(msg);
780 }
781 Slog.w(TAG, msg);
782 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700783 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800784 if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
785 detachWallpaperLocked(mLastWallpaper);
786 }
787 wallpaper.wallpaperComponent = componentName;
788 wallpaper.connection = newConn;
789 wallpaper.lastDiedTime = SystemClock.uptimeMillis();
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700790 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800791 if (wallpaper.userId == mCurrentUserId) {
792 if (DEBUG)
793 Slog.v(TAG, "Adding window token: " + newConn.mToken);
794 mIWindowManager.addWindowToken(newConn.mToken,
795 WindowManager.LayoutParams.TYPE_WALLPAPER);
796 mLastWallpaper = wallpaper;
797 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700798 } catch (RemoteException e) {
799 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700800 } catch (PackageManager.NameNotFoundException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700801 String msg = "Unknown component " + componentName;
802 if (fromUser) {
803 throw new IllegalArgumentException(msg);
804 }
805 Slog.w(TAG, msg);
806 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700807 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700808 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700809 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800810
811 void detachWallpaperLocked(WallpaperData wallpaper) {
812 if (wallpaper.connection != null) {
813 if (wallpaper.connection.mEngine != null) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700814 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800815 wallpaper.connection.mEngine.destroy();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700816 } catch (RemoteException e) {
817 }
818 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800819 mContext.unbindService(wallpaper.connection);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700820 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800821 if (DEBUG)
822 Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
823 mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700824 } catch (RemoteException e) {
825 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800826 wallpaper.connection.mService = null;
827 wallpaper.connection.mEngine = null;
828 wallpaper.connection = null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700829 }
830 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800831
832 void clearWallpaperComponentLocked(WallpaperData wallpaper) {
833 wallpaper.wallpaperComponent = null;
834 detachWallpaperLocked(wallpaper);
835 }
836
837 void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700838 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700839 conn.mService.attach(conn, conn.mToken,
840 WindowManager.LayoutParams.TYPE_WALLPAPER, false,
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800841 wallpaper.width, wallpaper.height);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700842 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800843 Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800844 if (!wallpaper.wallpaperUpdating) {
845 bindWallpaperComponentLocked(null, false, false, wallpaper);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800846 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700847 }
848 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800849
850 private void notifyCallbacksLocked(WallpaperData wallpaper) {
851 final int n = wallpaper.callbacks.beginBroadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 for (int i = 0; i < n; i++) {
853 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800854 wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 } catch (RemoteException e) {
856
857 // The RemoteCallbackList will take care of removing
858 // the dead object for us.
859 }
860 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800861 wallpaper.callbacks.finishBroadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
863 mContext.sendBroadcast(intent);
864 }
865
866 private void checkPermission(String permission) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700867 if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
869 + ", must have permission " + permission);
870 }
871 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700872
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800873 private static JournaledFile makeJournaledFile(int userId) {
Amith Yamasani13593602012-03-22 16:16:17 -0700874 final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700875 return new JournaledFile(new File(base), new File(base + ".tmp"));
876 }
877
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800878 private void saveSettingsLocked(WallpaperData wallpaper) {
879 JournaledFile journal = makeJournaledFile(wallpaper.userId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700880 FileOutputStream stream = null;
881 try {
882 stream = new FileOutputStream(journal.chooseForWrite(), false);
883 XmlSerializer out = new FastXmlSerializer();
884 out.setOutput(stream, "utf-8");
885 out.startDocument(null, true);
886
887 out.startTag(null, "wp");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800888 out.attribute(null, "width", Integer.toString(wallpaper.width));
889 out.attribute(null, "height", Integer.toString(wallpaper.height));
890 out.attribute(null, "name", wallpaper.name);
891 if (wallpaper.wallpaperComponent != null
892 && !wallpaper.wallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700893 out.attribute(null, "component",
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800894 wallpaper.wallpaperComponent.flattenToShortString());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700895 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700896 out.endTag(null, "wp");
897
898 out.endDocument();
899 stream.close();
900 journal.commit();
901 } catch (IOException e) {
902 try {
903 if (stream != null) {
904 stream.close();
905 }
906 } catch (IOException ex) {
907 // Ignore
908 }
909 journal.rollback();
910 }
911 }
912
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800913 private void migrateFromOld() {
914 File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
915 File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
916 if (oldWallpaper.exists()) {
917 File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
918 oldWallpaper.renameTo(newWallpaper);
919 }
920 if (oldInfo.exists()) {
921 File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
922 oldInfo.renameTo(newInfo);
923 }
924 }
925
926 private void loadSettingsLocked(int userId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800927 if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
Mike Clerona428b2c2009-11-15 22:53:08 -0800928
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800929 JournaledFile journal = makeJournaledFile(userId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700930 FileInputStream stream = null;
931 File file = journal.chooseForRead();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800932 if (!file.exists()) {
933 // This should only happen one time, when upgrading from a legacy system
934 migrateFromOld();
935 }
936 WallpaperData wallpaper = mWallpaperMap.get(userId);
937 if (wallpaper == null) {
938 wallpaper = new WallpaperData(userId);
939 mWallpaperMap.put(userId, wallpaper);
940 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700941 boolean success = false;
942 try {
943 stream = new FileInputStream(file);
944 XmlPullParser parser = Xml.newPullParser();
945 parser.setInput(stream, null);
946
947 int type;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700948 do {
949 type = parser.next();
950 if (type == XmlPullParser.START_TAG) {
951 String tag = parser.getName();
952 if ("wp".equals(tag)) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800953 wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
954 wallpaper.height = Integer.parseInt(parser
955 .getAttributeValue(null, "height"));
956 wallpaper.name = parser.getAttributeValue(null, "name");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700957 String comp = parser.getAttributeValue(null, "component");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800958 wallpaper.nextWallpaperComponent = comp != null
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700959 ? ComponentName.unflattenFromString(comp)
960 : null;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800961 if (wallpaper.nextWallpaperComponent == null
962 || "android".equals(wallpaper.nextWallpaperComponent
963 .getPackageName())) {
964 wallpaper.nextWallpaperComponent = wallpaper.imageWallpaperComponent;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700965 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800966
967 if (DEBUG) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800968 Slog.v(TAG, "mWidth:" + wallpaper.width);
969 Slog.v(TAG, "mHeight:" + wallpaper.height);
970 Slog.v(TAG, "mName:" + wallpaper.name);
971 Slog.v(TAG, "mNextWallpaperComponent:"
972 + wallpaper.nextWallpaperComponent);
Mike Clerona428b2c2009-11-15 22:53:08 -0800973 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700974 }
975 }
976 } while (type != XmlPullParser.END_DOCUMENT);
977 success = true;
978 } catch (NullPointerException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800979 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700980 } catch (NumberFormatException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800981 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700982 } catch (XmlPullParserException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700984 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800985 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700986 } catch (IndexOutOfBoundsException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800987 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700988 }
989 try {
990 if (stream != null) {
991 stream.close();
992 }
993 } catch (IOException e) {
994 // Ignore
995 }
996
997 if (!success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800998 wallpaper.width = -1;
999 wallpaper.height = -1;
1000 wallpaper.name = "";
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001001 }
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001002
1003 // We always want to have some reasonable width hint.
1004 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1005 Display d = wm.getDefaultDisplay();
1006 int baseSize = d.getMaximumSizeDimension();
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001007 if (wallpaper.width < baseSize) {
1008 wallpaper.width = baseSize;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001009 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001010 if (wallpaper.height < baseSize) {
1011 wallpaper.height = baseSize;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001012 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001013 }
1014
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001015 // Called by SystemBackupAgent after files are restored to disk.
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001016 void settingsRestored() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001017 // TODO: If necessary, make it work for secondary users as well. This currently assumes
1018 // restores only to the primary user
Joe Onorato8a9b2202010-02-26 18:56:32 -08001019 if (DEBUG) Slog.v(TAG, "settingsRestored");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001020 WallpaperData wallpaper = null;
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001021 boolean success = false;
1022 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001023 loadSettingsLocked(0);
1024 wallpaper = mWallpaperMap.get(0);
1025 if (wallpaper.nextWallpaperComponent != null
1026 && !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
1027 if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
1028 wallpaper)) {
Christopher Tatee3ab4d02009-12-16 14:03:31 -08001029 // No such live wallpaper or other failure; fall back to the default
1030 // live wallpaper (since the profile being restored indicated that the
1031 // user had selected a live rather than static one).
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001032 bindWallpaperComponentLocked(null, false, false, wallpaper);
Christopher Tatee3ab4d02009-12-16 14:03:31 -08001033 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001034 success = true;
1035 } else {
Mike Clerona428b2c2009-11-15 22:53:08 -08001036 // If there's a wallpaper name, we use that. If that can't be loaded, then we
1037 // use the default.
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001038 if ("".equals(wallpaper.name)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001039 if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
Mike Clerona428b2c2009-11-15 22:53:08 -08001040 success = true;
1041 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001042 if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001043 success = restoreNamedResourceLocked(wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -08001044 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001045 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
Mike Clerona428b2c2009-11-15 22:53:08 -08001046 if (success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001047 bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
1048 wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -08001049 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001050 }
1051 }
1052
1053 if (!success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001054 Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
1055 wallpaper.name = "";
1056 getWallpaperDir(0).delete();
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001057 }
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001058
1059 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001060 saveSettingsLocked(wallpaper);
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001061 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001062 }
1063
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001064 boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
1065 if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
1066 String resName = wallpaper.name.substring(4);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001067
1068 String pkg = null;
1069 int colon = resName.indexOf(':');
1070 if (colon > 0) {
1071 pkg = resName.substring(0, colon);
1072 }
1073
1074 String ident = null;
1075 int slash = resName.lastIndexOf('/');
1076 if (slash > 0) {
1077 ident = resName.substring(slash+1);
1078 }
1079
1080 String type = null;
1081 if (colon > 0 && slash > 0 && (slash-colon) > 1) {
1082 type = resName.substring(colon+1, slash);
1083 }
1084
1085 if (pkg != null && ident != null && type != null) {
1086 int resId = -1;
1087 InputStream res = null;
1088 FileOutputStream fos = null;
1089 try {
1090 Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
1091 Resources r = c.getResources();
1092 resId = r.getIdentifier(resName, null, null);
1093 if (resId == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001094 Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001095 + " ident=" + ident);
1096 return false;
1097 }
1098
1099 res = r.openRawResource(resId);
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001100 if (wallpaper.wallpaperFile.exists()) {
1101 wallpaper.wallpaperFile.delete();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07001102 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001103 fos = new FileOutputStream(wallpaper.wallpaperFile);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001104
1105 byte[] buffer = new byte[32768];
1106 int amt;
1107 while ((amt=res.read(buffer)) > 0) {
1108 fos.write(buffer, 0, amt);
1109 }
1110 // mWallpaperObserver will notice the close and send the change broadcast
1111
Joe Onorato8a9b2202010-02-26 18:56:32 -08001112 Slog.v(TAG, "Restored wallpaper: " + resName);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001113 return true;
1114 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001115 Slog.e(TAG, "Package name " + pkg + " not found");
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001116 } catch (Resources.NotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001117 Slog.e(TAG, "Resource not found: " + resId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001118 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001119 Slog.e(TAG, "IOException while restoring wallpaper ", e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001120 } finally {
1121 if (res != null) {
1122 try {
1123 res.close();
1124 } catch (IOException ex) {}
1125 }
1126 if (fos != null) {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07001127 FileUtils.sync(fos);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001128 try {
1129 fos.close();
1130 } catch (IOException ex) {}
1131 }
1132 }
1133 }
1134 }
1135 return false;
1136 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001137
Dianne Hackborneb034652009-09-07 00:49:58 -07001138 @Override
1139 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1140 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1141 != PackageManager.PERMISSION_GRANTED) {
1142
1143 pw.println("Permission Denial: can't dump wallpaper service from from pid="
1144 + Binder.getCallingPid()
1145 + ", uid=" + Binder.getCallingUid());
1146 return;
1147 }
1148
1149 synchronized (mLock) {
1150 pw.println("Current Wallpaper Service state:");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001151 for (int i = 0; i < mWallpaperMap.size(); i++) {
1152 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
1153 pw.println(" User " + wallpaper.userId + ":");
1154 pw.print(" mWidth=");
1155 pw.print(wallpaper.width);
1156 pw.print(" mHeight=");
1157 pw.println(wallpaper.height);
1158 pw.print(" mName=");
1159 pw.println(wallpaper.name);
1160 pw.print(" mWallpaperComponent=");
1161 pw.println(wallpaper.wallpaperComponent);
1162 if (wallpaper.connection != null) {
1163 WallpaperConnection conn = wallpaper.connection;
1164 pw.print(" Wallpaper connection ");
1165 pw.print(conn);
1166 pw.println(":");
1167 if (conn.mInfo != null) {
1168 pw.print(" mInfo.component=");
1169 pw.println(conn.mInfo.getComponent());
1170 }
1171 pw.print(" mToken=");
1172 pw.println(conn.mToken);
1173 pw.print(" mService=");
1174 pw.println(conn.mService);
1175 pw.print(" mEngine=");
1176 pw.println(conn.mEngine);
1177 pw.print(" mLastDiedTime=");
1178 pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
1179 }
Dianne Hackborneb034652009-09-07 00:49:58 -07001180 }
1181 }
1182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183}