WallpaperManagerService.java revision dd9b82c283815747b75fe4434c65e4b6c9c9b54f
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.os.FileObserver.*;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.os.ParcelFileDescriptor.*;
21111bd4acdb378266221b430a284f88a3990a3958Christopher Tate
228cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.app.IWallpaperManager;
238cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornimport android.app.IWallpaperManagerCallback;
24dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent;
25111bd4acdb378266221b430a284f88a3990a3958Christopher Tateimport android.backup.BackupManager;
264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ComponentName;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ServiceConnection;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ResolveInfo;
324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ServiceInfo;
339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.pm.PackageManager.NameNotFoundException;
349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.res.Resources;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
36284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.os.Bundle;
374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.IBinder;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.FileObserver;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteCallbackList;
424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.ServiceManager;
430cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackbornimport android.os.SystemClock;
44dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.provider.Settings;
454c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperConnection;
464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperEngine;
474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperService;
484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.util.Xml;
514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.IWindowManager;
524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.WindowManager;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException;
559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.InputStream;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileInputStream;
599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileOutputStream;
604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.List;
619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParser;
639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParserException;
649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlSerializer;
659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
66f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackbornimport com.android.internal.service.wallpaper.ImageWallpaper;
679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport com.android.internal.util.FastXmlSerializer;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
698cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornclass WallpaperManagerService extends IWallpaperManager.Stub {
704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    static final String TAG = "WallpaperService";
71cbf15048240ecf460957ac3de98a7efbccbbb754Dianne Hackborn    static final boolean DEBUG = false;
729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    Object mLock = new Object();
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
750cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    /**
760cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * Minimum time between crashes of a wallpaper service for us to consider
770cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * restarting it vs. just reverting to the static wallpaper.
780cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     */
790cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final long MIN_WALLPAPER_CRASH_TIME = 10000;
800cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn
810cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final File WALLPAPER_DIR = new File(
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "/data/data/com.android.settings/files");
830cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final String WALLPAPER = "wallpaper";
840cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * List of callbacks registered they should each be notified
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the wallpaper is changed.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
908cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks
918cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            = new RemoteCallbackList<IWallpaperManagerCallback>();
929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the wallpaper has changed. The CREATE is triggered when there is no
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * everytime the wallpaper is changed.
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final FileObserver mWallpaperObserver = new FileObserver(
1009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                @Override
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                public void onEvent(int event, String path) {
103e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                    if (path == null) {
104e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                        return;
105e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                    }
1069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    synchronized (mLock) {
1079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        // changing the wallpaper means we'll need to back up the new one
1089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        long origId = Binder.clearCallingIdentity();
1099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        BackupManager bm = new BackupManager(mContext);
1109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        bm.dataChanged();
1119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        Binder.restoreCallingIdentity(origId);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        File changedFile = new File(WALLPAPER_DIR, path);
1149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        if (WALLPAPER_FILE.equals(changedFile)) {
1159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            notifyCallbacksLocked();
1169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            };
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final Context mContext;
1224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final IWindowManager mIWindowManager;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mWidth = -1;
1254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mHeight = -1;
1264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    String mName = "";
1274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    ComponentName mWallpaperComponent;
1284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    WallpaperConnection mWallpaperConnection;
1290cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    long mLastDiedTime;
1304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    class WallpaperConnection extends IWallpaperConnection.Stub
1324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            implements ServiceConnection {
1334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        final Binder mToken = new Binder();
1344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperService mService;
1354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperEngine mEngine;
1364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceConnected(ComponentName name, IBinder service) {
1384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                if (mWallpaperConnection == this) {
1404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mService = IWallpaperService.Stub.asInterface(service);
1414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    attachServiceLocked(this);
1424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
1434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceDisconnected(ComponentName name) {
1474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mService = null;
1494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mEngine = null;
1500cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (mWallpaperConnection == this) {
1510cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    Log.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
1520cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    if ((mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
1530cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                            < SystemClock.uptimeMillis()) {
1540cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                        Log.w(TAG, "Reverting to built-in wallpaper!");
1550cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                        bindWallpaperComponentLocked(null);
1560cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    }
1570cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
1584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void attachEngine(IWallpaperEngine engine) {
1624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mEngine = engine;
1634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public ParcelFileDescriptor setWallpaper(String name) {
1664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                if (mWallpaperConnection == this) {
1684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
1694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    if (pfd != null) {
1704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        saveSettingsLocked();
1714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    }
1724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    return pfd;
1734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
1744c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                return null;
1754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1784c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1798cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public WallpaperManagerService(Context context) {
1804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (DEBUG) Log.d(TAG, "WallpaperService startup");
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mIWindowManager = IWindowManager.Stub.asInterface(
1834c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                ServiceManager.getService(Context.WINDOW_SERVICE));
184e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato        WALLPAPER_DIR.mkdirs();
1859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        loadSettingsLocked();
186e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato        mWallpaperObserver.startWatching();
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.finalize();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWallpaperObserver.stopWatching();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
195f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    public void systemReady() {
196f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        synchronized (mLock) {
197f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
198f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                bindWallpaperComponentLocked(mWallpaperComponent);
199f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RuntimeException e) {
200f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Log.w(TAG, "Failure starting previous wallpaper", e);
201f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                try {
202f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    bindWallpaperComponentLocked(null);
203f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                } catch (RuntimeException e2) {
204f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    Log.w(TAG, "Failure starting default wallpaper", e2);
205f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    clearWallpaperComponentLocked();
206f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                }
207f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
208f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
209f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
210f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearWallpaper() {
2129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            File f = WALLPAPER_FILE;
2149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (f.exists()) {
2159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                f.delete();
2169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
2170cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
2180cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
2190cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                bindWallpaperComponentLocked(null);
2200cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
2210cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
2220cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDimensionHints(int width, int height) throws RemoteException {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0 || height <= 0) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width and height must be > 0");
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (width != mWidth || height != mHeight) {
2359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mWidth = width;
2369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mHeight = height;
2379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                saveSettingsLocked();
238284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (mWallpaperConnection != null) {
239284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    if (mWallpaperConnection.mEngine != null) {
240284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        try {
241284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                            mWallpaperConnection.mEngine.setDesiredSize(
242284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                                    width, height);
243284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        } catch (RemoteException e) {
244284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
245284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        notifyCallbacksLocked();
246284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    }
247284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
2489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidthHint() throws RemoteException {
2539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return mWidth;
2559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeightHint() throws RemoteException {
2599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return mHeight;
2619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
264284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
265284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn            Bundle outParams) {
2669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
268284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (outParams != null) {
269284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    outParams.putInt("width", mWidth);
270284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    outParams.putInt("height", mHeight);
271284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
2729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mCallbacks.register(cb);
2739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                File f = WALLPAPER_FILE;
2749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (!f.exists()) {
2759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return null;
2769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
2779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
2789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (FileNotFoundException e) {
2799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                /* Shouldn't happen as we check to see if the file exists */
2804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                Log.w(TAG, "Error getting wallpaper", e);
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return null;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public ParcelFileDescriptor setWallpaper(String name) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER);
2889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2890cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
2900cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
2910cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
2920cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (pfd != null) {
2930cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    bindWallpaperComponentLocked(null);
2940cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    saveSettingsLocked();
2950cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
2960cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                return pfd;
2970cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
2980cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
2994c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
3004c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
3014c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3024c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3034c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
3044c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (name == null) name = "";
3054c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
3064c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
3074c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    MODE_CREATE|MODE_READ_WRITE);
3089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = name;
3094c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            return fd;
3104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (FileNotFoundException e) {
3114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            Log.w(TAG, "Error setting wallpaper", e);
3124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
3134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return null;
3144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setWallpaperComponent(ComponentName name) {
3174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
3184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mLock) {
3194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
3209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
321f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                bindWallpaperComponentLocked(name);
322f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } finally {
323f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Binder.restoreCallingIdentity(ident);
324f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
325f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
326f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
327f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
328f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    void bindWallpaperComponentLocked(ComponentName name) {
329f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        // Has the component changed?
330f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        if (mWallpaperConnection != null) {
331f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (mWallpaperComponent == null) {
332f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                if (name == null) {
333f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    // Still using default wallpaper.
334f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    return;
3354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
336f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } else if (mWallpaperComponent.equals(name)) {
337f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                // Changing to same wallpaper.
338f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                return;
339f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
340f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
341f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
342f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        try {
343f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            ComponentName realName = name;
344f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (realName == null) {
345f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                // The default component is our static image wallpaper.
3467341d7a104b47996445d069a695e155a07184606Dianne Hackborn                realName = new ComponentName("android",
3477341d7a104b47996445d069a695e155a07184606Dianne Hackborn                        ImageWallpaper.class.getName());
3487341d7a104b47996445d069a695e155a07184606Dianne Hackborn                //clearWallpaperComponentLocked();
3497341d7a104b47996445d069a695e155a07184606Dianne Hackborn                //return;
350f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
351f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            ServiceInfo si = mContext.getPackageManager().getServiceInfo(realName,
352f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
353f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
354f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                throw new SecurityException("Selected service does not require "
355f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + android.Manifest.permission.BIND_WALLPAPER
356f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + ": " + realName);
357f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
358f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
359f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
360f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (name != null) {
3614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                // Make sure the selected service is actually a wallpaper service.
3624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                List<ResolveInfo> ris = mContext.getPackageManager()
3634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        .queryIntentServices(intent, 0);
3644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                for (int i=0; i<ris.size(); i++) {
3654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    ServiceInfo rsi = ris.get(i).serviceInfo;
3664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    if (rsi.name.equals(si.name) &&
3674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                            rsi.packageName.equals(si.packageName)) {
3684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        ris = null;
3694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        break;
3704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    }
3714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
3724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                if (ris != null) {
3734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    throw new SecurityException("Selected service is not a wallpaper: "
374f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                            + realName);
3754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
3769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
377f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
378f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            // Bind the service!
379f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            WallpaperConnection newConn = new WallpaperConnection();
380f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            intent.setComponent(realName);
381dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
382dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                    com.android.internal.R.string.wallpaper_binding_label);
383dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
384dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                    mContext, 0, new Intent(Intent.ACTION_SET_WALLPAPER), 0));
385f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!mContext.bindService(intent, newConn,
386f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    Context.BIND_AUTO_CREATE)) {
387f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                throw new IllegalArgumentException("Unable to bind service: "
388f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + name);
389f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
390f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
391f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            clearWallpaperComponentLocked();
392f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            mWallpaperComponent = name;
393f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            mWallpaperConnection = newConn;
3940cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            mLastDiedTime = SystemClock.uptimeMillis();
395f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
396f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                if (DEBUG) Log.v(TAG, "Adding window token: " + newConn.mToken);
397f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                mIWindowManager.addWindowToken(newConn.mToken,
398f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        WindowManager.LayoutParams.TYPE_WALLPAPER);
399f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RemoteException e) {
400f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
401f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
402f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
403f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            throw new IllegalArgumentException("Unknown component " + name);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4064c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4074c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    void clearWallpaperComponentLocked() {
4084c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mWallpaperComponent = null;
4094c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mWallpaperConnection != null) {
4104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mWallpaperConnection.mEngine != null) {
4114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                try {
4124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mWallpaperConnection.mEngine.destroy();
4134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                } catch (RemoteException e) {
4144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
4154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
4164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mContext.unbindService(mWallpaperConnection);
417e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            try {
418e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                if (DEBUG) Log.v(TAG, "Removing window token: "
419e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                        + mWallpaperConnection.mToken);
420e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
421e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            } catch (RemoteException e) {
422e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            }
4234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mWallpaperConnection = null;
4244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
4254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
4264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    void attachServiceLocked(WallpaperConnection conn) {
4284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
4293be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn            conn.mService.attach(conn, conn.mToken,
4303be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
4313be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    mWidth, mHeight);
4324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (RemoteException e) {
4334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            Log.w(TAG, "Failed attaching wallpaper; clearing", e);
434f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            bindWallpaperComponentLocked(null);
4354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
4364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
4374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void notifyCallbacksLocked() {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int n = mCallbacks.beginBroadcast();
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCallbacks.getBroadcastItem(i).onWallpaperChanged();
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The RemoteCallbackList will take care of removing
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the dead object for us.
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCallbacks.finishBroadcast();
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendBroadcast(intent);
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPermission(String permission) {
4559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", must have permission " + permission);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
4619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private static JournaledFile makeJournaledFile() {
4629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        final String base = "/data/system/wallpaper_info.xml";
4639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return new JournaledFile(new File(base), new File(base + ".tmp"));
4649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
4659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
4669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void saveSettingsLocked() {
4679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        JournaledFile journal = makeJournaledFile();
4689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileOutputStream stream = null;
4699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
4709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileOutputStream(journal.chooseForWrite(), false);
4719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlSerializer out = new FastXmlSerializer();
4729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.setOutput(stream, "utf-8");
4739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startDocument(null, true);
4749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
4759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startTag(null, "wp");
4769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "width", Integer.toString(mWidth));
4779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "height", Integer.toString(mHeight));
4789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "name", mName);
4794c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mWallpaperComponent != null) {
4804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                out.attribute(null, "component",
4814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        mWallpaperComponent.flattenToShortString());
4824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
4839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endTag(null, "wp");
4849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
4859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endDocument();
4869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream.close();
4879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.commit();
4889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
4899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
4909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (stream != null) {
4919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    stream.close();
4929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
4939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (IOException ex) {
4949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                // Ignore
4959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
4969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.rollback();
4979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
4989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
4999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void loadSettingsLocked() {
5019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        JournaledFile journal = makeJournaledFile();
5029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileInputStream stream = null;
5039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        File file = journal.chooseForRead();
5049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
5059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
5069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileInputStream(file);
5079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlPullParser parser = Xml.newPullParser();
5089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            parser.setInput(stream, null);
5099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int type;
5119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            do {
5129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = parser.next();
5139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (type == XmlPullParser.START_TAG) {
5149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    String tag = parser.getName();
5159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if ("wp".equals(tag)) {
5169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mWidth = Integer.parseInt(parser.getAttributeValue(null, "width"));
5179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mHeight = Integer.parseInt(parser.getAttributeValue(null, "height"));
5189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mName = parser.getAttributeValue(null, "name");
5194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        String comp = parser.getAttributeValue(null, "component");
5204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        mWallpaperComponent = comp != null
5214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                ? ComponentName.unflattenFromString(comp)
5224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                : null;
5239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
5249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
5259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } while (type != XmlPullParser.END_DOCUMENT);
5269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            success = true;
5279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NullPointerException e) {
5282d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NumberFormatException e) {
5302d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (XmlPullParserException e) {
5322d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
5342d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IndexOutOfBoundsException e) {
5362d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
5399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (stream != null) {
5409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                stream.close();
5419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
5439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // Ignore
5449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
5479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mWidth = -1;
5489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mHeight = -1;
5499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = "";
5509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
5529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    void settingsRestored() {
5549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
5559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
5569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            loadSettingsLocked();
5579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // If there's a wallpaper name, we use that.  If that can't be loaded, then we
5589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // use the default.
5599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if ("".equals(mName)) {
5609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = true;
5619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } else {
5629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = restoreNamedResourceLocked();
5639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
5679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            Log.e(TAG, "Failed to restore wallpaper: '" + mName + "'");
5689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = "";
5699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            WALLPAPER_FILE.delete();
5709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        saveSettingsLocked();
5729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
5739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    boolean restoreNamedResourceLocked() {
5759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) {
5769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String resName = mName.substring(4);
5779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String pkg = null;
5799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int colon = resName.indexOf(':');
5809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0) {
5819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                pkg = resName.substring(0, colon);
5829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String ident = null;
5859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int slash = resName.lastIndexOf('/');
5869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (slash > 0) {
5879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                ident = resName.substring(slash+1);
5889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String type = null;
5919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0 && slash > 0 && (slash-colon) > 1) {
5929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = resName.substring(colon+1, slash);
5939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (pkg != null && ident != null && type != null) {
5969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                int resId = -1;
5979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                InputStream res = null;
5989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                FileOutputStream fos = null;
5999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                try {
6009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
6019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Resources r = c.getResources();
6029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    resId = r.getIdentifier(resName, null, null);
6039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (resId == 0) {
6049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        Log.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
6059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                                + " ident=" + ident);
6069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        return false;
6079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    res = r.openRawResource(resId);
6109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    fos = new FileOutputStream(WALLPAPER_FILE);
6119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    byte[] buffer = new byte[32768];
6139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    int amt;
6149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    while ((amt=res.read(buffer)) > 0) {
6159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        fos.write(buffer, 0, amt);
6169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    // mWallpaperObserver will notice the close and send the change broadcast
6189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.d(TAG, "Restored wallpaper: " + resName);
6209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return true;
6219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (NameNotFoundException e) {
6229bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "Package name " + pkg + " not found");
6239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (Resources.NotFoundException e) {
6249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "Resource not found: " + resId);
6259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (IOException e) {
6269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "IOException while restoring wallpaper ", e);
6279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } finally {
6289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (res != null) {
6299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
6309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            res.close();
6319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
6329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (fos != null) {
6349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
6359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            fos.close();
6369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
6379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
6399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
6419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return false;
6429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
644