blob: c6e43e6f11b5b792944e42edc31f3fff5723d3db [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;
rpcraig554cb0c2012-07-05 06:41:43 -040048import android.os.SELinux;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070049import android.os.ServiceManager;
Dianne Hackborn0cd48872009-08-13 18:51:59 -070050import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070051import android.os.UserHandle;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070052import android.service.wallpaper.IWallpaperConnection;
53import android.service.wallpaper.IWallpaperEngine;
54import android.service.wallpaper.IWallpaperService;
55import android.service.wallpaper.WallpaperService;
Joe Onorato8a9b2202010-02-26 18:56:32 -080056import android.util.Slog;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080057import android.util.SparseArray;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070058import android.util.Xml;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070059import android.view.Display;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070060import android.view.IWindowManager;
61import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Dianne Hackborneb034652009-09-07 00:49:58 -070063import java.io.FileDescriptor;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070064import java.io.IOException;
65import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.io.File;
67import java.io.FileNotFoundException;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070068import java.io.FileInputStream;
69import java.io.FileOutputStream;
Dianne Hackborneb034652009-09-07 00:49:58 -070070import java.io.PrintWriter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070071import java.util.List;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070072
73import org.xmlpull.v1.XmlPullParser;
74import org.xmlpull.v1.XmlPullParserException;
75import org.xmlpull.v1.XmlSerializer;
76
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080077import com.android.internal.content.PackageMonitor;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080078import com.android.internal.util.FastXmlSerializer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070079import com.android.internal.util.JournaledFile;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080080import com.android.server.am.ActivityManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070082class WallpaperManagerService extends IWallpaperManager.Stub {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070083 static final String TAG = "WallpaperService";
Dianne Hackborncbf15042009-08-18 18:29:09 -070084 static final boolean DEBUG = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070085
Romain Guy407ec782011-08-24 17:06:58 -070086 final Object mLock = new Object[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087
Dianne Hackborn0cd48872009-08-13 18:51:59 -070088 /**
89 * Minimum time between crashes of a wallpaper service for us to consider
90 * restarting it vs. just reverting to the static wallpaper.
91 */
92 static final long MIN_WALLPAPER_CRASH_TIME = 10000;
93
Amith Yamasani37ce3a82012-02-06 12:04:42 -080094 static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
Dianne Hackborn0cd48872009-08-13 18:51:59 -070095 static final String WALLPAPER = "wallpaper";
Amith Yamasani37ce3a82012-02-06 12:04:42 -080096 static final String WALLPAPER_INFO = "wallpaper_info.xml";
Joe Onorato9bb8fd72009-07-28 18:24:51 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 /**
99 * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
100 * that the wallpaper has changed. The CREATE is triggered when there is no
101 * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
102 * everytime the wallpaper is changed.
103 */
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800104 private class WallpaperObserver extends FileObserver {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700105
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800106 final WallpaperData mWallpaper;
107 final File mWallpaperDir;
108 final File mWallpaperFile;
109
110 public WallpaperObserver(WallpaperData wallpaper) {
111 super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
112 CLOSE_WRITE | DELETE | DELETE_SELF);
113 mWallpaperDir = getWallpaperDir(wallpaper.userId);
114 mWallpaper = wallpaper;
115 mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
116 }
117
118 @Override
119 public void onEvent(int event, String path) {
120 if (path == null) {
121 return;
122 }
123 synchronized (mLock) {
124 // changing the wallpaper means we'll need to back up the new one
125 long origId = Binder.clearCallingIdentity();
126 BackupManager bm = new BackupManager(mContext);
127 bm.dataChanged();
128 Binder.restoreCallingIdentity(origId);
129
130 File changedFile = new File(mWallpaperDir, path);
131 if (mWallpaperFile.equals(changedFile)) {
132 notifyCallbacksLocked(mWallpaper);
133 if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
134 || mWallpaper.imageWallpaperPending) {
135 if (event == CLOSE_WRITE) {
136 mWallpaper.imageWallpaperPending = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700137 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800138 bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
139 false, mWallpaper);
140 saveSettingsLocked(mWallpaper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 }
142 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800143 }
144 }
145 }
146
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700147 final Context mContext;
148 final IWindowManager mIWindowManager;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800149 final MyPackageMonitor mMonitor;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800150 WallpaperData mLastWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800152 SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
Dianne Hackborn07213e62011-08-24 20:05:39 -0700153
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800154 int mCurrentUserId;
Dianne Hackborn07213e62011-08-24 20:05:39 -0700155
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800156 static class WallpaperData {
157
158 int userId;
159
160 File wallpaperFile;
161
162 /**
163 * Client is currently writing a new image wallpaper.
164 */
165 boolean imageWallpaperPending;
166
167 /**
168 * Resource name if using a picture from the wallpaper gallery
169 */
170 String name = "";
171
172 /**
173 * The component name of the currently set live wallpaper.
174 */
175 ComponentName wallpaperComponent;
176
177 /**
178 * The component name of the wallpaper that should be set next.
179 */
180 ComponentName nextWallpaperComponent;
181
182 /**
183 * Name of the component used to display bitmap wallpapers from either the gallery or
184 * built-in wallpapers.
185 */
186 ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
187 "com.android.systemui.ImageWallpaper");
188
189 WallpaperConnection connection;
190 long lastDiedTime;
191 boolean wallpaperUpdating;
192 WallpaperObserver wallpaperObserver;
193
194 /**
195 * List of callbacks registered they should each be notified when the wallpaper is changed.
196 */
197 private RemoteCallbackList<IWallpaperManagerCallback> callbacks
198 = new RemoteCallbackList<IWallpaperManagerCallback>();
199
200 int width = -1;
201 int height = -1;
202
203 WallpaperData(int userId) {
204 this.userId = userId;
205 wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
206 }
207 }
208
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700209 class WallpaperConnection extends IWallpaperConnection.Stub
210 implements ServiceConnection {
Dianne Hackborneb034652009-09-07 00:49:58 -0700211 final WallpaperInfo mInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700212 final Binder mToken = new Binder();
213 IWallpaperService mService;
214 IWallpaperEngine mEngine;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800215 WallpaperData mWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800217 public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700218 mInfo = info;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800219 mWallpaper = wallpaper;
Dianne Hackborneb034652009-09-07 00:49:58 -0700220 }
221
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700222 public void onServiceConnected(ComponentName name, IBinder service) {
223 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800224 if (mWallpaper.connection == this) {
225 mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700226 mService = IWallpaperService.Stub.asInterface(service);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800227 attachServiceLocked(this, mWallpaper);
Dianne Hackborneb034652009-09-07 00:49:58 -0700228 // XXX should probably do saveSettingsLocked() later
229 // when we have an engine, but I'm not sure about
230 // locking there and anyway we always need to be able to
231 // recover if there is something wrong.
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800232 saveSettingsLocked(mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700233 }
234 }
235 }
236
237 public void onServiceDisconnected(ComponentName name) {
238 synchronized (mLock) {
239 mService = null;
240 mEngine = null;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800241 if (mWallpaper.connection == this) {
242 Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
243 if (!mWallpaper.wallpaperUpdating
244 && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
245 > SystemClock.uptimeMillis()
246 && mWallpaper.userId == mCurrentUserId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800247 Slog.w(TAG, "Reverting to built-in wallpaper!");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800248 clearWallpaperLocked(true, mWallpaper.userId);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700249 }
250 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700251 }
252 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800253
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700254 public void attachEngine(IWallpaperEngine engine) {
255 mEngine = engine;
256 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800257
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700258 public ParcelFileDescriptor setWallpaper(String name) {
259 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800260 if (mWallpaper.connection == this) {
261 return updateWallpaperBitmapLocked(name, mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700262 }
263 return null;
264 }
265 }
266 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800267
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800268 class MyPackageMonitor extends PackageMonitor {
269 @Override
270 public void onPackageUpdateFinished(String packageName, int uid) {
271 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800272 for (int i = 0; i < mWallpaperMap.size(); i++) {
273 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
274 if (wallpaper.wallpaperComponent != null
275 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
276 wallpaper.wallpaperUpdating = false;
277 ComponentName comp = wallpaper.wallpaperComponent;
278 clearWallpaperComponentLocked(wallpaper);
279 // Do this only for the current user's wallpaper
280 if (wallpaper.userId == mCurrentUserId
281 && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
282 Slog.w(TAG, "Wallpaper no longer available; reverting to default");
283 clearWallpaperLocked(false, wallpaper.userId);
284 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700285 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800286 }
287 }
288 }
289
290 @Override
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700291 public void onPackageModified(String packageName) {
292 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800293 for (int i = 0; i < mWallpaperMap.size(); i++) {
294 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
295 if (wallpaper.wallpaperComponent == null
296 || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
297 continue;
298 }
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700299 doPackagesChangedLocked(true, wallpaper);
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700300 }
301 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700302 }
303
304 @Override
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800305 public void onPackageUpdateStarted(String packageName, int uid) {
306 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800307 for (int i = 0; i < mWallpaperMap.size(); i++) {
308 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
309 if (wallpaper.wallpaperComponent != null
310 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
311 wallpaper.wallpaperUpdating = true;
312 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800313 }
314 }
315 }
316
317 @Override
318 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700319 synchronized (mLock) {
320 boolean changed = false;
321 for (int i = 0; i < mWallpaperMap.size(); i++) {
322 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
323 boolean res = doPackagesChangedLocked(doit, wallpaper);
324 changed |= res;
325 }
326 return changed;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800327 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800328 }
329
330 @Override
331 public void onSomePackagesChanged() {
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700332 synchronized (mLock) {
333 for (int i = 0; i < mWallpaperMap.size(); i++) {
334 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
335 doPackagesChangedLocked(true, wallpaper);
336 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800337 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800338 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800339
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700340 boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800341 boolean changed = false;
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700342 if (wallpaper.wallpaperComponent != null) {
343 int change = isPackageDisappearing(wallpaper.wallpaperComponent
344 .getPackageName());
345 if (change == PACKAGE_PERMANENT_CHANGE
346 || change == PACKAGE_TEMPORARY_CHANGE) {
347 changed = true;
348 if (doit) {
349 Slog.w(TAG, "Wallpaper uninstalled, removing: "
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800350 + wallpaper.wallpaperComponent);
351 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800352 }
353 }
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700354 }
355 if (wallpaper.nextWallpaperComponent != null) {
356 int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
357 .getPackageName());
358 if (change == PACKAGE_PERMANENT_CHANGE
359 || change == PACKAGE_TEMPORARY_CHANGE) {
360 wallpaper.nextWallpaperComponent = null;
361 }
362 }
363 if (wallpaper.wallpaperComponent != null
364 && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
365 try {
366 mContext.getPackageManager().getServiceInfo(
367 wallpaper.wallpaperComponent, 0);
368 } catch (NameNotFoundException e) {
369 Slog.w(TAG, "Wallpaper component gone, removing: "
370 + wallpaper.wallpaperComponent);
371 clearWallpaperLocked(false, wallpaper.userId);
372 }
373 }
374 if (wallpaper.nextWallpaperComponent != null
375 && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
376 try {
377 mContext.getPackageManager().getServiceInfo(
378 wallpaper.nextWallpaperComponent, 0);
379 } catch (NameNotFoundException e) {
380 wallpaper.nextWallpaperComponent = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800381 }
382 }
383 return changed;
384 }
385 }
386
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700387 public WallpaperManagerService(Context context) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800388 if (DEBUG) Slog.v(TAG, "WallpaperService startup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 mContext = context;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700390 mIWindowManager = IWindowManager.Stub.asInterface(
391 ServiceManager.getService(Context.WINDOW_SERVICE));
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800392 mMonitor = new MyPackageMonitor();
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700393 mMonitor.register(context, null, true);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800394 WALLPAPER_BASE_DIR.mkdirs();
395 loadSettingsLocked(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 }
397
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800398 private static File getWallpaperDir(int userId) {
399 return new File(WALLPAPER_BASE_DIR + "/" + userId);
400 }
401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 @Override
403 protected void finalize() throws Throwable {
404 super.finalize();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800405 for (int i = 0; i < mWallpaperMap.size(); i++) {
406 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
407 wallpaper.wallpaperObserver.stopWatching();
408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
Amith Yamasani13593602012-03-22 16:16:17 -0700410
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700411 public void systemReady() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800412 if (DEBUG) Slog.v(TAG, "systemReady");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800413 WallpaperData wallpaper = mWallpaperMap.get(0);
414 switchWallpaper(wallpaper);
415 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
416 wallpaper.wallpaperObserver.startWatching();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800417
Amith Yamasani13593602012-03-22 16:16:17 -0700418 IntentFilter userFilter = new IntentFilter();
419 userFilter.addAction(Intent.ACTION_USER_SWITCHED);
420 userFilter.addAction(Intent.ACTION_USER_REMOVED);
421 mContext.registerReceiver(new BroadcastReceiver() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800422 @Override
Amith Yamasani13593602012-03-22 16:16:17 -0700423 public void onReceive(Context context, Intent intent) {
424 String action = intent.getAction();
425 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
426 switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
427 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
428 removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
429 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800430 }
Amith Yamasani13593602012-03-22 16:16:17 -0700431 }, userFilter);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800432 }
433
434 String getName() {
435 return mWallpaperMap.get(0).name;
436 }
437
Amith Yamasani13593602012-03-22 16:16:17 -0700438 void removeUser(int userId) {
439 synchronized (mLock) {
440 WallpaperData wallpaper = mWallpaperMap.get(userId);
441 if (wallpaper != null) {
442 wallpaper.wallpaperObserver.stopWatching();
443 mWallpaperMap.remove(userId);
444 }
445 File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
446 wallpaperFile.delete();
447 File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
448 wallpaperInfoFile.delete();
449 }
450 }
451
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800452 void switchUser(int userId) {
453 synchronized (mLock) {
454 mCurrentUserId = userId;
455 WallpaperData wallpaper = mWallpaperMap.get(userId);
456 if (wallpaper == null) {
457 wallpaper = new WallpaperData(userId);
458 mWallpaperMap.put(userId, wallpaper);
459 loadSettingsLocked(userId);
460 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
461 wallpaper.wallpaperObserver.startWatching();
462 }
463 switchWallpaper(wallpaper);
464 }
465 }
466
467 void switchWallpaper(WallpaperData wallpaper) {
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700468 synchronized (mLock) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700469 RuntimeException e = null;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700470 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800471 ComponentName cname = wallpaper.wallpaperComponent != null ?
472 wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
473 if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700474 return;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700475 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700476 } catch (RuntimeException e1) {
477 e = e1;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700478 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700479 Slog.w(TAG, "Failure starting previous wallpaper", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800480 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800481 }
482 }
483
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800484 public void clearWallpaper() {
485 if (DEBUG) Slog.v(TAG, "clearWallpaper");
486 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700487 clearWallpaperLocked(false, UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800488 }
489 }
490
491 void clearWallpaperLocked(boolean defaultFailed, int userId) {
492 WallpaperData wallpaper = mWallpaperMap.get(userId);
493 File f = new File(getWallpaperDir(userId), WALLPAPER);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800494 if (f.exists()) {
495 f.delete();
496 }
497 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700498 RuntimeException e = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800499 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800500 wallpaper.imageWallpaperPending = false;
501 if (userId != mCurrentUserId) return;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700502 if (bindWallpaperComponentLocked(defaultFailed
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800503 ? wallpaper.imageWallpaperComponent
504 : null, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700505 return;
506 }
507 } catch (IllegalArgumentException e1) {
508 e = e1;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800509 } finally {
510 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700512
513 // This can happen if the default wallpaper component doesn't
514 // exist. This should be a system configuration problem, but
515 // let's not let it crash the system and just live with no
516 // wallpaper.
517 Slog.e(TAG, "Default wallpaper component not found!", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800518 clearWallpaperComponentLocked(wallpaper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 }
520
521 public void setDimensionHints(int width, int height) throws RemoteException {
522 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
523
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700524 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800525 WallpaperData wallpaper = mWallpaperMap.get(userId);
526 if (wallpaper == null) {
527 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
528 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 if (width <= 0 || height <= 0) {
530 throw new IllegalArgumentException("width and height must be > 0");
531 }
532
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700533 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800534 if (width != wallpaper.width || height != wallpaper.height) {
535 wallpaper.width = width;
536 wallpaper.height = height;
537 saveSettingsLocked(wallpaper);
538 if (mCurrentUserId != userId) return; // Don't change the properties now
539 if (wallpaper.connection != null) {
540 if (wallpaper.connection.mEngine != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700541 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800542 wallpaper.connection.mEngine.setDesiredSize(
Dianne Hackborn284ac932009-08-28 10:34:25 -0700543 width, height);
544 } catch (RemoteException e) {
545 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800546 notifyCallbacksLocked(wallpaper);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700547 }
548 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 }
551 }
552
553 public int getWidthHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700554 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700555 WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800556 return wallpaper.width;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 }
559
560 public int getHeightHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700561 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700562 WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800563 return wallpaper.height;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566
Dianne Hackborn284ac932009-08-28 10:34:25 -0700567 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
568 Bundle outParams) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700569 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800570 // This returns the current user's wallpaper, if called by a system service. Else it
571 // returns the wallpaper for the calling user.
572 int callingUid = Binder.getCallingUid();
573 int wallpaperUserId = 0;
574 if (callingUid == android.os.Process.SYSTEM_UID) {
575 wallpaperUserId = mCurrentUserId;
576 } else {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700577 wallpaperUserId = UserHandle.getUserId(callingUid);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800578 }
579 WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700580 try {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700581 if (outParams != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800582 outParams.putInt("width", wallpaper.width);
583 outParams.putInt("height", wallpaper.height);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700584 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800585 wallpaper.callbacks.register(cb);
586 File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700587 if (!f.exists()) {
588 return null;
589 }
590 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
591 } catch (FileNotFoundException e) {
592 /* Shouldn't happen as we check to see if the file exists */
Joe Onorato8a9b2202010-02-26 18:56:32 -0800593 Slog.w(TAG, "Error getting wallpaper", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700595 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
598
Dianne Hackborneb034652009-09-07 00:49:58 -0700599 public WallpaperInfo getWallpaperInfo() {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700600 int userId = UserHandle.getCallingUserId();
Dianne Hackborneb034652009-09-07 00:49:58 -0700601 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800602 WallpaperData wallpaper = mWallpaperMap.get(userId);
603 if (wallpaper.connection != null) {
604 return wallpaper.connection.mInfo;
Dianne Hackborneb034652009-09-07 00:49:58 -0700605 }
606 return null;
607 }
608 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800609
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700610 public ParcelFileDescriptor setWallpaper(String name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800611 if (DEBUG) Slog.v(TAG, "setWallpaper");
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700612 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800613 WallpaperData wallpaper = mWallpaperMap.get(userId);
614 if (wallpaper == null) {
615 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
616 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 checkPermission(android.Manifest.permission.SET_WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700618 synchronized (mLock) {
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700619 final long ident = Binder.clearCallingIdentity();
620 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800621 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700622 if (pfd != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800623 wallpaper.imageWallpaperPending = true;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700624 }
625 return pfd;
626 } finally {
627 Binder.restoreCallingIdentity(ident);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 }
630 }
631
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800632 ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700633 if (name == null) name = "";
634 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800635 File dir = getWallpaperDir(wallpaper.userId);
636 if (!dir.exists()) {
637 dir.mkdir();
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800638 FileUtils.setPermissions(
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800639 dir.getPath(),
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800640 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
641 -1, -1);
642 }
rpcraig554cb0c2012-07-05 06:41:43 -0400643 File file = new File(dir, WALLPAPER);
644 ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700645 MODE_CREATE|MODE_READ_WRITE);
rpcraig554cb0c2012-07-05 06:41:43 -0400646 if (!SELinux.restorecon(file)) {
647 return null;
648 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800649 wallpaper.name = name;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700650 return fd;
651 } catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800652 Slog.w(TAG, "Error setting wallpaper", e);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700653 }
654 return null;
655 }
656
657 public void setWallpaperComponent(ComponentName name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800658 if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700659 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800660 WallpaperData wallpaper = mWallpaperMap.get(userId);
661 if (wallpaper == null) {
662 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
663 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700664 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
665 synchronized (mLock) {
666 final long ident = Binder.clearCallingIdentity();
667 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800668 wallpaper.imageWallpaperPending = false;
669 bindWallpaperComponentLocked(name, false, true, wallpaper);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700670 } finally {
671 Binder.restoreCallingIdentity(ident);
672 }
673 }
674 }
675
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800676 boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
677 boolean fromUser, WallpaperData wallpaper) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800678 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700679 // Has the component changed?
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700680 if (!force) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800681 if (wallpaper.connection != null) {
682 if (wallpaper.wallpaperComponent == null) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700683 if (componentName == null) {
684 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
685 // Still using default wallpaper.
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700686 return true;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700687 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800688 } else if (wallpaper.wallpaperComponent.equals(componentName)) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700689 // Changing to same wallpaper.
690 if (DEBUG) Slog.v(TAG, "same wallpaper");
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700691 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700692 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700693 }
694 }
695
696 try {
Mike Clerona428b2c2009-11-15 22:53:08 -0800697 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800698 String defaultComponent =
699 mContext.getString(com.android.internal.R.string.default_wallpaper_component);
Mike Clerona428b2c2009-11-15 22:53:08 -0800700 if (defaultComponent != null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800701 // See if there is a default wallpaper component specified
Mike Clerona428b2c2009-11-15 22:53:08 -0800702 componentName = ComponentName.unflattenFromString(defaultComponent);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800703 if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
Mike Cleron322b6ee2009-11-12 07:45:47 -0800704 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800705 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800706 // Fall back to static image wallpaper
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800707 componentName = wallpaper.imageWallpaperComponent;
Mike Cleron322b6ee2009-11-12 07:45:47 -0800708 //clearWallpaperComponentLocked();
709 //return;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800710 if (DEBUG) Slog.v(TAG, "Using image wallpaper");
Mike Cleron322b6ee2009-11-12 07:45:47 -0800711 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700712 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800713 ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700714 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
715 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700716 String msg = "Selected service does not require "
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700717 + android.Manifest.permission.BIND_WALLPAPER
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700718 + ": " + componentName;
719 if (fromUser) {
720 throw new SecurityException(msg);
721 }
722 Slog.w(TAG, msg);
723 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700724 }
725
Dianne Hackborneb034652009-09-07 00:49:58 -0700726 WallpaperInfo wi = null;
727
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700728 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800729 if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700730 // Make sure the selected service is actually a wallpaper service.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700731 List<ResolveInfo> ris = mContext.getPackageManager()
Dianne Hackborneb034652009-09-07 00:49:58 -0700732 .queryIntentServices(intent, PackageManager.GET_META_DATA);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700733 for (int i=0; i<ris.size(); i++) {
734 ServiceInfo rsi = ris.get(i).serviceInfo;
735 if (rsi.name.equals(si.name) &&
736 rsi.packageName.equals(si.packageName)) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700737 try {
738 wi = new WallpaperInfo(mContext, ris.get(i));
739 } catch (XmlPullParserException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700740 if (fromUser) {
741 throw new IllegalArgumentException(e);
742 }
743 Slog.w(TAG, e);
744 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700745 } catch (IOException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700746 if (fromUser) {
747 throw new IllegalArgumentException(e);
748 }
749 Slog.w(TAG, e);
750 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700751 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700752 break;
753 }
754 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700755 if (wi == null) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700756 String msg = "Selected service is not a wallpaper: "
757 + componentName;
758 if (fromUser) {
759 throw new SecurityException(msg);
760 }
761 Slog.w(TAG, msg);
762 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700763 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700764 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700765
766 // Bind the service!
Joe Onorato8a9b2202010-02-26 18:56:32 -0800767 if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800768 WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -0800769 intent.setComponent(componentName);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800770 int serviceUserId = wallpaper.userId;
771 // Because the image wallpaper is running in the system ui
772 if (componentName.equals(wallpaper.imageWallpaperComponent)) {
773 serviceUserId = 0;
774 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -0700775 intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
776 com.android.internal.R.string.wallpaper_binding_label);
777 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
Dianne Hackborneb034652009-09-07 00:49:58 -0700778 mContext, 0,
779 Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
780 mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
781 0));
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800782 if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700783 String msg = "Unable to bind service: "
784 + componentName;
785 if (fromUser) {
786 throw new IllegalArgumentException(msg);
787 }
788 Slog.w(TAG, msg);
789 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700790 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800791 if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
792 detachWallpaperLocked(mLastWallpaper);
793 }
794 wallpaper.wallpaperComponent = componentName;
795 wallpaper.connection = newConn;
796 wallpaper.lastDiedTime = SystemClock.uptimeMillis();
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700797 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800798 if (wallpaper.userId == mCurrentUserId) {
799 if (DEBUG)
800 Slog.v(TAG, "Adding window token: " + newConn.mToken);
801 mIWindowManager.addWindowToken(newConn.mToken,
802 WindowManager.LayoutParams.TYPE_WALLPAPER);
803 mLastWallpaper = wallpaper;
804 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700805 } catch (RemoteException e) {
806 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700807 } catch (PackageManager.NameNotFoundException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700808 String msg = "Unknown component " + componentName;
809 if (fromUser) {
810 throw new IllegalArgumentException(msg);
811 }
812 Slog.w(TAG, msg);
813 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700814 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700815 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700816 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800817
818 void detachWallpaperLocked(WallpaperData wallpaper) {
819 if (wallpaper.connection != null) {
820 if (wallpaper.connection.mEngine != null) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700821 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800822 wallpaper.connection.mEngine.destroy();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700823 } catch (RemoteException e) {
824 }
825 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800826 mContext.unbindService(wallpaper.connection);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700827 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800828 if (DEBUG)
829 Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
830 mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700831 } catch (RemoteException e) {
832 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800833 wallpaper.connection.mService = null;
834 wallpaper.connection.mEngine = null;
835 wallpaper.connection = null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700836 }
837 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800838
839 void clearWallpaperComponentLocked(WallpaperData wallpaper) {
840 wallpaper.wallpaperComponent = null;
841 detachWallpaperLocked(wallpaper);
842 }
843
844 void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700845 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700846 conn.mService.attach(conn, conn.mToken,
847 WindowManager.LayoutParams.TYPE_WALLPAPER, false,
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800848 wallpaper.width, wallpaper.height);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700849 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800850 Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800851 if (!wallpaper.wallpaperUpdating) {
852 bindWallpaperComponentLocked(null, false, false, wallpaper);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800853 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700854 }
855 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800856
857 private void notifyCallbacksLocked(WallpaperData wallpaper) {
858 final int n = wallpaper.callbacks.beginBroadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 for (int i = 0; i < n; i++) {
860 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800861 wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 } catch (RemoteException e) {
863
864 // The RemoteCallbackList will take care of removing
865 // the dead object for us.
866 }
867 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800868 wallpaper.callbacks.finishBroadcast();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
870 mContext.sendBroadcast(intent);
871 }
872
873 private void checkPermission(String permission) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700874 if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
876 + ", must have permission " + permission);
877 }
878 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700879
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800880 private static JournaledFile makeJournaledFile(int userId) {
Amith Yamasani13593602012-03-22 16:16:17 -0700881 final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700882 return new JournaledFile(new File(base), new File(base + ".tmp"));
883 }
884
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800885 private void saveSettingsLocked(WallpaperData wallpaper) {
886 JournaledFile journal = makeJournaledFile(wallpaper.userId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700887 FileOutputStream stream = null;
888 try {
889 stream = new FileOutputStream(journal.chooseForWrite(), false);
890 XmlSerializer out = new FastXmlSerializer();
891 out.setOutput(stream, "utf-8");
892 out.startDocument(null, true);
893
894 out.startTag(null, "wp");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800895 out.attribute(null, "width", Integer.toString(wallpaper.width));
896 out.attribute(null, "height", Integer.toString(wallpaper.height));
897 out.attribute(null, "name", wallpaper.name);
898 if (wallpaper.wallpaperComponent != null
899 && !wallpaper.wallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700900 out.attribute(null, "component",
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800901 wallpaper.wallpaperComponent.flattenToShortString());
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700902 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700903 out.endTag(null, "wp");
904
905 out.endDocument();
906 stream.close();
907 journal.commit();
908 } catch (IOException e) {
909 try {
910 if (stream != null) {
911 stream.close();
912 }
913 } catch (IOException ex) {
914 // Ignore
915 }
916 journal.rollback();
917 }
918 }
919
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800920 private void migrateFromOld() {
921 File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
922 File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
923 if (oldWallpaper.exists()) {
924 File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
925 oldWallpaper.renameTo(newWallpaper);
926 }
927 if (oldInfo.exists()) {
928 File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
929 oldInfo.renameTo(newInfo);
930 }
931 }
932
933 private void loadSettingsLocked(int userId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800934 if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
Mike Clerona428b2c2009-11-15 22:53:08 -0800935
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800936 JournaledFile journal = makeJournaledFile(userId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700937 FileInputStream stream = null;
938 File file = journal.chooseForRead();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800939 if (!file.exists()) {
940 // This should only happen one time, when upgrading from a legacy system
941 migrateFromOld();
942 }
943 WallpaperData wallpaper = mWallpaperMap.get(userId);
944 if (wallpaper == null) {
945 wallpaper = new WallpaperData(userId);
946 mWallpaperMap.put(userId, wallpaper);
947 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700948 boolean success = false;
949 try {
950 stream = new FileInputStream(file);
951 XmlPullParser parser = Xml.newPullParser();
952 parser.setInput(stream, null);
953
954 int type;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700955 do {
956 type = parser.next();
957 if (type == XmlPullParser.START_TAG) {
958 String tag = parser.getName();
959 if ("wp".equals(tag)) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800960 wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
961 wallpaper.height = Integer.parseInt(parser
962 .getAttributeValue(null, "height"));
963 wallpaper.name = parser.getAttributeValue(null, "name");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700964 String comp = parser.getAttributeValue(null, "component");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800965 wallpaper.nextWallpaperComponent = comp != null
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700966 ? ComponentName.unflattenFromString(comp)
967 : null;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800968 if (wallpaper.nextWallpaperComponent == null
969 || "android".equals(wallpaper.nextWallpaperComponent
970 .getPackageName())) {
971 wallpaper.nextWallpaperComponent = wallpaper.imageWallpaperComponent;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700972 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800973
974 if (DEBUG) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800975 Slog.v(TAG, "mWidth:" + wallpaper.width);
976 Slog.v(TAG, "mHeight:" + wallpaper.height);
977 Slog.v(TAG, "mName:" + wallpaper.name);
978 Slog.v(TAG, "mNextWallpaperComponent:"
979 + wallpaper.nextWallpaperComponent);
Mike Clerona428b2c2009-11-15 22:53:08 -0800980 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700981 }
982 }
983 } while (type != XmlPullParser.END_DOCUMENT);
984 success = true;
985 } catch (NullPointerException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800986 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700987 } catch (NumberFormatException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800988 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700989 } catch (XmlPullParserException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800990 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700991 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800992 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700993 } catch (IndexOutOfBoundsException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800994 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700995 }
996 try {
997 if (stream != null) {
998 stream.close();
999 }
1000 } catch (IOException e) {
1001 // Ignore
1002 }
1003
1004 if (!success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001005 wallpaper.width = -1;
1006 wallpaper.height = -1;
1007 wallpaper.name = "";
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001008 }
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001009
1010 // We always want to have some reasonable width hint.
1011 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
1012 Display d = wm.getDefaultDisplay();
1013 int baseSize = d.getMaximumSizeDimension();
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001014 if (wallpaper.width < baseSize) {
1015 wallpaper.width = baseSize;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001016 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001017 if (wallpaper.height < baseSize) {
1018 wallpaper.height = baseSize;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -07001019 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001020 }
1021
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001022 // Called by SystemBackupAgent after files are restored to disk.
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001023 void settingsRestored() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001024 // TODO: If necessary, make it work for secondary users as well. This currently assumes
1025 // restores only to the primary user
Joe Onorato8a9b2202010-02-26 18:56:32 -08001026 if (DEBUG) Slog.v(TAG, "settingsRestored");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001027 WallpaperData wallpaper = null;
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001028 boolean success = false;
1029 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001030 loadSettingsLocked(0);
1031 wallpaper = mWallpaperMap.get(0);
1032 if (wallpaper.nextWallpaperComponent != null
1033 && !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
1034 if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
1035 wallpaper)) {
Christopher Tatee3ab4d02009-12-16 14:03:31 -08001036 // No such live wallpaper or other failure; fall back to the default
1037 // live wallpaper (since the profile being restored indicated that the
1038 // user had selected a live rather than static one).
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001039 bindWallpaperComponentLocked(null, false, false, wallpaper);
Christopher Tatee3ab4d02009-12-16 14:03:31 -08001040 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001041 success = true;
1042 } else {
Mike Clerona428b2c2009-11-15 22:53:08 -08001043 // If there's a wallpaper name, we use that. If that can't be loaded, then we
1044 // use the default.
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001045 if ("".equals(wallpaper.name)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001046 if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
Mike Clerona428b2c2009-11-15 22:53:08 -08001047 success = true;
1048 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001049 if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001050 success = restoreNamedResourceLocked(wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -08001051 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08001052 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
Mike Clerona428b2c2009-11-15 22:53:08 -08001053 if (success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001054 bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
1055 wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -08001056 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001057 }
1058 }
1059
1060 if (!success) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001061 Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
1062 wallpaper.name = "";
1063 getWallpaperDir(0).delete();
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001064 }
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001065
1066 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001067 saveSettingsLocked(wallpaper);
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -07001068 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001069 }
1070
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001071 boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
1072 if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
1073 String resName = wallpaper.name.substring(4);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001074
1075 String pkg = null;
1076 int colon = resName.indexOf(':');
1077 if (colon > 0) {
1078 pkg = resName.substring(0, colon);
1079 }
1080
1081 String ident = null;
1082 int slash = resName.lastIndexOf('/');
1083 if (slash > 0) {
1084 ident = resName.substring(slash+1);
1085 }
1086
1087 String type = null;
1088 if (colon > 0 && slash > 0 && (slash-colon) > 1) {
1089 type = resName.substring(colon+1, slash);
1090 }
1091
1092 if (pkg != null && ident != null && type != null) {
1093 int resId = -1;
1094 InputStream res = null;
1095 FileOutputStream fos = null;
1096 try {
1097 Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
1098 Resources r = c.getResources();
1099 resId = r.getIdentifier(resName, null, null);
1100 if (resId == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001101 Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001102 + " ident=" + ident);
1103 return false;
1104 }
1105
1106 res = r.openRawResource(resId);
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001107 if (wallpaper.wallpaperFile.exists()) {
1108 wallpaper.wallpaperFile.delete();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07001109 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001110 fos = new FileOutputStream(wallpaper.wallpaperFile);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001111
1112 byte[] buffer = new byte[32768];
1113 int amt;
1114 while ((amt=res.read(buffer)) > 0) {
1115 fos.write(buffer, 0, amt);
1116 }
1117 // mWallpaperObserver will notice the close and send the change broadcast
1118
Joe Onorato8a9b2202010-02-26 18:56:32 -08001119 Slog.v(TAG, "Restored wallpaper: " + resName);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001120 return true;
1121 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001122 Slog.e(TAG, "Package name " + pkg + " not found");
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001123 } catch (Resources.NotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001124 Slog.e(TAG, "Resource not found: " + resId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001125 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001126 Slog.e(TAG, "IOException while restoring wallpaper ", e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001127 } finally {
1128 if (res != null) {
1129 try {
1130 res.close();
1131 } catch (IOException ex) {}
1132 }
1133 if (fos != null) {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07001134 FileUtils.sync(fos);
Joe Onorato9bb8fd72009-07-28 18:24:51 -07001135 try {
1136 fos.close();
1137 } catch (IOException ex) {}
1138 }
1139 }
1140 }
1141 }
1142 return false;
1143 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001144
Dianne Hackborneb034652009-09-07 00:49:58 -07001145 @Override
1146 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1147 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1148 != PackageManager.PERMISSION_GRANTED) {
1149
1150 pw.println("Permission Denial: can't dump wallpaper service from from pid="
1151 + Binder.getCallingPid()
1152 + ", uid=" + Binder.getCallingUid());
1153 return;
1154 }
1155
1156 synchronized (mLock) {
1157 pw.println("Current Wallpaper Service state:");
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001158 for (int i = 0; i < mWallpaperMap.size(); i++) {
1159 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
1160 pw.println(" User " + wallpaper.userId + ":");
1161 pw.print(" mWidth=");
1162 pw.print(wallpaper.width);
1163 pw.print(" mHeight=");
1164 pw.println(wallpaper.height);
1165 pw.print(" mName=");
1166 pw.println(wallpaper.name);
1167 pw.print(" mWallpaperComponent=");
1168 pw.println(wallpaper.wallpaperComponent);
1169 if (wallpaper.connection != null) {
1170 WallpaperConnection conn = wallpaper.connection;
1171 pw.print(" Wallpaper connection ");
1172 pw.print(conn);
1173 pw.println(":");
1174 if (conn.mInfo != null) {
1175 pw.print(" mInfo.component=");
1176 pw.println(conn.mInfo.getComponent());
1177 }
1178 pw.print(" mToken=");
1179 pw.println(conn.mToken);
1180 pw.print(" mService=");
1181 pw.println(conn.mService);
1182 pw.print(" mEngine=");
1183 pw.println(conn.mEngine);
1184 pw.print(" mLastDiedTime=");
1185 pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
1186 }
Dianne Hackborneb034652009-09-07 00:49:58 -07001187 }
1188 }
1189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190}