blob: 6ceccafdbd6ae07657e7efd540638827598d5c3c [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;
123 bindWallpaperComponentLocked(mImageWallpaperComponent, true);
124 saveSettingsLocked();
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700125 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 }
128 }
129 };
130
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700131 final Context mContext;
132 final IWindowManager mIWindowManager;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800133 final MyPackageMonitor mMonitor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700135 int mWidth = -1;
136 int mHeight = -1;
Dianne Hackborn07213e62011-08-24 20:05:39 -0700137
138 /**
139 * Client is currently writing a new image wallpaper.
140 */
141 boolean mImageWallpaperPending;
142
Mike Clerona428b2c2009-11-15 22:53:08 -0800143 /**
144 * Resource name if using a picture from the wallpaper gallery
145 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700146 String mName = "";
Mike Clerond6c0b842009-11-13 16:37:27 -0800147
148 /**
Mike Clerona428b2c2009-11-15 22:53:08 -0800149 * The component name of the currently set live wallpaper.
Mike Clerond6c0b842009-11-13 16:37:27 -0800150 */
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700151 ComponentName mWallpaperComponent;
Mike Clerona428b2c2009-11-15 22:53:08 -0800152
153 /**
154 * The component name of the wallpaper that should be set next.
155 */
156 ComponentName mNextWallpaperComponent;
157
158 /**
159 * Name of the component used to display bitmap wallpapers from either the gallery or
160 * built-in wallpapers.
161 */
Dianne Hackbornba398392011-08-01 16:11:57 -0700162 ComponentName mImageWallpaperComponent = new ComponentName("com.android.systemui",
163 "com.android.systemui.ImageWallpaper");
Mike Clerona428b2c2009-11-15 22:53:08 -0800164
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700165 WallpaperConnection mWallpaperConnection;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700166 long mLastDiedTime;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800167 boolean mWallpaperUpdating;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700168
169 class WallpaperConnection extends IWallpaperConnection.Stub
170 implements ServiceConnection {
Dianne Hackborneb034652009-09-07 00:49:58 -0700171 final WallpaperInfo mInfo;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700172 final Binder mToken = new Binder();
173 IWallpaperService mService;
174 IWallpaperEngine mEngine;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175
Dianne Hackborneb034652009-09-07 00:49:58 -0700176 public WallpaperConnection(WallpaperInfo info) {
177 mInfo = info;
178 }
179
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700180 public void onServiceConnected(ComponentName name, IBinder service) {
181 synchronized (mLock) {
182 if (mWallpaperConnection == this) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800183 mLastDiedTime = SystemClock.uptimeMillis();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700184 mService = IWallpaperService.Stub.asInterface(service);
185 attachServiceLocked(this);
Dianne Hackborneb034652009-09-07 00:49:58 -0700186 // XXX should probably do saveSettingsLocked() later
187 // when we have an engine, but I'm not sure about
188 // locking there and anyway we always need to be able to
189 // recover if there is something wrong.
190 saveSettingsLocked();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700191 }
192 }
193 }
194
195 public void onServiceDisconnected(ComponentName name) {
196 synchronized (mLock) {
197 mService = null;
198 mEngine = null;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700199 if (mWallpaperConnection == this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800200 Slog.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800201 if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
202 > SystemClock.uptimeMillis()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800203 Slog.w(TAG, "Reverting to built-in wallpaper!");
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700204 bindWallpaperComponentLocked(null, true);
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700205 }
206 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700207 }
208 }
209
210 public void attachEngine(IWallpaperEngine engine) {
211 mEngine = engine;
212 }
213
214 public ParcelFileDescriptor setWallpaper(String name) {
215 synchronized (mLock) {
216 if (mWallpaperConnection == this) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700217 return updateWallpaperBitmapLocked(name);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700218 }
219 return null;
220 }
221 }
222 }
223
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800224 class MyPackageMonitor extends PackageMonitor {
225 @Override
226 public void onPackageUpdateFinished(String packageName, int uid) {
227 synchronized (mLock) {
228 if (mWallpaperComponent != null &&
229 mWallpaperComponent.getPackageName().equals(packageName)) {
230 mWallpaperUpdating = false;
231 ComponentName comp = mWallpaperComponent;
232 clearWallpaperComponentLocked();
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700233 bindWallpaperComponentLocked(comp, false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800234 }
235 }
236 }
237
238 @Override
239 public void onPackageUpdateStarted(String packageName, int uid) {
240 synchronized (mLock) {
241 if (mWallpaperComponent != null &&
242 mWallpaperComponent.getPackageName().equals(packageName)) {
243 mWallpaperUpdating = true;
244 }
245 }
246 }
247
248 @Override
249 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
250 return doPackagesChanged(doit);
251 }
252
253 @Override
254 public void onSomePackagesChanged() {
255 doPackagesChanged(true);
256 }
257
258 boolean doPackagesChanged(boolean doit) {
259 boolean changed = false;
260 synchronized (mLock) {
261 if (mWallpaperComponent != null) {
262 int change = isPackageDisappearing(mWallpaperComponent.getPackageName());
263 if (change == PACKAGE_PERMANENT_CHANGE
264 || change == PACKAGE_TEMPORARY_CHANGE) {
265 changed = true;
266 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800267 Slog.w(TAG, "Wallpaper uninstalled, removing: " + mWallpaperComponent);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800268 clearWallpaperLocked();
269 }
270 }
271 }
272 if (mNextWallpaperComponent != null) {
273 int change = isPackageDisappearing(mNextWallpaperComponent.getPackageName());
274 if (change == PACKAGE_PERMANENT_CHANGE
275 || change == PACKAGE_TEMPORARY_CHANGE) {
276 mNextWallpaperComponent = null;
277 }
278 }
279 if (mWallpaperComponent != null
280 && isPackageModified(mWallpaperComponent.getPackageName())) {
281 try {
282 mContext.getPackageManager().getServiceInfo(
283 mWallpaperComponent, 0);
284 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800285 Slog.w(TAG, "Wallpaper component gone, removing: " + mWallpaperComponent);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800286 clearWallpaperLocked();
287 }
288 }
289 if (mNextWallpaperComponent != null
290 && isPackageModified(mNextWallpaperComponent.getPackageName())) {
291 try {
292 mContext.getPackageManager().getServiceInfo(
293 mNextWallpaperComponent, 0);
294 } catch (NameNotFoundException e) {
295 mNextWallpaperComponent = null;
296 }
297 }
298 }
299 return changed;
300 }
301 }
302
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700303 public WallpaperManagerService(Context context) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800304 if (DEBUG) Slog.v(TAG, "WallpaperService startup");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 mContext = context;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700306 mIWindowManager = IWindowManager.Stub.asInterface(
307 ServiceManager.getService(Context.WINDOW_SERVICE));
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800308 mMonitor = new MyPackageMonitor();
309 mMonitor.register(context, true);
Joe Onoratoe712ee32009-07-29 16:23:58 -0700310 WALLPAPER_DIR.mkdirs();
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700311 loadSettingsLocked();
Joe Onoratoe712ee32009-07-29 16:23:58 -0700312 mWallpaperObserver.startWatching();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
314
315 @Override
316 protected void finalize() throws Throwable {
317 super.finalize();
318 mWallpaperObserver.stopWatching();
319 }
320
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700321 public void systemReady() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800322 if (DEBUG) Slog.v(TAG, "systemReady");
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700323 synchronized (mLock) {
324 try {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700325 bindWallpaperComponentLocked(mNextWallpaperComponent, false);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700326 } catch (RuntimeException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800327 Slog.w(TAG, "Failure starting previous wallpaper", e);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700328 try {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700329 bindWallpaperComponentLocked(null, false);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700330 } catch (RuntimeException e2) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800331 Slog.w(TAG, "Failure starting default wallpaper", e2);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700332 clearWallpaperComponentLocked();
333 }
334 }
335 }
336 }
337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 public void clearWallpaper() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800339 if (DEBUG) Slog.v(TAG, "clearWallpaper");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700340 synchronized (mLock) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800341 clearWallpaperLocked();
342 }
343 }
344
345 public void clearWallpaperLocked() {
346 File f = WALLPAPER_FILE;
347 if (f.exists()) {
348 f.delete();
349 }
350 final long ident = Binder.clearCallingIdentity();
351 try {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700352 mImageWallpaperPending = false;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700353 bindWallpaperComponentLocked(null, false);
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800354 } catch (IllegalArgumentException e) {
355 // This can happen if the default wallpaper component doesn't
356 // exist. This should be a system configuration problem, but
357 // let's not let it crash the system and just live with no
358 // wallpaper.
359 Slog.e(TAG, "Default wallpaper component not found!", e);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800360 } finally {
361 Binder.restoreCallingIdentity(ident);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 }
363 }
364
365 public void setDimensionHints(int width, int height) throws RemoteException {
366 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
367
368 if (width <= 0 || height <= 0) {
369 throw new IllegalArgumentException("width and height must be > 0");
370 }
371
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700372 synchronized (mLock) {
373 if (width != mWidth || height != mHeight) {
374 mWidth = width;
375 mHeight = height;
376 saveSettingsLocked();
Dianne Hackborn284ac932009-08-28 10:34:25 -0700377 if (mWallpaperConnection != null) {
378 if (mWallpaperConnection.mEngine != null) {
379 try {
380 mWallpaperConnection.mEngine.setDesiredSize(
381 width, height);
382 } catch (RemoteException e) {
383 }
384 notifyCallbacksLocked();
385 }
386 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389 }
390
391 public int getWidthHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700392 synchronized (mLock) {
393 return mWidth;
394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
396
397 public int getHeightHint() throws RemoteException {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700398 synchronized (mLock) {
399 return mHeight;
400 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 }
402
Dianne Hackborn284ac932009-08-28 10:34:25 -0700403 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
404 Bundle outParams) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700405 synchronized (mLock) {
406 try {
Dianne Hackborn284ac932009-08-28 10:34:25 -0700407 if (outParams != null) {
408 outParams.putInt("width", mWidth);
409 outParams.putInt("height", mHeight);
410 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700411 mCallbacks.register(cb);
412 File f = WALLPAPER_FILE;
413 if (!f.exists()) {
414 return null;
415 }
416 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
417 } catch (FileNotFoundException e) {
418 /* Shouldn't happen as we check to see if the file exists */
Joe Onorato8a9b2202010-02-26 18:56:32 -0800419 Slog.w(TAG, "Error getting wallpaper", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700421 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 }
424
Dianne Hackborneb034652009-09-07 00:49:58 -0700425 public WallpaperInfo getWallpaperInfo() {
426 synchronized (mLock) {
427 if (mWallpaperConnection != null) {
428 return mWallpaperConnection.mInfo;
429 }
430 return null;
431 }
432 }
433
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700434 public ParcelFileDescriptor setWallpaper(String name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800435 if (DEBUG) Slog.v(TAG, "setWallpaper");
Mike Clerona428b2c2009-11-15 22:53:08 -0800436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 checkPermission(android.Manifest.permission.SET_WALLPAPER);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700438 synchronized (mLock) {
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700439 final long ident = Binder.clearCallingIdentity();
440 try {
441 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
442 if (pfd != null) {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700443 mImageWallpaperPending = true;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700444 }
445 return pfd;
446 } finally {
447 Binder.restoreCallingIdentity(ident);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 }
450 }
451
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700452 ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
453 if (name == null) name = "";
454 try {
455 ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
456 MODE_CREATE|MODE_READ_WRITE);
457 mName = name;
458 return fd;
459 } catch (FileNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800460 Slog.w(TAG, "Error setting wallpaper", e);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700461 }
462 return null;
463 }
464
465 public void setWallpaperComponent(ComponentName name) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800466 if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700467 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
468 synchronized (mLock) {
469 final long ident = Binder.clearCallingIdentity();
470 try {
Dianne Hackborn07213e62011-08-24 20:05:39 -0700471 mImageWallpaperPending = false;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700472 bindWallpaperComponentLocked(name, false);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700473 } finally {
474 Binder.restoreCallingIdentity(ident);
475 }
476 }
477 }
478
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700479 void bindWallpaperComponentLocked(ComponentName componentName, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800480 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
Mike Clerona428b2c2009-11-15 22:53:08 -0800481
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700482 // Has the component changed?
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700483 if (!force) {
484 if (mWallpaperConnection != null) {
485 if (mWallpaperComponent == null) {
486 if (componentName == null) {
487 if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
488 // Still using default wallpaper.
489 return;
490 }
491 } else if (mWallpaperComponent.equals(componentName)) {
492 // Changing to same wallpaper.
493 if (DEBUG) Slog.v(TAG, "same wallpaper");
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700494 return;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700495 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700496 }
497 }
498
499 try {
Mike Clerona428b2c2009-11-15 22:53:08 -0800500 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800501 String defaultComponent =
502 mContext.getString(com.android.internal.R.string.default_wallpaper_component);
Mike Clerona428b2c2009-11-15 22:53:08 -0800503 if (defaultComponent != null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800504 // See if there is a default wallpaper component specified
Mike Clerona428b2c2009-11-15 22:53:08 -0800505 componentName = ComponentName.unflattenFromString(defaultComponent);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800506 if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
Mike Cleron322b6ee2009-11-12 07:45:47 -0800507 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800508 if (componentName == null) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800509 // Fall back to static image wallpaper
Mike Clerona428b2c2009-11-15 22:53:08 -0800510 componentName = mImageWallpaperComponent;
Mike Cleron322b6ee2009-11-12 07:45:47 -0800511 //clearWallpaperComponentLocked();
512 //return;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800513 if (DEBUG) Slog.v(TAG, "Using image wallpaper");
Mike Cleron322b6ee2009-11-12 07:45:47 -0800514 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700515 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800516 ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700517 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
518 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
519 throw new SecurityException("Selected service does not require "
520 + android.Manifest.permission.BIND_WALLPAPER
Mike Clerona428b2c2009-11-15 22:53:08 -0800521 + ": " + componentName);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700522 }
523
Dianne Hackborneb034652009-09-07 00:49:58 -0700524 WallpaperInfo wi = null;
525
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700526 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
Mike Clerona428b2c2009-11-15 22:53:08 -0800527 if (componentName != null && !componentName.equals(mImageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700528 // Make sure the selected service is actually a wallpaper service.
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700529 List<ResolveInfo> ris = mContext.getPackageManager()
Dianne Hackborneb034652009-09-07 00:49:58 -0700530 .queryIntentServices(intent, PackageManager.GET_META_DATA);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700531 for (int i=0; i<ris.size(); i++) {
532 ServiceInfo rsi = ris.get(i).serviceInfo;
533 if (rsi.name.equals(si.name) &&
534 rsi.packageName.equals(si.packageName)) {
Dianne Hackborneb034652009-09-07 00:49:58 -0700535 try {
536 wi = new WallpaperInfo(mContext, ris.get(i));
537 } catch (XmlPullParserException e) {
538 throw new IllegalArgumentException(e);
539 } catch (IOException e) {
540 throw new IllegalArgumentException(e);
541 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700542 break;
543 }
544 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700545 if (wi == null) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700546 throw new SecurityException("Selected service is not a wallpaper: "
Mike Clerona428b2c2009-11-15 22:53:08 -0800547 + componentName);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700548 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700549 }
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700550
551 // Bind the service!
Joe Onorato8a9b2202010-02-26 18:56:32 -0800552 if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
Dianne Hackborneb034652009-09-07 00:49:58 -0700553 WallpaperConnection newConn = new WallpaperConnection(wi);
Mike Clerona428b2c2009-11-15 22:53:08 -0800554 intent.setComponent(componentName);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -0700555 intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
556 com.android.internal.R.string.wallpaper_binding_label);
557 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
Dianne Hackborneb034652009-09-07 00:49:58 -0700558 mContext, 0,
559 Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
560 mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
561 0));
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700562 if (!mContext.bindService(intent, newConn,
563 Context.BIND_AUTO_CREATE)) {
564 throw new IllegalArgumentException("Unable to bind service: "
Mike Cleron322b6ee2009-11-12 07:45:47 -0800565 + componentName);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700566 }
567
568 clearWallpaperComponentLocked();
Mike Cleron322b6ee2009-11-12 07:45:47 -0800569 mWallpaperComponent = componentName;
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700570 mWallpaperConnection = newConn;
Dianne Hackborn0cd48872009-08-13 18:51:59 -0700571 mLastDiedTime = SystemClock.uptimeMillis();
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700572 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800573 if (DEBUG) Slog.v(TAG, "Adding window token: " + newConn.mToken);
Dianne Hackbornf21adf62009-08-13 10:20:21 -0700574 mIWindowManager.addWindowToken(newConn.mToken,
575 WindowManager.LayoutParams.TYPE_WALLPAPER);
576 } catch (RemoteException e) {
577 }
578
579 } catch (PackageManager.NameNotFoundException e) {
Mike Cleron322b6ee2009-11-12 07:45:47 -0800580 throw new IllegalArgumentException("Unknown component " + componentName);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700581 }
582 }
583
584 void clearWallpaperComponentLocked() {
585 mWallpaperComponent = null;
586 if (mWallpaperConnection != null) {
587 if (mWallpaperConnection.mEngine != null) {
588 try {
589 mWallpaperConnection.mEngine.destroy();
590 } catch (RemoteException e) {
591 }
592 }
593 mContext.unbindService(mWallpaperConnection);
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700594 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800595 if (DEBUG) Slog.v(TAG, "Removing window token: "
Dianne Hackborne9e9bca2009-08-18 15:08:22 -0700596 + mWallpaperConnection.mToken);
597 mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
598 } catch (RemoteException e) {
599 }
Vairavan Srinivasanfdfc1b22010-12-23 14:05:44 -0800600 mWallpaperConnection.mService = null;
601 mWallpaperConnection.mEngine = null;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700602 mWallpaperConnection = null;
603 }
604 }
605
606 void attachServiceLocked(WallpaperConnection conn) {
607 try {
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700608 conn.mService.attach(conn, conn.mToken,
609 WindowManager.LayoutParams.TYPE_WALLPAPER, false,
610 mWidth, mHeight);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700611 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800612 Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800613 if (!mWallpaperUpdating) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700614 bindWallpaperComponentLocked(null, false);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800615 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700616 }
617 }
618
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700619 private void notifyCallbacksLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800620 final int n = mCallbacks.beginBroadcast();
621 for (int i = 0; i < n; i++) {
622 try {
623 mCallbacks.getBroadcastItem(i).onWallpaperChanged();
624 } catch (RemoteException e) {
625
626 // The RemoteCallbackList will take care of removing
627 // the dead object for us.
628 }
629 }
630 mCallbacks.finishBroadcast();
631 final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
632 mContext.sendBroadcast(intent);
633 }
634
635 private void checkPermission(String permission) {
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700636 if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
638 + ", must have permission " + permission);
639 }
640 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700641
642 private static JournaledFile makeJournaledFile() {
643 final String base = "/data/system/wallpaper_info.xml";
644 return new JournaledFile(new File(base), new File(base + ".tmp"));
645 }
646
647 private void saveSettingsLocked() {
648 JournaledFile journal = makeJournaledFile();
649 FileOutputStream stream = null;
650 try {
651 stream = new FileOutputStream(journal.chooseForWrite(), false);
652 XmlSerializer out = new FastXmlSerializer();
653 out.setOutput(stream, "utf-8");
654 out.startDocument(null, true);
655
656 out.startTag(null, "wp");
657 out.attribute(null, "width", Integer.toString(mWidth));
658 out.attribute(null, "height", Integer.toString(mHeight));
659 out.attribute(null, "name", mName);
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700660 if (mWallpaperComponent != null &&
661 !mWallpaperComponent.equals(mImageWallpaperComponent)) {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700662 out.attribute(null, "component",
663 mWallpaperComponent.flattenToShortString());
664 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700665 out.endTag(null, "wp");
666
667 out.endDocument();
668 stream.close();
669 journal.commit();
670 } catch (IOException e) {
671 try {
672 if (stream != null) {
673 stream.close();
674 }
675 } catch (IOException ex) {
676 // Ignore
677 }
678 journal.rollback();
679 }
680 }
681
682 private void loadSettingsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800683 if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
Mike Clerona428b2c2009-11-15 22:53:08 -0800684
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700685 JournaledFile journal = makeJournaledFile();
686 FileInputStream stream = null;
687 File file = journal.chooseForRead();
688 boolean success = false;
689 try {
690 stream = new FileInputStream(file);
691 XmlPullParser parser = Xml.newPullParser();
692 parser.setInput(stream, null);
693
694 int type;
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700695 do {
696 type = parser.next();
697 if (type == XmlPullParser.START_TAG) {
698 String tag = parser.getName();
699 if ("wp".equals(tag)) {
700 mWidth = Integer.parseInt(parser.getAttributeValue(null, "width"));
701 mHeight = Integer.parseInt(parser.getAttributeValue(null, "height"));
702 mName = parser.getAttributeValue(null, "name");
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700703 String comp = parser.getAttributeValue(null, "component");
Mike Clerona428b2c2009-11-15 22:53:08 -0800704 mNextWallpaperComponent = comp != null
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700705 ? ComponentName.unflattenFromString(comp)
706 : null;
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700707 if (mNextWallpaperComponent == null ||
708 "android".equals(mNextWallpaperComponent.getPackageName())) {
709 mNextWallpaperComponent = mImageWallpaperComponent;
710 }
Mike Clerona428b2c2009-11-15 22:53:08 -0800711
712 if (DEBUG) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800713 Slog.v(TAG, "mWidth:" + mWidth);
714 Slog.v(TAG, "mHeight:" + mHeight);
715 Slog.v(TAG, "mName:" + mName);
716 Slog.v(TAG, "mNextWallpaperComponent:" + mNextWallpaperComponent);
Mike Clerona428b2c2009-11-15 22:53:08 -0800717 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700718 }
719 }
720 } while (type != XmlPullParser.END_DOCUMENT);
721 success = true;
722 } catch (NullPointerException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800723 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700724 } catch (NumberFormatException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800725 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700726 } catch (XmlPullParserException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800727 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700728 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800729 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700730 } catch (IndexOutOfBoundsException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800731 Slog.w(TAG, "failed parsing " + file + " " + e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700732 }
733 try {
734 if (stream != null) {
735 stream.close();
736 }
737 } catch (IOException e) {
738 // Ignore
739 }
740
741 if (!success) {
742 mWidth = -1;
743 mHeight = -1;
744 mName = "";
745 }
Dianne Hackborn44bc17c2011-04-20 18:18:51 -0700746
747 // We always want to have some reasonable width hint.
748 WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
749 Display d = wm.getDefaultDisplay();
750 int baseSize = d.getMaximumSizeDimension();
751 if (mWidth < baseSize) {
752 mWidth = baseSize;
753 }
754 if (mHeight < baseSize) {
755 mHeight = baseSize;
756 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700757 }
758
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700759 // Called by SystemBackupAgent after files are restored to disk.
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700760 void settingsRestored() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800761 if (DEBUG) Slog.v(TAG, "settingsRestored");
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700762
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700763 boolean success = false;
764 synchronized (mLock) {
765 loadSettingsLocked();
Mike Clerona428b2c2009-11-15 22:53:08 -0800766 if (mNextWallpaperComponent != null &&
767 !mNextWallpaperComponent.equals(mImageWallpaperComponent)) {
Christopher Tatee3ab4d02009-12-16 14:03:31 -0800768 try {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700769 bindWallpaperComponentLocked(mNextWallpaperComponent, false);
Christopher Tatee3ab4d02009-12-16 14:03:31 -0800770 } catch (IllegalArgumentException e) {
771 // No such live wallpaper or other failure; fall back to the default
772 // live wallpaper (since the profile being restored indicated that the
773 // user had selected a live rather than static one).
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700774 bindWallpaperComponentLocked(null, false);
Christopher Tatee3ab4d02009-12-16 14:03:31 -0800775 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700776 success = true;
777 } else {
Mike Clerona428b2c2009-11-15 22:53:08 -0800778 // If there's a wallpaper name, we use that. If that can't be loaded, then we
779 // use the default.
780 if ("".equals(mName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800781 if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
Mike Clerona428b2c2009-11-15 22:53:08 -0800782 success = true;
783 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800784 if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
Mike Clerona428b2c2009-11-15 22:53:08 -0800785 success = restoreNamedResourceLocked();
786 }
Joe Onorato8a9b2202010-02-26 18:56:32 -0800787 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
Mike Clerona428b2c2009-11-15 22:53:08 -0800788 if (success) {
Dianne Hackborn9ea31632011-08-05 14:43:50 -0700789 bindWallpaperComponentLocked(null, false);
Mike Clerona428b2c2009-11-15 22:53:08 -0800790 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700791 }
792 }
793
794 if (!success) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800795 Slog.e(TAG, "Failed to restore wallpaper: '" + mName + "'");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700796 mName = "";
797 WALLPAPER_FILE.delete();
798 }
Brad Fitzpatrick194b19a2010-09-14 11:30:29 -0700799
800 synchronized (mLock) {
801 saveSettingsLocked();
802 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700803 }
804
805 boolean restoreNamedResourceLocked() {
806 if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) {
807 String resName = mName.substring(4);
808
809 String pkg = null;
810 int colon = resName.indexOf(':');
811 if (colon > 0) {
812 pkg = resName.substring(0, colon);
813 }
814
815 String ident = null;
816 int slash = resName.lastIndexOf('/');
817 if (slash > 0) {
818 ident = resName.substring(slash+1);
819 }
820
821 String type = null;
822 if (colon > 0 && slash > 0 && (slash-colon) > 1) {
823 type = resName.substring(colon+1, slash);
824 }
825
826 if (pkg != null && ident != null && type != null) {
827 int resId = -1;
828 InputStream res = null;
829 FileOutputStream fos = null;
830 try {
831 Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
832 Resources r = c.getResources();
833 resId = r.getIdentifier(resName, null, null);
834 if (resId == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800835 Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700836 + " ident=" + ident);
837 return false;
838 }
839
840 res = r.openRawResource(resId);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700841 if (WALLPAPER_FILE.exists()) {
842 WALLPAPER_FILE.delete();
843 }
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700844 fos = new FileOutputStream(WALLPAPER_FILE);
845
846 byte[] buffer = new byte[32768];
847 int amt;
848 while ((amt=res.read(buffer)) > 0) {
849 fos.write(buffer, 0, amt);
850 }
851 // mWallpaperObserver will notice the close and send the change broadcast
852
Joe Onorato8a9b2202010-02-26 18:56:32 -0800853 Slog.v(TAG, "Restored wallpaper: " + resName);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700854 return true;
855 } catch (NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800856 Slog.e(TAG, "Package name " + pkg + " not found");
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700857 } catch (Resources.NotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800858 Slog.e(TAG, "Resource not found: " + resId);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700859 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800860 Slog.e(TAG, "IOException while restoring wallpaper ", e);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700861 } finally {
862 if (res != null) {
863 try {
864 res.close();
865 } catch (IOException ex) {}
866 }
867 if (fos != null) {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -0700868 FileUtils.sync(fos);
Joe Onorato9bb8fd72009-07-28 18:24:51 -0700869 try {
870 fos.close();
871 } catch (IOException ex) {}
872 }
873 }
874 }
875 }
876 return false;
877 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700878
879 @Override
880 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
881 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
882 != PackageManager.PERMISSION_GRANTED) {
883
884 pw.println("Permission Denial: can't dump wallpaper service from from pid="
885 + Binder.getCallingPid()
886 + ", uid=" + Binder.getCallingUid());
887 return;
888 }
889
890 synchronized (mLock) {
891 pw.println("Current Wallpaper Service state:");
892 pw.print(" mWidth="); pw.print(mWidth);
893 pw.print(" mHeight="); pw.println(mHeight);
894 pw.print(" mName="); pw.println(mName);
895 pw.print(" mWallpaperComponent="); pw.println(mWallpaperComponent);
896 if (mWallpaperConnection != null) {
897 WallpaperConnection conn = mWallpaperConnection;
898 pw.print(" Wallpaper connection ");
899 pw.print(conn); pw.println(":");
900 pw.print(" mInfo.component="); pw.println(conn.mInfo.getComponent());
901 pw.print(" mToken="); pw.println(conn.mToken);
902 pw.print(" mService="); pw.println(conn.mService);
903 pw.print(" mEngine="); pw.println(conn.mEngine);
904 pw.print(" mLastDiedTime=");
905 pw.println(mLastDiedTime - SystemClock.uptimeMillis());
906 }
907 }
908 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909}