blob: a0e28ed47f9771ff967b7396a95a1ee5789cdaeb [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;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070027import android.content.ComponentName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.content.Context;
29import android.content.Intent;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070030import android.content.ServiceConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.pm.PackageManager;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070032import android.content.pm.ResolveInfo;
33import android.content.pm.ServiceInfo;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070034import android.content.pm.PackageManager.NameNotFoundException;
35import android.content.res.Resources;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.Binder;
Dianne Hackborn284ac932009-08-28 10:34:25 -070037import android.os.Bundle;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070038import android.os.FileUtils;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070039import android.os.IBinder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.os.RemoteException;
41import android.os.FileObserver;
42import android.os.ParcelFileDescriptor;
43import android.os.RemoteCallbackList;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070044import android.os.ServiceManager;
Dianne Hackborn0cd48872009-08-13 18:51:59 -070045import android.os.SystemClock;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070046import android.service.wallpaper.IWallpaperConnection;
47import android.service.wallpaper.IWallpaperEngine;
48import android.service.wallpaper.IWallpaperService;
49import android.service.wallpaper.WallpaperService;
Joe Onorato8a9b2202010-02-26 18:56:32 -080050import android.util.Slog;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070051import android.util.Xml;
Dianne Hackborn44bc17c2011-04-20 18:18:51 -070052import android.view.Display;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070053import android.view.IWindowManager;
54import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055
Dianne Hackborneb034652009-09-07 00:49:58 -070056import java.io.FileDescriptor;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070057import java.io.IOException;
58import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import java.io.File;
60import java.io.FileNotFoundException;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070061import java.io.FileInputStream;
62import java.io.FileOutputStream;
Dianne Hackborneb034652009-09-07 00:49:58 -070063import java.io.PrintWriter;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070064import java.util.List;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070065
66import org.xmlpull.v1.XmlPullParser;
67import org.xmlpull.v1.XmlPullParserException;
68import org.xmlpull.v1.XmlSerializer;
69
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080070import com.android.internal.content.PackageMonitor;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080071import com.android.internal.util.FastXmlSerializer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070072import com.android.internal.util.JournaledFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070074class WallpaperManagerService extends IWallpaperManager.Stub {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070075 static final String TAG = "WallpaperService";
Dianne Hackborncbf15042009-08-18 18:29:09 -070076 static final boolean DEBUG = false;
Joe Onorato9bb8fd72009-07-28 18:24:51 -070077
Romain Guy407ec782011-08-24 17:06:58 -070078 final Object mLock = new Object[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Dianne Hackborn0cd48872009-08-13 18:51:59 -070080 /**
81 * Minimum time between crashes of a wallpaper service for us to consider
82 * restarting it vs. just reverting to the static wallpaper.
83 */
84 static final long MIN_WALLPAPER_CRASH_TIME = 10000;
85
86 static final File WALLPAPER_DIR = new File(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 "/data/data/com.android.settings/files");
Dianne Hackborn0cd48872009-08-13 18:51:59 -070088 static final String WALLPAPER = "wallpaper";
89 static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 /**
92 * List of callbacks registered they should each be notified
93 * when the wallpaper is changed.
94 */
Dianne Hackborn8cc6a502009-08-05 21:29:42 -070095 private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks
96 = new RemoteCallbackList<IWallpaperManagerCallback>();
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 */
104 private final FileObserver mWallpaperObserver = new FileObserver(
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700105 WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 @Override
107 public void onEvent(int event, String path) {
Joe Onoratoe712ee32009-07-29 16:23:58 -0700108 if (path == null) {
109 return;
110 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700111 synchronized (mLock) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700112 // changing the wallpaper means we'll need to back up the new one
113 long origId = Binder.clearCallingIdentity();
114 BackupManager bm = new BackupManager(mContext);
115 bm.dataChanged();
116 Binder.restoreCallingIdentity(origId);
117
118 File changedFile = new File(WALLPAPER_DIR, path);
119 if (WALLPAPER_FILE.equals(changedFile)) {
120 notifyCallbacksLocked();
Dianne Hackborn07213e62011-08-24 20:05:39 -0700121 if (mWallpaperComponent == null || mImageWallpaperPending) {
122 mImageWallpaperPending = false;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700123 bindWallpaperComponentLocked(mImageWallpaperComponent,
124 true, false);
Dianne Hackborn07213e62011-08-24 20:05:39 -0700125 saveSettingsLocked();
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700126 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 }
129 }
130 };
131
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700132 final Context mContext;
133 final IWindowManager mIWindowManager;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800134 final MyPackageMonitor mMonitor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700136 int mWidth = -1;
137 int mHeight = -1;
Dianne Hackborn07213e62011-08-24 20:05:39 -0700138
139 /**
140 * Client is currently writing a new image wallpaper.
141 */
142 boolean mImageWallpaperPending;
143
Mike Clerona428b2c2009-11-15 22:53:08 -0800144 /**
145 * Resource name if using a picture from the wallpaper gallery
146 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700147 String mName = "";
Mike Clerond6c0b842009-11-13 16:37:27 -0800148
149 /**
Mike Clerona428b2c2009-11-15 22:53:08 -0800150 * The component name of the currently set live wallpaper.
Mike Clerond6c0b842009-11-13 16:37:27 -0800151 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700152 ComponentName mWallpaperComponent;
Mike Clerona428b2c2009-11-15 22:53:08 -0800153
154 /**
155 * The component name of the wallpaper that should be set next.
156 */
157 ComponentName mNextWallpaperComponent;
158
159 /**
160 * Name of the component used to display bitmap wallpapers from either the gallery or
161 * built-in wallpapers.
162 */
Dianne Hackbornba398392011-08-01 16:11:57 -0700163 ComponentName mImageWallpaperComponent = new ComponentName("com.android.systemui",
164 "com.android.systemui.ImageWallpaper");
Mike Clerona428b2c2009-11-15 22:53:08 -0800165
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700166 WallpaperConnection mWallpaperConnection;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700167 long mLastDiedTime;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800168 boolean mWallpaperUpdating;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700169
170 class WallpaperConnection extends IWallpaperConnection.Stub
171 implements ServiceConnection {
Dianne Hackborneb034652009-09-07 00:49:58 -0700172 final WallpaperInfo mInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700173 final Binder mToken = new Binder();
174 IWallpaperService mService;
175 IWallpaperEngine mEngine;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176
Dianne Hackborneb034652009-09-07 00:49:58 -0700177 public WallpaperConnection(WallpaperInfo info) {
178 mInfo = info;
179 }
180
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700181 public void onServiceConnected(ComponentName name, IBinder service) {
182 synchronized (mLock) {
183 if (mWallpaperConnection == this) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800184 mLastDiedTime = SystemClock.uptimeMillis();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700185 mService = IWallpaperService.Stub.asInterface(service);
186 attachServiceLocked(this);
Dianne Hackborneb034652009-09-07 00:49:58 -0700187 // XXX should probably do saveSettingsLocked() later
188 // when we have an engine, but I'm not sure about
189 // locking there and anyway we always need to be able to
190 // recover if there is something wrong.
191 saveSettingsLocked();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700192 }
193 }
194 }
195
196 public void onServiceDisconnected(ComponentName name) {
197 synchronized (mLock) {
198 mService = null;
199 mEngine = null;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700200 if (mWallpaperConnection == this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800201 Slog.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800202 if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
203 > SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800204 Slog.w(TAG, "Reverting to built-in wallpaper!");
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700205 clearWallpaperLocked(true);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700206 }
207 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700208 }
209 }
210
211 public void attachEngine(IWallpaperEngine engine) {
212 mEngine = engine;
213 }
214
215 public ParcelFileDescriptor setWallpaper(String name) {
216 synchronized (mLock) {
217 if (mWallpaperConnection == this) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700218 return updateWallpaperBitmapLocked(name);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700219 }
220 return null;
221 }
222 }
223 }
224
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800225 class MyPackageMonitor extends PackageMonitor {
226 @Override
227 public void onPackageUpdateFinished(String packageName, int uid) {
228 synchronized (mLock) {
229 if (mWallpaperComponent != null &&
230 mWallpaperComponent.getPackageName().equals(packageName)) {
231 mWallpaperUpdating = false;
232 ComponentName comp = mWallpaperComponent;
233 clearWallpaperComponentLocked();
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700234 if (!bindWallpaperComponentLocked(comp, false, false)) {
235 Slog.w(TAG, "Wallpaper no longer available; reverting to default");
236 clearWallpaperLocked(false);
237 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800238 }
239 }
240 }
241
242 @Override
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700243 public void onPackageModified(String packageName) {
244 synchronized (mLock) {
245 if (mWallpaperComponent == null ||
246 !mWallpaperComponent.getPackageName().equals(packageName)) {
247 return;
248 }
249 }
250 doPackagesChanged(true);
251 }
252
253 @Override
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800254 public void onPackageUpdateStarted(String packageName, int uid) {
255 synchronized (mLock) {
256 if (mWallpaperComponent != null &&
257 mWallpaperComponent.getPackageName().equals(packageName)) {
258 mWallpaperUpdating = true;
259 }
260 }
261 }
262
263 @Override
264 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
265 return doPackagesChanged(doit);
266 }
267
268 @Override
269 public void onSomePackagesChanged() {
270 doPackagesChanged(true);
271 }
272
273 boolean doPackagesChanged(boolean doit) {
274 boolean changed = false;
275 synchronized (mLock) {
276 if (mWallpaperComponent != null) {
277 int change = isPackageDisappearing(mWallpaperComponent.getPackageName());
278 if (change == PACKAGE_PERMANENT_CHANGE
279 || change == PACKAGE_TEMPORARY_CHANGE) {
280 changed = true;
281 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800282 Slog.w(TAG, "Wallpaper uninstalled, removing: " + mWallpaperComponent);
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700283 clearWallpaperLocked(false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800284 }
285 }
286 }
287 if (mNextWallpaperComponent != null) {
288 int change = isPackageDisappearing(mNextWallpaperComponent.getPackageName());
289 if (change == PACKAGE_PERMANENT_CHANGE
290 || change == PACKAGE_TEMPORARY_CHANGE) {
291 mNextWallpaperComponent = null;
292 }
293 }
294 if (mWallpaperComponent != null
295 && isPackageModified(mWallpaperComponent.getPackageName())) {
296 try {
297 mContext.getPackageManager().getServiceInfo(
298 mWallpaperComponent, 0);
299 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800300 Slog.w(TAG, "Wallpaper component gone, removing: " + mWallpaperComponent);
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700301 clearWallpaperLocked(false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800302 }
303 }
304 if (mNextWallpaperComponent != null
305 && isPackageModified(mNextWallpaperComponent.getPackageName())) {
306 try {
307 mContext.getPackageManager().getServiceInfo(
308 mNextWallpaperComponent, 0);
309 } catch (NameNotFoundException e) {
310 mNextWallpaperComponent = null;
311 }
312 }
313 }
314 return changed;
315 }
316 }
317
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700318 public WallpaperManagerService(Context context) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800319 if (DEBUG) Slog.v(TAG, "WallpaperService startup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 mContext = context;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700321 mIWindowManager = IWindowManager.Stub.asInterface(
322 ServiceManager.getService(Context.WINDOW_SERVICE));
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800323 mMonitor = new MyPackageMonitor();
324 mMonitor.register(context, true);
Joe Onoratoe712ee32009-07-29 16:23:58 -0700325 WALLPAPER_DIR.mkdirs();
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700326 loadSettingsLocked();
Joe Onoratoe712ee32009-07-29 16:23:58 -0700327 mWallpaperObserver.startWatching();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 }
329
330 @Override
331 protected void finalize() throws Throwable {
332 super.finalize();
333 mWallpaperObserver.stopWatching();
334 }
335
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700336 public void systemReady() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800337 if (DEBUG) Slog.v(TAG, "systemReady");
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700338 synchronized (mLock) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700339 RuntimeException e = null;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700340 try {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700341 if (bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
342 return;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700343 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700344 } catch (RuntimeException e1) {
345 e = e1;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700346 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700347 Slog.w(TAG, "Failure starting previous wallpaper", e);
348 clearWallpaperLocked(false);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700349 }
350 }
351
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352 public void clearWallpaper() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800353 if (DEBUG) Slog.v(TAG, "clearWallpaper");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700354 synchronized (mLock) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700355 clearWallpaperLocked(false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800356 }
357 }
358
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700359 public void clearWallpaperLocked(boolean defaultFailed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800360 File f = WALLPAPER_FILE;
361 if (f.exists()) {
362 f.delete();
363 }
364 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700365 RuntimeException e = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800366 try {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700367 mImageWallpaperPending = false;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700368 if (bindWallpaperComponentLocked(defaultFailed
369 ? mImageWallpaperComponent : null, true, false)) {
370 return;
371 }
372 } catch (IllegalArgumentException e1) {
373 e = e1;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800374 } finally {
375 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700377
378 // This can happen if the default wallpaper component doesn't
379 // exist. This should be a system configuration problem, but
380 // let's not let it crash the system and just live with no
381 // wallpaper.
382 Slog.e(TAG, "Default wallpaper component not found!", e);
383 clearWallpaperComponentLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 }
385
386 public void setDimensionHints(int width, int height) throws RemoteException {
387 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
388
389 if (width <= 0 || height <= 0) {
390 throw new IllegalArgumentException("width and height must be > 0");
391 }
392
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700393 synchronized (mLock) {
394 if (width != mWidth || height != mHeight) {
395 mWidth = width;
396 mHeight = height;
397 saveSettingsLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -0700398 if (mWallpaperConnection != null) {
399 if (mWallpaperConnection.mEngine != null) {
400 try {
401 mWallpaperConnection.mEngine.setDesiredSize(
402 width, height);
403 } catch (RemoteException e) {
404 }
405 notifyCallbacksLocked();
406 }
407 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
410 }
411
412 public int getWidthHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700413 synchronized (mLock) {
414 return mWidth;
415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 }
417
418 public int getHeightHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700419 synchronized (mLock) {
420 return mHeight;
421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
423
Dianne Hackborn284ac932009-08-28 10:34:25 -0700424 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
425 Bundle outParams) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700426 synchronized (mLock) {
427 try {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700428 if (outParams != null) {
429 outParams.putInt("width", mWidth);
430 outParams.putInt("height", mHeight);
431 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700432 mCallbacks.register(cb);
433 File f = WALLPAPER_FILE;
434 if (!f.exists()) {
435 return null;
436 }
437 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
438 } catch (FileNotFoundException e) {
439 /* Shouldn't happen as we check to see if the file exists */
Joe Onorato8a9b2202010-02-26 18:56:32 -0800440 Slog.w(TAG, "Error getting wallpaper", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700442 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 }
445
Dianne Hackborneb034652009-09-07 00:49:58 -0700446 public WallpaperInfo getWallpaperInfo() {
447 synchronized (mLock) {
448 if (mWallpaperConnection != null) {
449 return mWallpaperConnection.mInfo;
450 }
451 return null;
452 }
453 }
454
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700455 public ParcelFileDescriptor setWallpaper(String name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800456 if (DEBUG) Slog.v(TAG, "setWallpaper");
Mike Clerona428b2c2009-11-15 22:53:08 -0800457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 checkPermission(android.Manifest.permission.SET_WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700459 synchronized (mLock) {
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700460 final long ident = Binder.clearCallingIdentity();
461 try {
462 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
463 if (pfd != null) {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700464 mImageWallpaperPending = true;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700465 }
466 return pfd;
467 } finally {
468 Binder.restoreCallingIdentity(ident);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 }
471 }
472
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700473 ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
474 if (name == null) name = "";
475 try {
476 ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
477 MODE_CREATE|MODE_READ_WRITE);
478 mName = name;
479 return fd;
480 } catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800481 Slog.w(TAG, "Error setting wallpaper", e);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700482 }
483 return null;
484 }
485
486 public void setWallpaperComponent(ComponentName name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800487 if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700488 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
489 synchronized (mLock) {
490 final long ident = Binder.clearCallingIdentity();
491 try {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700492 mImageWallpaperPending = false;
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700493 bindWallpaperComponentLocked(name, false, true);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700494 } finally {
495 Binder.restoreCallingIdentity(ident);
496 }
497 }
498 }
499
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700500 boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean fromUser) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800501 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
Mike Clerona428b2c2009-11-15 22:53:08 -0800502
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700503 // Has the component changed?
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700504 if (!force) {
505 if (mWallpaperConnection != null) {
506 if (mWallpaperComponent == null) {
507 if (componentName == null) {
508 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
509 // Still using default wallpaper.
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700510 return true;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700511 }
512 } else if (mWallpaperComponent.equals(componentName)) {
513 // Changing to same wallpaper.
514 if (DEBUG) Slog.v(TAG, "same wallpaper");
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700515 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700516 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700517 }
518 }
519
520 try {
Mike Clerona428b2c2009-11-15 22:53:08 -0800521 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800522 String defaultComponent =
523 mContext.getString(com.android.internal.R.string.default_wallpaper_component);
Mike Clerona428b2c2009-11-15 22:53:08 -0800524 if (defaultComponent != null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800525 // See if there is a default wallpaper component specified
Mike Clerona428b2c2009-11-15 22:53:08 -0800526 componentName = ComponentName.unflattenFromString(defaultComponent);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800527 if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
Mike Cleron322b6ee2009-11-12 07:45:47 -0800528 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800529 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800530 // Fall back to static image wallpaper
Mike Clerona428b2c2009-11-15 22:53:08 -0800531 componentName = mImageWallpaperComponent;
Mike Cleron322b6ee2009-11-12 07:45:47 -0800532 //clearWallpaperComponentLocked();
533 //return;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800534 if (DEBUG) Slog.v(TAG, "Using image wallpaper");
Mike Cleron322b6ee2009-11-12 07:45:47 -0800535 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700536 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800537 ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700538 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
539 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700540 String msg = "Selected service does not require "
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700541 + android.Manifest.permission.BIND_WALLPAPER
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700542 + ": " + componentName;
543 if (fromUser) {
544 throw new SecurityException(msg);
545 }
546 Slog.w(TAG, msg);
547 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700548 }
549
Dianne Hackborneb034652009-09-07 00:49:58 -0700550 WallpaperInfo wi = null;
551
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700552 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
Mike Clerona428b2c2009-11-15 22:53:08 -0800553 if (componentName != null && !componentName.equals(mImageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700554 // Make sure the selected service is actually a wallpaper service.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700555 List<ResolveInfo> ris = mContext.getPackageManager()
Dianne Hackborneb034652009-09-07 00:49:58 -0700556 .queryIntentServices(intent, PackageManager.GET_META_DATA);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700557 for (int i=0; i<ris.size(); i++) {
558 ServiceInfo rsi = ris.get(i).serviceInfo;
559 if (rsi.name.equals(si.name) &&
560 rsi.packageName.equals(si.packageName)) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700561 try {
562 wi = new WallpaperInfo(mContext, ris.get(i));
563 } catch (XmlPullParserException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700564 if (fromUser) {
565 throw new IllegalArgumentException(e);
566 }
567 Slog.w(TAG, e);
568 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700569 } catch (IOException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700570 if (fromUser) {
571 throw new IllegalArgumentException(e);
572 }
573 Slog.w(TAG, e);
574 return false;
Dianne Hackborneb034652009-09-07 00:49:58 -0700575 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700576 break;
577 }
578 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700579 if (wi == null) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700580 String msg = "Selected service is not a wallpaper: "
581 + componentName;
582 if (fromUser) {
583 throw new SecurityException(msg);
584 }
585 Slog.w(TAG, msg);
586 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700587 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700588 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700589
590 // Bind the service!
Joe Onorato8a9b2202010-02-26 18:56:32 -0800591 if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
Dianne Hackborneb034652009-09-07 00:49:58 -0700592 WallpaperConnection newConn = new WallpaperConnection(wi);
Mike Clerona428b2c2009-11-15 22:53:08 -0800593 intent.setComponent(componentName);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -0700594 intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
595 com.android.internal.R.string.wallpaper_binding_label);
596 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
Dianne Hackborneb034652009-09-07 00:49:58 -0700597 mContext, 0,
598 Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
599 mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
600 0));
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700601 if (!mContext.bindService(intent, newConn,
602 Context.BIND_AUTO_CREATE)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700603 String msg = "Unable to bind service: "
604 + componentName;
605 if (fromUser) {
606 throw new IllegalArgumentException(msg);
607 }
608 Slog.w(TAG, msg);
609 return false;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700610 }
611
612 clearWallpaperComponentLocked();
Mike Cleron322b6ee2009-11-12 07:45:47 -0800613 mWallpaperComponent = componentName;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700614 mWallpaperConnection = newConn;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700615 mLastDiedTime = SystemClock.uptimeMillis();
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700616 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800617 if (DEBUG) Slog.v(TAG, "Adding window token: " + newConn.mToken);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700618 mIWindowManager.addWindowToken(newConn.mToken,
619 WindowManager.LayoutParams.TYPE_WALLPAPER);
620 } catch (RemoteException e) {
621 }
622
623 } catch (PackageManager.NameNotFoundException e) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700624 String msg = "Unknown component " + componentName;
625 if (fromUser) {
626 throw new IllegalArgumentException(msg);
627 }
628 Slog.w(TAG, msg);
629 return false;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700630 }
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700631 return true;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700632 }
633
634 void clearWallpaperComponentLocked() {
635 mWallpaperComponent = null;
636 if (mWallpaperConnection != null) {
637 if (mWallpaperConnection.mEngine != null) {
638 try {
639 mWallpaperConnection.mEngine.destroy();
640 } catch (RemoteException e) {
641 }
642 }
643 mContext.unbindService(mWallpaperConnection);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700644 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800645 if (DEBUG) Slog.v(TAG, "Removing window token: "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700646 + mWallpaperConnection.mToken);
647 mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
648 } catch (RemoteException e) {
649 }
Vairavan Srinivasanfdfc1b22010-12-23 14:05:44 -0800650 mWallpaperConnection.mService = null;
651 mWallpaperConnection.mEngine = null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700652 mWallpaperConnection = null;
653 }
654 }
655
656 void attachServiceLocked(WallpaperConnection conn) {
657 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700658 conn.mService.attach(conn, conn.mToken,
659 WindowManager.LayoutParams.TYPE_WALLPAPER, false,
660 mWidth, mHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700661 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800662 Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800663 if (!mWallpaperUpdating) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700664 bindWallpaperComponentLocked(null, false, false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800665 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700666 }
667 }
668
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700669 private void notifyCallbacksLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 final int n = mCallbacks.beginBroadcast();
671 for (int i = 0; i < n; i++) {
672 try {
673 mCallbacks.getBroadcastItem(i).onWallpaperChanged();
674 } catch (RemoteException e) {
675
676 // The RemoteCallbackList will take care of removing
677 // the dead object for us.
678 }
679 }
680 mCallbacks.finishBroadcast();
681 final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
682 mContext.sendBroadcast(intent);
683 }
684
685 private void checkPermission(String permission) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700686 if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
688 + ", must have permission " + permission);
689 }
690 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700691
692 private static JournaledFile makeJournaledFile() {
693 final String base = "/data/system/wallpaper_info.xml";
694 return new JournaledFile(new File(base), new File(base + ".tmp"));
695 }
696
697 private void saveSettingsLocked() {
698 JournaledFile journal = makeJournaledFile();
699 FileOutputStream stream = null;
700 try {
701 stream = new FileOutputStream(journal.chooseForWrite(), false);
702 XmlSerializer out = new FastXmlSerializer();
703 out.setOutput(stream, "utf-8");
704 out.startDocument(null, true);
705
706 out.startTag(null, "wp");
707 out.attribute(null, "width", Integer.toString(mWidth));
708 out.attribute(null, "height", Integer.toString(mHeight));
709 out.attribute(null, "name", mName);
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700710 if (mWallpaperComponent != null &&
711 !mWallpaperComponent.equals(mImageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700712 out.attribute(null, "component",
713 mWallpaperComponent.flattenToShortString());
714 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700715 out.endTag(null, "wp");
716
717 out.endDocument();
718 stream.close();
719 journal.commit();
720 } catch (IOException e) {
721 try {
722 if (stream != null) {
723 stream.close();
724 }
725 } catch (IOException ex) {
726 // Ignore
727 }
728 journal.rollback();
729 }
730 }
731
732 private void loadSettingsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800733 if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
Mike Clerona428b2c2009-11-15 22:53:08 -0800734
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700735 JournaledFile journal = makeJournaledFile();
736 FileInputStream stream = null;
737 File file = journal.chooseForRead();
738 boolean success = false;
739 try {
740 stream = new FileInputStream(file);
741 XmlPullParser parser = Xml.newPullParser();
742 parser.setInput(stream, null);
743
744 int type;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700745 do {
746 type = parser.next();
747 if (type == XmlPullParser.START_TAG) {
748 String tag = parser.getName();
749 if ("wp".equals(tag)) {
750 mWidth = Integer.parseInt(parser.getAttributeValue(null, "width"));
751 mHeight = Integer.parseInt(parser.getAttributeValue(null, "height"));
752 mName = parser.getAttributeValue(null, "name");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700753 String comp = parser.getAttributeValue(null, "component");
Mike Clerona428b2c2009-11-15 22:53:08 -0800754 mNextWallpaperComponent = comp != null
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700755 ? ComponentName.unflattenFromString(comp)
756 : null;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700757 if (mNextWallpaperComponent == null ||
758 "android".equals(mNextWallpaperComponent.getPackageName())) {
759 mNextWallpaperComponent = mImageWallpaperComponent;
760 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800761
762 if (DEBUG) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800763 Slog.v(TAG, "mWidth:" + mWidth);
764 Slog.v(TAG, "mHeight:" + mHeight);
765 Slog.v(TAG, "mName:" + mName);
766 Slog.v(TAG, "mNextWallpaperComponent:" + mNextWallpaperComponent);
Mike Clerona428b2c2009-11-15 22:53:08 -0800767 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700768 }
769 }
770 } while (type != XmlPullParser.END_DOCUMENT);
771 success = true;
772 } catch (NullPointerException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800773 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700774 } catch (NumberFormatException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800775 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700776 } catch (XmlPullParserException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800777 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700778 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800779 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700780 } catch (IndexOutOfBoundsException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800781 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700782 }
783 try {
784 if (stream != null) {
785 stream.close();
786 }
787 } catch (IOException e) {
788 // Ignore
789 }
790
791 if (!success) {
792 mWidth = -1;
793 mHeight = -1;
794 mName = "";
795 }
Dianne Hackborn44bc17c2011-04-20 18:18:51 -0700796
797 // We always want to have some reasonable width hint.
798 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
799 Display d = wm.getDefaultDisplay();
800 int baseSize = d.getMaximumSizeDimension();
801 if (mWidth < baseSize) {
802 mWidth = baseSize;
803 }
804 if (mHeight < baseSize) {
805 mHeight = baseSize;
806 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700807 }
808
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700809 // Called by SystemBackupAgent after files are restored to disk.
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700810 void settingsRestored() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800811 if (DEBUG) Slog.v(TAG, "settingsRestored");
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700812
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700813 boolean success = false;
814 synchronized (mLock) {
815 loadSettingsLocked();
Mike Clerona428b2c2009-11-15 22:53:08 -0800816 if (mNextWallpaperComponent != null &&
817 !mNextWallpaperComponent.equals(mImageWallpaperComponent)) {
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700818 if (!bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
Christopher Tatee3ab4d02009-12-16 14:03:31 -0800819 // No such live wallpaper or other failure; fall back to the default
820 // live wallpaper (since the profile being restored indicated that the
821 // user had selected a live rather than static one).
Dianne Hackborn80b902f2011-09-15 15:15:27 -0700822 bindWallpaperComponentLocked(null, false, false);
Christopher Tatee3ab4d02009-12-16 14:03:31 -0800823 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700824 success = true;
825 } else {
Mike Clerona428b2c2009-11-15 22:53:08 -0800826 // If there's a wallpaper name, we use that. If that can't be loaded, then we
827 // use the default.
828 if ("".equals(mName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800829 if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
Mike Clerona428b2c2009-11-15 22:53:08 -0800830 success = true;
831 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800832 if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
Mike Clerona428b2c2009-11-15 22:53:08 -0800833 success = restoreNamedResourceLocked();
834 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800835 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
Mike Clerona428b2c2009-11-15 22:53:08 -0800836 if (success) {
Christopher Tatebf6ee4f2011-10-07 12:37:42 -0700837 bindWallpaperComponentLocked(mNextWallpaperComponent, false, false);
Mike Clerona428b2c2009-11-15 22:53:08 -0800838 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700839 }
840 }
841
842 if (!success) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800843 Slog.e(TAG, "Failed to restore wallpaper: '" + mName + "'");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700844 mName = "";
845 WALLPAPER_FILE.delete();
846 }
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700847
848 synchronized (mLock) {
849 saveSettingsLocked();
850 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700851 }
852
853 boolean restoreNamedResourceLocked() {
854 if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) {
855 String resName = mName.substring(4);
856
857 String pkg = null;
858 int colon = resName.indexOf(':');
859 if (colon > 0) {
860 pkg = resName.substring(0, colon);
861 }
862
863 String ident = null;
864 int slash = resName.lastIndexOf('/');
865 if (slash > 0) {
866 ident = resName.substring(slash+1);
867 }
868
869 String type = null;
870 if (colon > 0 && slash > 0 && (slash-colon) > 1) {
871 type = resName.substring(colon+1, slash);
872 }
873
874 if (pkg != null && ident != null && type != null) {
875 int resId = -1;
876 InputStream res = null;
877 FileOutputStream fos = null;
878 try {
879 Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
880 Resources r = c.getResources();
881 resId = r.getIdentifier(resName, null, null);
882 if (resId == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800883 Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700884 + " ident=" + ident);
885 return false;
886 }
887
888 res = r.openRawResource(resId);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700889 if (WALLPAPER_FILE.exists()) {
890 WALLPAPER_FILE.delete();
891 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700892 fos = new FileOutputStream(WALLPAPER_FILE);
893
894 byte[] buffer = new byte[32768];
895 int amt;
896 while ((amt=res.read(buffer)) > 0) {
897 fos.write(buffer, 0, amt);
898 }
899 // mWallpaperObserver will notice the close and send the change broadcast
900
Joe Onorato8a9b2202010-02-26 18:56:32 -0800901 Slog.v(TAG, "Restored wallpaper: " + resName);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700902 return true;
903 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800904 Slog.e(TAG, "Package name " + pkg + " not found");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700905 } catch (Resources.NotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800906 Slog.e(TAG, "Resource not found: " + resId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700907 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800908 Slog.e(TAG, "IOException while restoring wallpaper ", e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700909 } finally {
910 if (res != null) {
911 try {
912 res.close();
913 } catch (IOException ex) {}
914 }
915 if (fos != null) {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -0700916 FileUtils.sync(fos);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700917 try {
918 fos.close();
919 } catch (IOException ex) {}
920 }
921 }
922 }
923 }
924 return false;
925 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700926
927 @Override
928 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
929 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
930 != PackageManager.PERMISSION_GRANTED) {
931
932 pw.println("Permission Denial: can't dump wallpaper service from from pid="
933 + Binder.getCallingPid()
934 + ", uid=" + Binder.getCallingUid());
935 return;
936 }
937
938 synchronized (mLock) {
939 pw.println("Current Wallpaper Service state:");
940 pw.print(" mWidth="); pw.print(mWidth);
941 pw.print(" mHeight="); pw.println(mHeight);
942 pw.print(" mName="); pw.println(mName);
943 pw.print(" mWallpaperComponent="); pw.println(mWallpaperComponent);
944 if (mWallpaperConnection != null) {
945 WallpaperConnection conn = mWallpaperConnection;
946 pw.print(" Wallpaper connection ");
947 pw.print(conn); pw.println(":");
948 pw.print(" mInfo.component="); pw.println(conn.mInfo.getComponent());
949 pw.print(" mToken="); pw.println(conn.mToken);
950 pw.print(" mService="); pw.println(conn.mService);
951 pw.print(" mEngine="); pw.println(conn.mEngine);
952 pw.print(" mLastDiedTime=");
953 pw.println(mLastDiedTime - SystemClock.uptimeMillis());
954 }
955 }
956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957}