blob: a807f4c8228e6f44f43952922f4b775422fa5159 [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
Amith Yamasani4e2820c2012-08-28 22:17:23 -070022import android.app.AppGlobals;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070023import android.app.IWallpaperManager;
24import android.app.IWallpaperManagerCallback;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070025import android.app.PendingIntent;
Dianne Hackborneb034652009-09-07 00:49:58 -070026import android.app.WallpaperInfo;
Christopher Tate45281862010-03-05 15:46:30 -080027import android.app.backup.BackupManager;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080028import android.app.backup.WallpaperBackupHelper;
Amith Yamasani13593602012-03-22 16:16:17 -070029import android.content.BroadcastReceiver;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070030import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.Context;
32import android.content.Intent;
Amith Yamasani13593602012-03-22 16:16:17 -070033import android.content.IntentFilter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import android.content.ServiceConnection;
Amith Yamasani4e2820c2012-08-28 22:17:23 -070035import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.pm.PackageManager;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070037import android.content.pm.ResolveInfo;
38import android.content.pm.ServiceInfo;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070039import android.content.pm.PackageManager.NameNotFoundException;
40import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.os.Binder;
Dianne Hackborn284ac932009-08-28 10:34:25 -070042import android.os.Bundle;
Amith Yamasani13593602012-03-22 16:16:17 -070043import android.os.Environment;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070044import android.os.FileUtils;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070045import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.os.RemoteException;
47import android.os.FileObserver;
48import android.os.ParcelFileDescriptor;
49import android.os.RemoteCallbackList;
rpcraig554cb0c2012-07-05 06:41:43 -040050import android.os.SELinux;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070051import android.os.ServiceManager;
Dianne Hackborn0cd48872009-08-13 18:51:59 -070052import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070053import android.os.UserHandle;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070054import android.service.wallpaper.IWallpaperConnection;
55import android.service.wallpaper.IWallpaperEngine;
56import android.service.wallpaper.IWallpaperService;
57import android.service.wallpaper.WallpaperService;
Joe Onorato8a9b2202010-02-26 18:56:32 -080058import android.util.Slog;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080059import android.util.SparseArray;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070060import android.util.Xml;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070061import android.view.Display;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070062import android.view.IWindowManager;
63import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
Dianne Hackborneb034652009-09-07 00:49:58 -070065import java.io.FileDescriptor;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070066import java.io.IOException;
67import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import java.io.File;
69import java.io.FileNotFoundException;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070070import java.io.FileInputStream;
71import java.io.FileOutputStream;
Dianne Hackborneb034652009-09-07 00:49:58 -070072import java.io.PrintWriter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070073import java.util.List;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070074
75import org.xmlpull.v1.XmlPullParser;
76import org.xmlpull.v1.XmlPullParserException;
77import org.xmlpull.v1.XmlSerializer;
78
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080079import com.android.internal.content.PackageMonitor;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080080import com.android.internal.util.FastXmlSerializer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070081import com.android.internal.util.JournaledFile;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080082import com.android.server.am.ActivityManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070084class WallpaperManagerService extends IWallpaperManager.Stub {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070085 static final String TAG = "WallpaperService";
Dianne Hackborncbf15042009-08-18 18:29:09 -070086 static final boolean DEBUG = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070087
Romain Guy407ec782011-08-24 17:06:58 -070088 final Object mLock = new Object[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
Dianne Hackborn0cd48872009-08-13 18:51:59 -070090 /**
91 * Minimum time between crashes of a wallpaper service for us to consider
92 * restarting it vs. just reverting to the static wallpaper.
93 */
94 static final long MIN_WALLPAPER_CRASH_TIME = 10000;
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;
Amith Yamasani4e2820c2012-08-28 22:17:23 -0700149 final IPackageManager mIPackageManager;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800150 final MyPackageMonitor mMonitor;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800151 WallpaperData mLastWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800153 SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
Dianne Hackborn07213e62011-08-24 20:05:39 -0700154
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800155 int mCurrentUserId;
Dianne Hackborn07213e62011-08-24 20:05:39 -0700156
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800157 static class WallpaperData {
158
159 int userId;
160
161 File wallpaperFile;
162
163 /**
164 * Client is currently writing a new image wallpaper.
165 */
166 boolean imageWallpaperPending;
167
168 /**
169 * Resource name if using a picture from the wallpaper gallery
170 */
171 String name = "";
172
173 /**
174 * The component name of the currently set live wallpaper.
175 */
176 ComponentName wallpaperComponent;
177
178 /**
179 * The component name of the wallpaper that should be set next.
180 */
181 ComponentName nextWallpaperComponent;
182
183 /**
184 * Name of the component used to display bitmap wallpapers from either the gallery or
185 * built-in wallpapers.
186 */
187 ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
188 "com.android.systemui.ImageWallpaper");
189
190 WallpaperConnection connection;
191 long lastDiedTime;
192 boolean wallpaperUpdating;
193 WallpaperObserver wallpaperObserver;
194
195 /**
196 * List of callbacks registered they should each be notified when the wallpaper is changed.
197 */
198 private RemoteCallbackList<IWallpaperManagerCallback> callbacks
199 = new RemoteCallbackList<IWallpaperManagerCallback>();
200
201 int width = -1;
202 int height = -1;
203
204 WallpaperData(int userId) {
205 this.userId = userId;
206 wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
207 }
208 }
209
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700210 class WallpaperConnection extends IWallpaperConnection.Stub
211 implements ServiceConnection {
Dianne Hackborneb034652009-09-07 00:49:58 -0700212 final WallpaperInfo mInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700213 final Binder mToken = new Binder();
214 IWallpaperService mService;
215 IWallpaperEngine mEngine;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800216 WallpaperData mWallpaper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800218 public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700219 mInfo = info;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800220 mWallpaper = wallpaper;
Dianne Hackborneb034652009-09-07 00:49:58 -0700221 }
222
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700223 public void onServiceConnected(ComponentName name, IBinder service) {
224 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800225 if (mWallpaper.connection == this) {
226 mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700227 mService = IWallpaperService.Stub.asInterface(service);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800228 attachServiceLocked(this, mWallpaper);
Dianne Hackborneb034652009-09-07 00:49:58 -0700229 // XXX should probably do saveSettingsLocked() later
230 // when we have an engine, but I'm not sure about
231 // locking there and anyway we always need to be able to
232 // recover if there is something wrong.
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800233 saveSettingsLocked(mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700234 }
235 }
236 }
237
238 public void onServiceDisconnected(ComponentName name) {
239 synchronized (mLock) {
240 mService = null;
241 mEngine = null;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800242 if (mWallpaper.connection == this) {
243 Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
244 if (!mWallpaper.wallpaperUpdating
245 && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
246 > SystemClock.uptimeMillis()
247 && mWallpaper.userId == mCurrentUserId) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800248 Slog.w(TAG, "Reverting to built-in wallpaper!");
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800249 clearWallpaperLocked(true, mWallpaper.userId);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700250 }
251 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700252 }
253 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800254
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700255 public void attachEngine(IWallpaperEngine engine) {
256 mEngine = engine;
257 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800258
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700259 public ParcelFileDescriptor setWallpaper(String name) {
260 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800261 if (mWallpaper.connection == this) {
262 return updateWallpaperBitmapLocked(name, mWallpaper);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700263 }
264 return null;
265 }
266 }
267 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800268
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800269 class MyPackageMonitor extends PackageMonitor {
270 @Override
271 public void onPackageUpdateFinished(String packageName, int uid) {
272 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800273 for (int i = 0; i < mWallpaperMap.size(); i++) {
274 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
275 if (wallpaper.wallpaperComponent != null
276 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
277 wallpaper.wallpaperUpdating = false;
278 ComponentName comp = wallpaper.wallpaperComponent;
279 clearWallpaperComponentLocked(wallpaper);
280 // Do this only for the current user's wallpaper
281 if (wallpaper.userId == mCurrentUserId
282 && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
283 Slog.w(TAG, "Wallpaper no longer available; reverting to default");
284 clearWallpaperLocked(false, wallpaper.userId);
285 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700286 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800287 }
288 }
289 }
290
291 @Override
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700292 public void onPackageModified(String packageName) {
293 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800294 for (int i = 0; i < mWallpaperMap.size(); i++) {
295 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
296 if (wallpaper.wallpaperComponent == null
297 || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
298 continue;
299 }
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700300 doPackagesChangedLocked(true, wallpaper);
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700301 }
302 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700303 }
304
305 @Override
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800306 public void onPackageUpdateStarted(String packageName, int uid) {
307 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800308 for (int i = 0; i < mWallpaperMap.size(); i++) {
309 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
310 if (wallpaper.wallpaperComponent != null
311 && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
312 wallpaper.wallpaperUpdating = true;
313 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800314 }
315 }
316 }
317
318 @Override
319 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700320 synchronized (mLock) {
321 boolean changed = false;
322 for (int i = 0; i < mWallpaperMap.size(); i++) {
323 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
324 boolean res = doPackagesChangedLocked(doit, wallpaper);
325 changed |= res;
326 }
327 return changed;
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800328 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800329 }
330
331 @Override
332 public void onSomePackagesChanged() {
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700333 synchronized (mLock) {
334 for (int i = 0; i < mWallpaperMap.size(); i++) {
335 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
336 doPackagesChangedLocked(true, wallpaper);
337 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800338 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800339 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800340
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700341 boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800342 boolean changed = false;
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700343 if (wallpaper.wallpaperComponent != null) {
344 int change = isPackageDisappearing(wallpaper.wallpaperComponent
345 .getPackageName());
346 if (change == PACKAGE_PERMANENT_CHANGE
347 || change == PACKAGE_TEMPORARY_CHANGE) {
348 changed = true;
349 if (doit) {
350 Slog.w(TAG, "Wallpaper uninstalled, removing: "
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800351 + wallpaper.wallpaperComponent);
352 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800353 }
354 }
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700355 }
356 if (wallpaper.nextWallpaperComponent != null) {
357 int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
358 .getPackageName());
359 if (change == PACKAGE_PERMANENT_CHANGE
360 || change == PACKAGE_TEMPORARY_CHANGE) {
361 wallpaper.nextWallpaperComponent = null;
362 }
363 }
364 if (wallpaper.wallpaperComponent != null
365 && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
366 try {
367 mContext.getPackageManager().getServiceInfo(
368 wallpaper.wallpaperComponent, 0);
369 } catch (NameNotFoundException e) {
370 Slog.w(TAG, "Wallpaper component gone, removing: "
371 + wallpaper.wallpaperComponent);
372 clearWallpaperLocked(false, wallpaper.userId);
373 }
374 }
375 if (wallpaper.nextWallpaperComponent != null
376 && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
377 try {
378 mContext.getPackageManager().getServiceInfo(
379 wallpaper.nextWallpaperComponent, 0);
380 } catch (NameNotFoundException e) {
381 wallpaper.nextWallpaperComponent = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800382 }
383 }
384 return changed;
385 }
386 }
387
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700388 public WallpaperManagerService(Context context) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800389 if (DEBUG) Slog.v(TAG, "WallpaperService startup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 mContext = context;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700391 mIWindowManager = IWindowManager.Stub.asInterface(
392 ServiceManager.getService(Context.WINDOW_SERVICE));
Amith Yamasani4e2820c2012-08-28 22:17:23 -0700393 mIPackageManager = AppGlobals.getPackageManager();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800394 mMonitor = new MyPackageMonitor();
Dianne Hackbornd0d75032012-04-19 23:12:09 -0700395 mMonitor.register(context, null, true);
Amith Yamasani61f57372012-08-31 12:12:28 -0700396 getWallpaperDir(UserHandle.USER_OWNER).mkdirs();
397 loadSettingsLocked(UserHandle.USER_OWNER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 }
399
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800400 private static File getWallpaperDir(int userId) {
Amith Yamasani61f57372012-08-31 12:12:28 -0700401 return Environment.getUserSystemDirectory(userId);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800402 }
403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 @Override
405 protected void finalize() throws Throwable {
406 super.finalize();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800407 for (int i = 0; i < mWallpaperMap.size(); i++) {
408 WallpaperData wallpaper = mWallpaperMap.valueAt(i);
409 wallpaper.wallpaperObserver.stopWatching();
410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
Amith Yamasani13593602012-03-22 16:16:17 -0700412
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700413 public void systemReady() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800414 if (DEBUG) Slog.v(TAG, "systemReady");
Amith Yamasani61f57372012-08-31 12:12:28 -0700415 WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_OWNER);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800416 switchWallpaper(wallpaper);
417 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
418 wallpaper.wallpaperObserver.startWatching();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800419
Amith Yamasani13593602012-03-22 16:16:17 -0700420 IntentFilter userFilter = new IntentFilter();
421 userFilter.addAction(Intent.ACTION_USER_SWITCHED);
422 userFilter.addAction(Intent.ACTION_USER_REMOVED);
423 mContext.registerReceiver(new BroadcastReceiver() {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800424 @Override
Amith Yamasani13593602012-03-22 16:16:17 -0700425 public void onReceive(Context context, Intent intent) {
426 String action = intent.getAction();
427 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
Amith Yamasani2a003292012-08-14 18:25:45 -0700428 switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
Amith Yamasani13593602012-03-22 16:16:17 -0700429 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
Amith Yamasani2a003292012-08-14 18:25:45 -0700430 removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
Amith Yamasani13593602012-03-22 16:16:17 -0700431 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800432 }
Amith Yamasani13593602012-03-22 16:16:17 -0700433 }, userFilter);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800434 }
435
436 String getName() {
437 return mWallpaperMap.get(0).name;
438 }
439
Amith Yamasani13593602012-03-22 16:16:17 -0700440 void removeUser(int userId) {
441 synchronized (mLock) {
442 WallpaperData wallpaper = mWallpaperMap.get(userId);
443 if (wallpaper != null) {
444 wallpaper.wallpaperObserver.stopWatching();
445 mWallpaperMap.remove(userId);
446 }
447 File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
448 wallpaperFile.delete();
449 File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
450 wallpaperInfoFile.delete();
451 }
452 }
453
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800454 void switchUser(int userId) {
455 synchronized (mLock) {
456 mCurrentUserId = userId;
457 WallpaperData wallpaper = mWallpaperMap.get(userId);
458 if (wallpaper == null) {
459 wallpaper = new WallpaperData(userId);
460 mWallpaperMap.put(userId, wallpaper);
461 loadSettingsLocked(userId);
462 wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
463 wallpaper.wallpaperObserver.startWatching();
464 }
465 switchWallpaper(wallpaper);
466 }
467 }
468
469 void switchWallpaper(WallpaperData wallpaper) {
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700470 synchronized (mLock) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700471 RuntimeException e = null;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700472 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800473 ComponentName cname = wallpaper.wallpaperComponent != null ?
474 wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
475 if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700476 return;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700477 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700478 } catch (RuntimeException e1) {
479 e = e1;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700480 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700481 Slog.w(TAG, "Failure starting previous wallpaper", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800482 clearWallpaperLocked(false, wallpaper.userId);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800483 }
484 }
485
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800486 public void clearWallpaper() {
487 if (DEBUG) Slog.v(TAG, "clearWallpaper");
488 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700489 clearWallpaperLocked(false, UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800490 }
491 }
492
493 void clearWallpaperLocked(boolean defaultFailed, int userId) {
494 WallpaperData wallpaper = mWallpaperMap.get(userId);
495 File f = new File(getWallpaperDir(userId), WALLPAPER);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800496 if (f.exists()) {
497 f.delete();
498 }
499 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700500 RuntimeException e = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800501 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800502 wallpaper.imageWallpaperPending = false;
503 if (userId != mCurrentUserId) return;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700504 if (bindWallpaperComponentLocked(defaultFailed
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800505 ? wallpaper.imageWallpaperComponent
506 : null, true, false, wallpaper)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700507 return;
508 }
509 } catch (IllegalArgumentException e1) {
510 e = e1;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800511 } finally {
512 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700514
515 // This can happen if the default wallpaper component doesn't
516 // exist. This should be a system configuration problem, but
517 // let's not let it crash the system and just live with no
518 // wallpaper.
519 Slog.e(TAG, "Default wallpaper component not found!", e);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800520 clearWallpaperComponentLocked(wallpaper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 }
522
523 public void setDimensionHints(int width, int height) throws RemoteException {
524 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
525
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700526 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800527 WallpaperData wallpaper = mWallpaperMap.get(userId);
528 if (wallpaper == null) {
529 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 if (width <= 0 || height <= 0) {
532 throw new IllegalArgumentException("width and height must be > 0");
533 }
534
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700535 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800536 if (width != wallpaper.width || height != wallpaper.height) {
537 wallpaper.width = width;
538 wallpaper.height = height;
539 saveSettingsLocked(wallpaper);
540 if (mCurrentUserId != userId) return; // Don't change the properties now
541 if (wallpaper.connection != null) {
542 if (wallpaper.connection.mEngine != null) {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700543 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800544 wallpaper.connection.mEngine.setDesiredSize(
Dianne Hackborn284ac932009-08-28 10:34:25 -0700545 width, height);
546 } catch (RemoteException e) {
547 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800548 notifyCallbacksLocked(wallpaper);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700549 }
550 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700551 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 }
553 }
554
555 public int getWidthHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700556 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700557 WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800558 return wallpaper.width;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 }
561
562 public int getHeightHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700563 synchronized (mLock) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700564 WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800565 return wallpaper.height;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 }
568
Dianne Hackborn284ac932009-08-28 10:34:25 -0700569 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
570 Bundle outParams) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700571 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800572 // This returns the current user's wallpaper, if called by a system service. Else it
573 // returns the wallpaper for the calling user.
574 int callingUid = Binder.getCallingUid();
575 int wallpaperUserId = 0;
576 if (callingUid == android.os.Process.SYSTEM_UID) {
577 wallpaperUserId = mCurrentUserId;
578 } else {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700579 wallpaperUserId = UserHandle.getUserId(callingUid);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800580 }
581 WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700582 try {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700583 if (outParams != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800584 outParams.putInt("width", wallpaper.width);
585 outParams.putInt("height", wallpaper.height);
Dianne Hackborn284ac932009-08-28 10:34:25 -0700586 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800587 wallpaper.callbacks.register(cb);
588 File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700589 if (!f.exists()) {
590 return null;
591 }
592 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
593 } catch (FileNotFoundException e) {
594 /* Shouldn't happen as we check to see if the file exists */
Joe Onorato8a9b2202010-02-26 18:56:32 -0800595 Slog.w(TAG, "Error getting wallpaper", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700597 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 }
600
Dianne Hackborneb034652009-09-07 00:49:58 -0700601 public WallpaperInfo getWallpaperInfo() {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700602 int userId = UserHandle.getCallingUserId();
Dianne Hackborneb034652009-09-07 00:49:58 -0700603 synchronized (mLock) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800604 WallpaperData wallpaper = mWallpaperMap.get(userId);
605 if (wallpaper.connection != null) {
606 return wallpaper.connection.mInfo;
Dianne Hackborneb034652009-09-07 00:49:58 -0700607 }
608 return null;
609 }
610 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800611
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700612 public ParcelFileDescriptor setWallpaper(String name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800613 if (DEBUG) Slog.v(TAG, "setWallpaper");
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700614 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800615 WallpaperData wallpaper = mWallpaperMap.get(userId);
616 if (wallpaper == null) {
617 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
618 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 checkPermission(android.Manifest.permission.SET_WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700620 synchronized (mLock) {
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700621 final long ident = Binder.clearCallingIdentity();
622 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800623 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700624 if (pfd != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800625 wallpaper.imageWallpaperPending = true;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700626 }
627 return pfd;
628 } finally {
629 Binder.restoreCallingIdentity(ident);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 }
632 }
633
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800634 ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700635 if (name == null) name = "";
636 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800637 File dir = getWallpaperDir(wallpaper.userId);
638 if (!dir.exists()) {
639 dir.mkdir();
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800640 FileUtils.setPermissions(
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800641 dir.getPath(),
Dianne Hackbornebac48c2011-11-29 18:01:50 -0800642 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
643 -1, -1);
644 }
rpcraig554cb0c2012-07-05 06:41:43 -0400645 File file = new File(dir, WALLPAPER);
646 ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700647 MODE_CREATE|MODE_READ_WRITE);
rpcraig554cb0c2012-07-05 06:41:43 -0400648 if (!SELinux.restorecon(file)) {
649 return null;
650 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800651 wallpaper.name = name;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700652 return fd;
653 } catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800654 Slog.w(TAG, "Error setting wallpaper", e);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700655 }
656 return null;
657 }
658
659 public void setWallpaperComponent(ComponentName name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800660 if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700661 int userId = UserHandle.getCallingUserId();
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800662 WallpaperData wallpaper = mWallpaperMap.get(userId);
663 if (wallpaper == null) {
664 throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
665 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700666 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
667 synchronized (mLock) {
668 final long ident = Binder.clearCallingIdentity();
669 try {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800670 wallpaper.imageWallpaperPending = false;
671 bindWallpaperComponentLocked(name, false, true, wallpaper);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700672 } finally {
673 Binder.restoreCallingIdentity(ident);
674 }
675 }
676 }
677
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800678 boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
679 boolean fromUser, WallpaperData wallpaper) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800680 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700681 // Has the component changed?
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700682 if (!force) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800683 if (wallpaper.connection != null) {
684 if (wallpaper.wallpaperComponent == null) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700685 if (componentName == null) {
686 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
687 // Still using default wallpaper.
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700688 return true;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700689 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800690 } else if (wallpaper.wallpaperComponent.equals(componentName)) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700691 // Changing to same wallpaper.
692 if (DEBUG) Slog.v(TAG, "same wallpaper");
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700693 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700694 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700695 }
696 }
697
698 try {
Mike Clerona428b2c2009-11-15 22:53:08 -0800699 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800700 String defaultComponent =
701 mContext.getString(com.android.internal.R.string.default_wallpaper_component);
Mike Clerona428b2c2009-11-15 22:53:08 -0800702 if (defaultComponent != null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800703 // See if there is a default wallpaper component specified
Mike Clerona428b2c2009-11-15 22:53:08 -0800704 componentName = ComponentName.unflattenFromString(defaultComponent);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800705 if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
Mike Cleron322b6ee2009-11-12 07:45:47 -0800706 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800707 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800708 // Fall back to static image wallpaper
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800709 componentName = wallpaper.imageWallpaperComponent;
Mike Cleron322b6ee2009-11-12 07:45:47 -0800710 //clearWallpaperComponentLocked();
711 //return;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800712 if (DEBUG) Slog.v(TAG, "Using image wallpaper");
Mike Cleron322b6ee2009-11-12 07:45:47 -0800713 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700714 }
Amith Yamasani4e2820c2012-08-28 22:17:23 -0700715 int serviceUserId = wallpaper.userId;
716 ServiceInfo si = mIPackageManager.getServiceInfo(componentName,
717 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, serviceUserId);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700718 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700719 String msg = "Selected service does not require "
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700720 + android.Manifest.permission.BIND_WALLPAPER
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700721 + ": " + componentName;
722 if (fromUser) {
723 throw new SecurityException(msg);
724 }
725 Slog.w(TAG, msg);
726 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700727 }
728
Dianne Hackborneb034652009-09-07 00:49:58 -0700729 WallpaperInfo wi = null;
730
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700731 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800732 if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700733 // Make sure the selected service is actually a wallpaper service.
Amith Yamasani4e2820c2012-08-28 22:17:23 -0700734 List<ResolveInfo> ris =
735 mIPackageManager.queryIntentServices(intent,
736 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
737 PackageManager.GET_META_DATA, serviceUserId);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700738 for (int i=0; i<ris.size(); i++) {
739 ServiceInfo rsi = ris.get(i).serviceInfo;
740 if (rsi.name.equals(si.name) &&
741 rsi.packageName.equals(si.packageName)) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700742 try {
743 wi = new WallpaperInfo(mContext, ris.get(i));
744 } catch (XmlPullParserException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700745 if (fromUser) {
746 throw new IllegalArgumentException(e);
747 }
748 Slog.w(TAG, e);
749 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700750 } catch (IOException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700751 if (fromUser) {
752 throw new IllegalArgumentException(e);
753 }
754 Slog.w(TAG, e);
755 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700756 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700757 break;
758 }
759 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700760 if (wi == null) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700761 String msg = "Selected service is not a wallpaper: "
762 + componentName;
763 if (fromUser) {
764 throw new SecurityException(msg);
765 }
766 Slog.w(TAG, msg);
767 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700768 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700769 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700770
771 // Bind the service!
Joe Onorato8a9b2202010-02-26 18:56:32 -0800772 if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
Amith Yamasani37ce3a82012-02-06 12:04:42 -0800773 WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
Mike Clerona428b2c2009-11-15 22:53:08 -0800774 intent.setComponent(componentName);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -0700775 intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
776 com.android.internal.R.string.wallpaper_binding_label);
Dianne Hackborn41203752012-08-31 14:05:51 -0700777 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
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)),
Dianne Hackborn41203752012-08-31 14:05:51 -0700781 0, null, new UserHandle(serviceUserId)));
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 }
Amith Yamasani4e2820c2012-08-28 22:17:23 -0700807 } catch (RemoteException e) {
808 String msg = "Remote exception for " + componentName + "\n" + e;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700809 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);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700870 mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 }
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 Yamasani61f57372012-08-31 12:12:28 -0700881 final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
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}