WallpaperManagerService.java revision d6c0b844a0eb128a9429aa01d23d15ce095ef479
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;
25eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport android.app.WallpaperInfo;
26111bd4acdb378266221b430a284f88a3990a3958Christopher Tateimport android.backup.BackupManager;
274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ComponentName;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ServiceConnection;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ResolveInfo;
334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ServiceInfo;
349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.pm.PackageManager.NameNotFoundException;
359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.res.Resources;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
37284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.os.Bundle;
384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.IBinder;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.FileObserver;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteCallbackList;
434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.ServiceManager;
440cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackbornimport android.os.SystemClock;
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
54eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.FileDescriptor;
559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException;
569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.InputStream;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileInputStream;
609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileOutputStream;
61eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.PrintWriter;
624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.List;
639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParser;
659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParserException;
669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlSerializer;
679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
68f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackbornimport com.android.internal.service.wallpaper.ImageWallpaper;
699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport com.android.internal.util.FastXmlSerializer;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
718cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornclass WallpaperManagerService extends IWallpaperManager.Stub {
724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    static final String TAG = "WallpaperService";
73cbf15048240ecf460957ac3de98a7efbccbbb754Dianne Hackborn    static final boolean DEBUG = false;
749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    Object mLock = new Object();
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
770cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    /**
780cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * Minimum time between crashes of a wallpaper service for us to consider
790cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * restarting it vs. just reverting to the static wallpaper.
800cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     */
810cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final long MIN_WALLPAPER_CRASH_TIME = 10000;
820cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn
830cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final File WALLPAPER_DIR = new File(
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "/data/data/com.android.settings/files");
850cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final String WALLPAPER = "wallpaper";
860cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER);
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * List of callbacks registered they should each be notified
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the wallpaper is changed.
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
928cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks
938cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn            = new RemoteCallbackList<IWallpaperManagerCallback>();
949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the wallpaper has changed. The CREATE is triggered when there is no
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * everytime the wallpaper is changed.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final FileObserver mWallpaperObserver = new FileObserver(
1029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                @Override
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                public void onEvent(int event, String path) {
105e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                    if (path == null) {
106e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                        return;
107e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato                    }
1089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    synchronized (mLock) {
1099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        // changing the wallpaper means we'll need to back up the new one
1109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        long origId = Binder.clearCallingIdentity();
1119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        BackupManager bm = new BackupManager(mContext);
1129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        bm.dataChanged();
1139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        Binder.restoreCallingIdentity(origId);
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        File changedFile = new File(WALLPAPER_DIR, path);
1169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        if (WALLPAPER_FILE.equals(changedFile)) {
1179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            notifyCallbacksLocked();
1189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            };
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final Context mContext;
1244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final IWindowManager mIWindowManager;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mWidth = -1;
1274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    int mHeight = -1;
1284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    String mName = "";
129d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron
130d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron    /**
131d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron     * The component name of the currently set live wallpaper. This will be null if the
132d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron     * wallpaper uses the built in ImageWallpaper component to display a bitmap.
133d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron     */
1344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    ComponentName mWallpaperComponent;
1354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    WallpaperConnection mWallpaperConnection;
1360cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    long mLastDiedTime;
1374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    class WallpaperConnection extends IWallpaperConnection.Stub
1394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            implements ServiceConnection {
140eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        final WallpaperInfo mInfo;
1414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        final Binder mToken = new Binder();
1424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperService mService;
1434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperEngine mEngine;
1444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
145eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        public WallpaperConnection(WallpaperInfo info) {
146eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            mInfo = info;
147eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
148eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
1494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceConnected(ComponentName name, IBinder service) {
1504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                if (mWallpaperConnection == this) {
1524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mService = IWallpaperService.Stub.asInterface(service);
1534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    attachServiceLocked(this);
154eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // XXX should probably do saveSettingsLocked() later
155eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // when we have an engine, but I'm not sure about
156eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // locking there and anyway we always need to be able to
157eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // recover if there is something wrong.
158eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    saveSettingsLocked();
1594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
1604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceDisconnected(ComponentName name) {
1644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mService = null;
1664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mEngine = null;
1670cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (mWallpaperConnection == this) {
1680cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    Log.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
1690cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    if ((mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
1700cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                            < SystemClock.uptimeMillis()) {
1710cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                        Log.w(TAG, "Reverting to built-in wallpaper!");
172322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                        bindWallpaperComponentLocked(null, false);
1730cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    }
1740cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
1754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1784c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void attachEngine(IWallpaperEngine engine) {
1794c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mEngine = engine;
1804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public ParcelFileDescriptor setWallpaper(String name) {
1834c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
1844c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                if (mWallpaperConnection == this) {
185eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    return updateWallpaperBitmapLocked(name);
1864c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
1874c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                return null;
1884c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
1894c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
1904c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
1914c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
1928cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public WallpaperManagerService(Context context) {
1934c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (DEBUG) Log.d(TAG, "WallpaperService startup");
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1954c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mIWindowManager = IWindowManager.Stub.asInterface(
1964c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                ServiceManager.getService(Context.WINDOW_SERVICE));
197e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato        WALLPAPER_DIR.mkdirs();
1989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        loadSettingsLocked();
199e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato        mWallpaperObserver.startWatching();
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.finalize();
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWallpaperObserver.stopWatching();
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
208f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    public void systemReady() {
209f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        synchronized (mLock) {
210f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
211322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                bindWallpaperComponentLocked(mWallpaperComponent, false);
212f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RuntimeException e) {
213f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Log.w(TAG, "Failure starting previous wallpaper", e);
214f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                try {
215322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    bindWallpaperComponentLocked(null, false);
216f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                } catch (RuntimeException e2) {
217f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    Log.w(TAG, "Failure starting default wallpaper", e2);
218f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    clearWallpaperComponentLocked();
219f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                }
220f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
221f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
222f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
223f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearWallpaper() {
2259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            File f = WALLPAPER_FILE;
2279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (f.exists()) {
2289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                f.delete();
2299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
2300cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
2310cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
232322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                bindWallpaperComponentLocked(null, false);
2330cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
2340cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
2350cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDimensionHints(int width, int height) throws RemoteException {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0 || height <= 0) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width and height must be > 0");
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (width != mWidth || height != mHeight) {
2489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mWidth = width;
2499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mHeight = height;
2509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                saveSettingsLocked();
251284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (mWallpaperConnection != null) {
252284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    if (mWallpaperConnection.mEngine != null) {
253284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        try {
254284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                            mWallpaperConnection.mEngine.setDesiredSize(
255284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                                    width, height);
256284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        } catch (RemoteException e) {
257284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
258284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        notifyCallbacksLocked();
259284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    }
260284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
2619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidthHint() throws RemoteException {
2669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return mWidth;
2689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeightHint() throws RemoteException {
2729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return mHeight;
2749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
277284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
278284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn            Bundle outParams) {
2799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
2809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
281284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (outParams != null) {
282284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    outParams.putInt("width", mWidth);
283284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    outParams.putInt("height", mHeight);
284284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
2859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mCallbacks.register(cb);
2869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                File f = WALLPAPER_FILE;
2879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (!f.exists()) {
2889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return null;
2899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
2909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
2919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (FileNotFoundException e) {
2929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                /* Shouldn't happen as we check to see if the file exists */
2934c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                Log.w(TAG, "Error getting wallpaper", e);
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return null;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    public WallpaperInfo getWallpaperInfo() {
300eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
301eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            if (mWallpaperConnection != null) {
302eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                return mWallpaperConnection.mInfo;
303eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
304eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return null;
305eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
306eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
307eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
3089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public ParcelFileDescriptor setWallpaper(String name) {
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER);
3109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
3110cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
3120cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
3130cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name);
3140cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (pfd != null) {
315322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // Bind the wallpaper to an ImageWallpaper
316322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    bindWallpaperComponentLocked(null, true);
3170cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    saveSettingsLocked();
3180cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
3190cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                return pfd;
3200cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
3210cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
3224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
3234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
3244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    ParcelFileDescriptor updateWallpaperBitmapLocked(String name) {
3274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (name == null) name = "";
3284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
3294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
3304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    MODE_CREATE|MODE_READ_WRITE);
3319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = name;
3324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            return fd;
3334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (FileNotFoundException e) {
3344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            Log.w(TAG, "Error setting wallpaper", e);
3354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
3364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return null;
3374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
3384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
3394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setWallpaperComponent(ComponentName name) {
3404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
3414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mLock) {
3424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
3439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
344322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                bindWallpaperComponentLocked(name, false);
345f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } finally {
346f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Binder.restoreCallingIdentity(ident);
347f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
348f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
349f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
350f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
351322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron    void bindWallpaperComponentLocked(ComponentName componentName, boolean isBitmap) {
352f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        // Has the component changed?
353f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        if (mWallpaperConnection != null) {
354f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (mWallpaperComponent == null) {
355322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                if (componentName == null) {
356f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    // Still using default wallpaper.
357f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    return;
3584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
359322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            } else if (mWallpaperComponent.equals(componentName)) {
360f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                // Changing to same wallpaper.
361f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                return;
362f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
363f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
364f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
365f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        try {
366322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            ComponentName realComponentName = componentName;
367322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            if (realComponentName == null) {
368322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                String defaultComponent =
369322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    mContext.getString(com.android.internal.R.string.default_wallpaper_component);
370322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                if (defaultComponent != null && !isBitmap) {
371322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // See if there is a default wallpaper component specified
372322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // Only look for this if the wallpaper is not being set to a bitmap
373322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    realComponentName = ComponentName.unflattenFromString(defaultComponent);
374d6c0b844a0eb128a9429aa01d23d15ce095ef479Mike Cleron                    componentName = realComponentName;
375322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
376322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                if (realComponentName == null) {
377322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // Fall back to static image wallpaper
378322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    realComponentName = new ComponentName("android",
379322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                            ImageWallpaper.class.getName());
380322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //clearWallpaperComponentLocked();
381322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //return;
382322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
383f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
384322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            ServiceInfo si = mContext.getPackageManager().getServiceInfo(realComponentName,
385f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
386f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
387f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                throw new SecurityException("Selected service does not require "
388f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + android.Manifest.permission.BIND_WALLPAPER
389322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                        + ": " + realComponentName);
390f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
391f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
392eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            WallpaperInfo wi = null;
393eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
394f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
395322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            if (componentName != null) {
3964c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                // Make sure the selected service is actually a wallpaper service.
3974c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                List<ResolveInfo> ris = mContext.getPackageManager()
398eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        .queryIntentServices(intent, PackageManager.GET_META_DATA);
3994c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                for (int i=0; i<ris.size(); i++) {
4004c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    ServiceInfo rsi = ris.get(i).serviceInfo;
4014c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    if (rsi.name.equals(si.name) &&
4024c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                            rsi.packageName.equals(si.packageName)) {
403eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        try {
404eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            wi = new WallpaperInfo(mContext, ris.get(i));
405eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (XmlPullParserException e) {
406eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            throw new IllegalArgumentException(e);
407eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (IOException e) {
408eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            throw new IllegalArgumentException(e);
409eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
4104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        break;
4114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    }
4124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
413eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                if (wi == null) {
4144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    throw new SecurityException("Selected service is not a wallpaper: "
415322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                            + realComponentName);
4164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
4179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
418f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
419f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            // Bind the service!
420eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            WallpaperConnection newConn = new WallpaperConnection(wi);
421322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            intent.setComponent(realComponentName);
422dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
423dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                    com.android.internal.R.string.wallpaper_binding_label);
424dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
425eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    mContext, 0,
426eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
427eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
428eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            0));
429f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!mContext.bindService(intent, newConn,
430f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    Context.BIND_AUTO_CREATE)) {
431f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                throw new IllegalArgumentException("Unable to bind service: "
432322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                        + componentName);
433f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
434f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
435f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            clearWallpaperComponentLocked();
436322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            mWallpaperComponent = componentName;
437f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            mWallpaperConnection = newConn;
4380cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            mLastDiedTime = SystemClock.uptimeMillis();
439f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
440f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                if (DEBUG) Log.v(TAG, "Adding window token: " + newConn.mToken);
441f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                mIWindowManager.addWindowToken(newConn.mToken,
442f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        WindowManager.LayoutParams.TYPE_WALLPAPER);
443f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RemoteException e) {
444f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
445f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
446f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
447322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            throw new IllegalArgumentException("Unknown component " + componentName);
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    void clearWallpaperComponentLocked() {
4524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mWallpaperComponent = null;
4534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (mWallpaperConnection != null) {
4544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mWallpaperConnection.mEngine != null) {
4554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                try {
4564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mWallpaperConnection.mEngine.destroy();
4574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                } catch (RemoteException e) {
4584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
4594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
4604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mContext.unbindService(mWallpaperConnection);
461e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            try {
462e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                if (DEBUG) Log.v(TAG, "Removing window token: "
463e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                        + mWallpaperConnection.mToken);
464e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn                mIWindowManager.removeWindowToken(mWallpaperConnection.mToken);
465e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            } catch (RemoteException e) {
466e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            }
4674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mWallpaperConnection = null;
4684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
4694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
4704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    void attachServiceLocked(WallpaperConnection conn) {
4724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
4733be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn            conn.mService.attach(conn, conn.mToken,
4743be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
4753be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    mWidth, mHeight);
4764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (RemoteException e) {
4774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            Log.w(TAG, "Failed attaching wallpaper; clearing", e);
478322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron            bindWallpaperComponentLocked(null, false);
4794c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
4804c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
4814c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
4829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void notifyCallbacksLocked() {
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int n = mCallbacks.beginBroadcast();
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCallbacks.getBroadcastItem(i).onWallpaperChanged();
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The RemoteCallbackList will take care of removing
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the dead object for us.
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCallbacks.finishBroadcast();
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendBroadcast(intent);
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPermission(String permission) {
4999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", must have permission " + permission);
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private static JournaledFile makeJournaledFile() {
5069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        final String base = "/data/system/wallpaper_info.xml";
5079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return new JournaledFile(new File(base), new File(base + ".tmp"));
5089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
5099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void saveSettingsLocked() {
5119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        JournaledFile journal = makeJournaledFile();
5129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileOutputStream stream = null;
5139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
5149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileOutputStream(journal.chooseForWrite(), false);
5159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlSerializer out = new FastXmlSerializer();
5169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.setOutput(stream, "utf-8");
5179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startDocument(null, true);
5189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startTag(null, "wp");
5209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "width", Integer.toString(mWidth));
5219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "height", Integer.toString(mHeight));
5229bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.attribute(null, "name", mName);
5234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            if (mWallpaperComponent != null) {
5244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                out.attribute(null, "component",
5254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        mWallpaperComponent.flattenToShortString());
5264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
5279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endTag(null, "wp");
5289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endDocument();
5309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream.close();
5319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.commit();
5329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
5339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
5349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (stream != null) {
5359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    stream.close();
5369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
5379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (IOException ex) {
5389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                // Ignore
5399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.rollback();
5419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
5439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    private void loadSettingsLocked() {
5459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        JournaledFile journal = makeJournaledFile();
5469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileInputStream stream = null;
5479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        File file = journal.chooseForRead();
5489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
5499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
5509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileInputStream(file);
5519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlPullParser parser = Xml.newPullParser();
5529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            parser.setInput(stream, null);
5539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int type;
5559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            do {
5569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = parser.next();
5579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (type == XmlPullParser.START_TAG) {
5589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    String tag = parser.getName();
5599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if ("wp".equals(tag)) {
5609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mWidth = Integer.parseInt(parser.getAttributeValue(null, "width"));
5619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mHeight = Integer.parseInt(parser.getAttributeValue(null, "height"));
5629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        mName = parser.getAttributeValue(null, "name");
5634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        String comp = parser.getAttributeValue(null, "component");
5644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        mWallpaperComponent = comp != null
5654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                ? ComponentName.unflattenFromString(comp)
5664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                : null;
5679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
5689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
5699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } while (type != XmlPullParser.END_DOCUMENT);
5709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            success = true;
5719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NullPointerException e) {
5722d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NumberFormatException e) {
5742d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (XmlPullParserException e) {
5762d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
5782d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IndexOutOfBoundsException e) {
5802d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato            Log.w(TAG, "failed parsing " + file + " " + e);
5819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
5839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (stream != null) {
5849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                stream.close();
5859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
5879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // Ignore
5889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
5919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mWidth = -1;
5929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mHeight = -1;
5939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = "";
5949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
5969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
5979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    void settingsRestored() {
5989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
5999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
6009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            loadSettingsLocked();
6019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // If there's a wallpaper name, we use that.  If that can't be loaded, then we
6029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // use the default.
6039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if ("".equals(mName)) {
6049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = true;
6059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } else {
6069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = restoreNamedResourceLocked();
6079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
6099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
6119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            Log.e(TAG, "Failed to restore wallpaper: '" + mName + "'");
6129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mName = "";
6139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            WALLPAPER_FILE.delete();
6149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
6159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        saveSettingsLocked();
6169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
6179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    boolean restoreNamedResourceLocked() {
6199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) {
6209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String resName = mName.substring(4);
6219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6229bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String pkg = null;
6239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int colon = resName.indexOf(':');
6249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0) {
6259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                pkg = resName.substring(0, colon);
6269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String ident = null;
6299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int slash = resName.lastIndexOf('/');
6309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (slash > 0) {
6319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                ident = resName.substring(slash+1);
6329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String type = null;
6359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0 && slash > 0 && (slash-colon) > 1) {
6369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = resName.substring(colon+1, slash);
6379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (pkg != null && ident != null && type != null) {
6409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                int resId = -1;
6419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                InputStream res = null;
6429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                FileOutputStream fos = null;
6439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                try {
6449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
6459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Resources r = c.getResources();
6469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    resId = r.getIdentifier(resName, null, null);
6479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (resId == 0) {
6489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        Log.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
6499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                                + " ident=" + ident);
6509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        return false;
6519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    res = r.openRawResource(resId);
6549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    fos = new FileOutputStream(WALLPAPER_FILE);
6559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    byte[] buffer = new byte[32768];
6579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    int amt;
6589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    while ((amt=res.read(buffer)) > 0) {
6599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        fos.write(buffer, 0, amt);
6609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    // mWallpaperObserver will notice the close and send the change broadcast
6629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
6639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.d(TAG, "Restored wallpaper: " + resName);
6649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return true;
6659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (NameNotFoundException e) {
6669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "Package name " + pkg + " not found");
6679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (Resources.NotFoundException e) {
6689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "Resource not found: " + resId);
6699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (IOException e) {
6709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Log.e(TAG, "IOException while restoring wallpaper ", e);
6719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } finally {
6729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (res != null) {
6739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
6749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            res.close();
6759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
6769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (fos != null) {
6789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
6799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            fos.close();
6809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
6819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
6829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
6839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
6849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
6859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return false;
6869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
687eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
688eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    @Override
689eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
690eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
691eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
692eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
693eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Permission Denial: can't dump wallpaper service from from pid="
694eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + Binder.getCallingPid()
695eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + ", uid=" + Binder.getCallingUid());
696eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return;
697eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
698eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
699eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
700eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Current Wallpaper Service state:");
701eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.print("  mWidth="); pw.print(mWidth);
702eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    pw.print(" mHeight="); pw.println(mHeight);
703eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.print("  mName="); pw.println(mName);
704eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.print("  mWallpaperComponent="); pw.println(mWallpaperComponent);
705eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            if (mWallpaperConnection != null) {
706eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                WallpaperConnection conn = mWallpaperConnection;
707eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("  Wallpaper connection ");
708eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        pw.print(conn); pw.println(":");
709eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("    mInfo.component="); pw.println(conn.mInfo.getComponent());
710eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("    mToken="); pw.println(conn.mToken);
711eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("    mService="); pw.println(conn.mService);
712eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("    mEngine="); pw.println(conn.mEngine);
713eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                pw.print("    mLastDiedTime=");
714eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        pw.println(mLastDiedTime - SystemClock.uptimeMillis());
715eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
716eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
717eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
719