WallpaperManagerService.java revision 554cb0c290406f5bba34908489db5382a69d0a9a
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;
264528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupManager;
2737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport android.app.backup.WallpaperBackupHelper;
28135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.content.BroadcastReceiver;
294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ComponentName;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
32135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.content.IntentFilter;
334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ServiceConnection;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ResolveInfo;
364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ServiceInfo;
379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.pm.PackageManager.NameNotFoundException;
389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.res.Resources;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
40284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackbornimport android.os.Bundle;
41135936072b24b090fb63940aea41b408d855a4f3Amith Yamasaniimport android.os.Environment;
428bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackbornimport android.os.FileUtils;
434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.IBinder;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.FileObserver;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteCallbackList;
48554cb0c290406f5bba34908489db5382a69d0a9arpcraigimport android.os.SELinux;
494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.ServiceManager;
500cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackbornimport android.os.SystemClock;
5137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport android.os.UserId;
524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperConnection;
534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperEngine;
544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperService;
554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService;
568a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
5737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport android.util.SparseArray;
589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.util.Xml;
5944bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackbornimport android.view.Display;
604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.IWindowManager;
614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.WindowManager;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
63eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.FileDescriptor;
649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException;
659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.InputStream;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileInputStream;
699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileOutputStream;
70eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.PrintWriter;
714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.List;
729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParser;
749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParserException;
759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlSerializer;
769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
7721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor;
782269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.FastXmlSerializer;
791afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornimport com.android.internal.util.JournaledFile;
8037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport com.android.server.am.ActivityManagerService;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
828cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornclass WallpaperManagerService extends IWallpaperManager.Stub {
834c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    static final String TAG = "WallpaperService";
84cbf15048240ecf460957ac3de98a7efbccbbb754Dianne Hackborn    static final boolean DEBUG = false;
859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
86407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    final Object mLock = new Object[0];
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
880cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    /**
890cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * Minimum time between crashes of a wallpaper service for us to consider
900cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * restarting it vs. just reverting to the static wallpaper.
910cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     */
920cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final long MIN_WALLPAPER_CRASH_TIME = 10000;
930cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn
9437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
950cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final String WALLPAPER = "wallpaper";
9637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static final String WALLPAPER_INFO = "wallpaper_info.xml";
979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the wallpaper has changed. The CREATE is triggered when there is no
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * everytime the wallpaper is changed.
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private class WallpaperObserver extends FileObserver {
10537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
10637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final WallpaperData mWallpaper;
10737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final File mWallpaperDir;
10837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final File mWallpaperFile;
10937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
11037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public WallpaperObserver(WallpaperData wallpaper) {
11137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
11237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    CLOSE_WRITE | DELETE | DELETE_SELF);
11337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperDir = getWallpaperDir(wallpaper.userId);
11437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaper = wallpaper;
11537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
11637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
11737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
11837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        @Override
11937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public void onEvent(int event, String path) {
12037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (path == null) {
12137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                return;
12237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
12337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            synchronized (mLock) {
12437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                // changing the wallpaper means we'll need to back up the new one
12537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                long origId = Binder.clearCallingIdentity();
12637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                BackupManager bm = new BackupManager(mContext);
12737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bm.dataChanged();
12837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                Binder.restoreCallingIdentity(origId);
12937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
13037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                File changedFile = new File(mWallpaperDir, path);
13137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaperFile.equals(changedFile)) {
13237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    notifyCallbacksLocked(mWallpaper);
13337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
13437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            || mWallpaper.imageWallpaperPending) {
13537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (event == CLOSE_WRITE) {
13637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            mWallpaper.imageWallpaperPending = false;
1379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        }
13837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
13937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                false, mWallpaper);
14037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        saveSettingsLocked(mWallpaper);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
14437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
14537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
14637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
1474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final Context mContext;
1484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final IWindowManager mIWindowManager;
14921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    final MyPackageMonitor mMonitor;
15037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    WallpaperData mLastWallpaper;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
15307213e6d8895af10951851435adf96a779863f6cDianne Hackborn
15437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    int mCurrentUserId;
15537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
15637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static class WallpaperData {
15737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
15837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId;
15937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
16037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File wallpaperFile;
16137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
16237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
16337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Client is currently writing a new image wallpaper.
16437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
16537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        boolean imageWallpaperPending;
16637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
16737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
16837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Resource name if using a picture from the wallpaper gallery
16937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
17037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        String name = "";
17137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
17237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
17337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * The component name of the currently set live wallpaper.
17437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
17537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName wallpaperComponent;
17637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
17737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
17837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * The component name of the wallpaper that should be set next.
17937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
18037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName nextWallpaperComponent;
18137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
18237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
18337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Name of the component used to display bitmap wallpapers from either the gallery or
18437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * built-in wallpapers.
18537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
18637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
18737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                "com.android.systemui.ImageWallpaper");
18837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
18937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperConnection connection;
19037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        long lastDiedTime;
19137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        boolean wallpaperUpdating;
19237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperObserver wallpaperObserver;
19337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
19437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
19537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * List of callbacks registered they should each be notified when the wallpaper is changed.
19637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
19737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        private RemoteCallbackList<IWallpaperManagerCallback> callbacks
19837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                = new RemoteCallbackList<IWallpaperManagerCallback>();
19937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
20037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int width = -1;
20137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int height = -1;
20237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
20337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData(int userId) {
20437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            this.userId = userId;
20537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
20637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
20737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
20807213e6d8895af10951851435adf96a779863f6cDianne Hackborn
2094c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    class WallpaperConnection extends IWallpaperConnection.Stub
2104c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            implements ServiceConnection {
211eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        final WallpaperInfo mInfo;
2124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        final Binder mToken = new Binder();
2134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperService mService;
2144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperEngine mEngine;
21537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData mWallpaper;
2164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
21737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
218eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            mInfo = info;
21937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaper = wallpaper;
220eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
221eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
2224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceConnected(ComponentName name, IBinder service) {
2234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
22437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
22537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
2264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mService = IWallpaperService.Stub.asInterface(service);
22737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    attachServiceLocked(this, mWallpaper);
228eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // XXX should probably do saveSettingsLocked() later
229eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // when we have an engine, but I'm not sure about
230eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // locking there and anyway we always need to be able to
231eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // recover if there is something wrong.
23237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    saveSettingsLocked(mWallpaper);
2334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
2344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceDisconnected(ComponentName name) {
2384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
2394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mService = null;
2404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mEngine = null;
24137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
24237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
24337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (!mWallpaper.wallpaperUpdating
24437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
24537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                > SystemClock.uptimeMillis()
24637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && mWallpaper.userId == mCurrentUserId) {
2478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        Slog.w(TAG, "Reverting to built-in wallpaper!");
24837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperLocked(true, mWallpaper.userId);
2490cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    }
2500cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
2514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
25337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
2544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void attachEngine(IWallpaperEngine engine) {
2554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mEngine = engine;
2564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
25737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
2584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public ParcelFileDescriptor setWallpaper(String name) {
2594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
26037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
26137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    return updateWallpaperBitmapLocked(name, mWallpaper);
2624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
2634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                return null;
2644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
26737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
26821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    class MyPackageMonitor extends PackageMonitor {
26921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
27021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onPackageUpdateFinished(String packageName, int uid) {
27121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mLock) {
27237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
27337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
27437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent != null
27537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
27637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperUpdating = false;
27737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        ComponentName comp = wallpaper.wallpaperComponent;
27837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperComponentLocked(wallpaper);
27937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        // Do this only for the current user's wallpaper
28037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (wallpaper.userId == mCurrentUserId
28137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
28237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.w(TAG, "Wallpaper no longer available; reverting to default");
28337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            clearWallpaperLocked(false, wallpaper.userId);
28437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        }
28580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    }
28680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
28780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
28880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        }
28980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn
29080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        @Override
29180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        public void onPackageModified(String packageName) {
29280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            synchronized (mLock) {
29337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
29437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
29537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent == null
29637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
29737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        continue;
29837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
299d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    doPackagesChangedLocked(true, wallpaper);
30021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
30121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
30221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
30321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
30421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
30521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onPackageUpdateStarted(String packageName, int uid) {
30621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mLock) {
30737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
30837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
30937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent != null
31037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
31137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperUpdating = true;
31237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
31321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
31421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
31521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
31621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
31721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
31821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
319d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            synchronized (mLock) {
320d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                boolean changed = false;
321d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                for (int i = 0; i < mWallpaperMap.size(); i++) {
322d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
323d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    boolean res = doPackagesChangedLocked(doit, wallpaper);
324d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    changed |= res;
325d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
326d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                return changed;
32737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
32821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
32921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
33021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
33121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onSomePackagesChanged() {
332d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            synchronized (mLock) {
333d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                for (int i = 0; i < mWallpaperMap.size(); i++) {
334d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
335d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    doPackagesChangedLocked(true, wallpaper);
336d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
33737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
33821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
33937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
340d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn        boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
34121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            boolean changed = false;
342d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.wallpaperComponent != null) {
343d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                int change = isPackageDisappearing(wallpaper.wallpaperComponent
344d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        .getPackageName());
345d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                if (change == PACKAGE_PERMANENT_CHANGE
346d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        || change == PACKAGE_TEMPORARY_CHANGE) {
347d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    changed = true;
348d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    if (doit) {
349d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        Slog.w(TAG, "Wallpaper uninstalled, removing: "
35037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                + wallpaper.wallpaperComponent);
35137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperLocked(false, wallpaper.userId);
35221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
35321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
354d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
355d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.nextWallpaperComponent != null) {
356d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
357d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        .getPackageName());
358d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                if (change == PACKAGE_PERMANENT_CHANGE
359d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        || change == PACKAGE_TEMPORARY_CHANGE) {
360d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    wallpaper.nextWallpaperComponent = null;
361d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
362d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
363d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.wallpaperComponent != null
364d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
365d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                try {
366d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    mContext.getPackageManager().getServiceInfo(
367d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            wallpaper.wallpaperComponent, 0);
368d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                } catch (NameNotFoundException e) {
369d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    Slog.w(TAG, "Wallpaper component gone, removing: "
370d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            + wallpaper.wallpaperComponent);
371d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    clearWallpaperLocked(false, wallpaper.userId);
372d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
373d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
374d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.nextWallpaperComponent != null
375d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
376d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                try {
377d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    mContext.getPackageManager().getServiceInfo(
378d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            wallpaper.nextWallpaperComponent, 0);
379d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                } catch (NameNotFoundException e) {
380d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    wallpaper.nextWallpaperComponent = null;
38121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
38221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
38321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return changed;
38421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
38521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
38621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
3878cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public WallpaperManagerService(Context context) {
3888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "WallpaperService startup");
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
3904c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mIWindowManager = IWindowManager.Stub.asInterface(
3914c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                ServiceManager.getService(Context.WINDOW_SERVICE));
39221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        mMonitor = new MyPackageMonitor();
393d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn        mMonitor.register(context, null, true);
39437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WALLPAPER_BASE_DIR.mkdirs();
39537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        loadSettingsLocked(0);
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private static File getWallpaperDir(int userId) {
39937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        return new File(WALLPAPER_BASE_DIR + "/" + userId);
40037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
40137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.finalize();
40537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        for (int i = 0; i < mWallpaperMap.size(); i++) {
40637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.valueAt(i);
40737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.wallpaperObserver.stopWatching();
40837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
410135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
411f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    public void systemReady() {
4128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "systemReady");
41337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(0);
41437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        switchWallpaper(wallpaper);
41537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
41637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperObserver.startWatching();
41737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
418135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        IntentFilter userFilter = new IntentFilter();
419135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        userFilter.addAction(Intent.ACTION_USER_SWITCHED);
420135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        userFilter.addAction(Intent.ACTION_USER_REMOVED);
421135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        mContext.registerReceiver(new BroadcastReceiver() {
42237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            @Override
423135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            public void onReceive(Context context, Intent intent) {
424135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                String action = intent.getAction();
425135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
426135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                    switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
427135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
428135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                    removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
429135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                }
43037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
431135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        }, userFilter);
43237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
43337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
43437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    String getName() {
43537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        return mWallpaperMap.get(0).name;
43637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
43737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    void removeUser(int userId) {
439135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        synchronized (mLock) {
440135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
441135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            if (wallpaper != null) {
442135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                wallpaper.wallpaperObserver.stopWatching();
443135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                mWallpaperMap.remove(userId);
444135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            }
445135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
446135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            wallpaperFile.delete();
447135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
448135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            wallpaperInfoFile.delete();
449135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        }
450135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    }
451135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
45237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void switchUser(int userId) {
45337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        synchronized (mLock) {
45437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mCurrentUserId = userId;
45537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
45637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper == null) {
45737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper = new WallpaperData(userId);
45837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                mWallpaperMap.put(userId, wallpaper);
45937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                loadSettingsLocked(userId);
46037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
46137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.wallpaperObserver.startWatching();
46237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
46337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            switchWallpaper(wallpaper);
46437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
46537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
46637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
46737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void switchWallpaper(WallpaperData wallpaper) {
468f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        synchronized (mLock) {
46980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            RuntimeException e = null;
470f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
47137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                ComponentName cname = wallpaper.wallpaperComponent != null ?
47237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
47337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
47480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return;
475f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                }
47680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            } catch (RuntimeException e1) {
47780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                e = e1;
478f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
47980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            Slog.w(TAG, "Failure starting previous wallpaper", e);
48037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            clearWallpaperLocked(false, wallpaper.userId);
481f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
482f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
48337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearWallpaper() {
4858a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "clearWallpaper");
4869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
48737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            clearWallpaperLocked(false, UserId.getCallingUserId());
48821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
48921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
49021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
49137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void clearWallpaperLocked(boolean defaultFailed, int userId) {
49237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
49337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File f = new File(getWallpaperDir(userId), WALLPAPER);
49421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (f.exists()) {
49521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            f.delete();
49621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
49721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        final long ident = Binder.clearCallingIdentity();
49880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        RuntimeException e = null;
49921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        try {
50037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.imageWallpaperPending = false;
50137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (userId != mCurrentUserId) return;
50280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            if (bindWallpaperComponentLocked(defaultFailed
50337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    ? wallpaper.imageWallpaperComponent
50437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    : null, true, false, wallpaper)) {
50580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return;
50680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
50780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        } catch (IllegalArgumentException e1) {
50880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            e = e1;
50921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        } finally {
51021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            Binder.restoreCallingIdentity(ident);
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
51280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn
51380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // This can happen if the default wallpaper component doesn't
51480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // exist.  This should be a system configuration problem, but
51580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // let's not let it crash the system and just live with no
51680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // wallpaper.
51780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        Slog.e(TAG, "Default wallpaper component not found!", e);
51837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        clearWallpaperComponentLocked(wallpaper);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDimensionHints(int width, int height) throws RemoteException {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
52437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId = UserId.getCallingUserId();
52537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
52637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
52737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
52837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0 || height <= 0) {
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width and height must be > 0");
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
53437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (width != wallpaper.width || height != wallpaper.height) {
53537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.width = width;
53637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.height = height;
53737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                saveSettingsLocked(wallpaper);
53837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mCurrentUserId != userId) return; // Don't change the properties now
53937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.connection != null) {
54037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.connection.mEngine != null) {
541284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        try {
54237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper.connection.mEngine.setDesiredSize(
543284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                                    width, height);
544284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        } catch (RemoteException e) {
545284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
54637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        notifyCallbacksLocked(wallpaper);
547284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    }
548284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
5499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidthHint() throws RemoteException {
5549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
55537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
55637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            return wallpaper.width;
5579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeightHint() throws RemoteException {
5619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
56237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(UserId.getCallingUserId());
56337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            return wallpaper.height;
5649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
567284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
568284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn            Bundle outParams) {
5699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
57037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // This returns the current user's wallpaper, if called by a system service. Else it
57137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // returns the wallpaper for the calling user.
57237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int callingUid = Binder.getCallingUid();
57337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int wallpaperUserId = 0;
57437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (callingUid == android.os.Process.SYSTEM_UID) {
57537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaperUserId = mCurrentUserId;
57637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            } else {
57737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaperUserId = UserId.getUserId(callingUid);
57837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
57937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
5809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
581284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (outParams != null) {
58237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    outParams.putInt("width", wallpaper.width);
58337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    outParams.putInt("height", wallpaper.height);
584284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
58537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.callbacks.register(cb);
58637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
5879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (!f.exists()) {
5889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return null;
5899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
5909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
5919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (FileNotFoundException e) {
5929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                /* Shouldn't happen as we check to see if the file exists */
5938a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Error getting wallpaper", e);
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return null;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    public WallpaperInfo getWallpaperInfo() {
60037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId = UserId.getCallingUserId();
601eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
60237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
60337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection != null) {
60437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                return wallpaper.connection.mInfo;
605eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
606eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return null;
607eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
608eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
60937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
6109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public ParcelFileDescriptor setWallpaper(String name) {
6118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "setWallpaper");
61237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId = UserId.getCallingUserId();
61337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
61437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
61537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
61637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER);
6189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
6190cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
6200cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
62137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
6220cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (pfd != null) {
62337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.imageWallpaperPending = true;
6240cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
6250cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                return pfd;
6260cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
6270cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
6284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
6294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
6304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
6314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
63237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
6334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (name == null) name = "";
6344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
63537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File dir = getWallpaperDir(wallpaper.userId);
63637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!dir.exists()) {
63737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                dir.mkdir();
638ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                FileUtils.setPermissions(
63937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        dir.getPath(),
640ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
641ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                        -1, -1);
642ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn            }
643554cb0c290406f5bba34908489db5382a69d0a9arpcraig            File file = new File(dir, WALLPAPER);
644554cb0c290406f5bba34908489db5382a69d0a9arpcraig            ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
6454c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    MODE_CREATE|MODE_READ_WRITE);
646554cb0c290406f5bba34908489db5382a69d0a9arpcraig            if (!SELinux.restorecon(file)) {
647554cb0c290406f5bba34908489db5382a69d0a9arpcraig                return null;
648554cb0c290406f5bba34908489db5382a69d0a9arpcraig            }
64937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = name;
6504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            return fd;
6514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (FileNotFoundException e) {
6528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "Error setting wallpaper", e);
6534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
6544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return null;
6554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
6564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
6574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setWallpaperComponent(ComponentName name) {
6588a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
65937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId = UserId.getCallingUserId();
66037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
66137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
66237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
66337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
6644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
6654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mLock) {
6664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
6679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
66837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.imageWallpaperPending = false;
66937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bindWallpaperComponentLocked(name, false, true, wallpaper);
670f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } finally {
671f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Binder.restoreCallingIdentity(ident);
672f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
673f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
674f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
675f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
67637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
67737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            boolean fromUser, WallpaperData wallpaper) {
6788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
679f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        // Has the component changed?
6809ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn        if (!force) {
68137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection != null) {
68237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.wallpaperComponent == null) {
6839ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    if (componentName == null) {
6849ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
6859ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        // Still using default wallpaper.
68680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        return true;
6879ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    }
68837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                } else if (wallpaper.wallpaperComponent.equals(componentName)) {
6899ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    // Changing to same wallpaper.
6909ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    if (DEBUG) Slog.v(TAG, "same wallpaper");
69180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return true;
6924c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
693f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
694f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
695f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
696f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        try {
697a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            if (componentName == null) {
698322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                String defaultComponent =
699322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    mContext.getString(com.android.internal.R.string.default_wallpaper_component);
700a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (defaultComponent != null) {
701322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // See if there is a default wallpaper component specified
702a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                    componentName = ComponentName.unflattenFromString(defaultComponent);
7038a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
704322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
705a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (componentName == null) {
706322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // Fall back to static image wallpaper
70737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    componentName = wallpaper.imageWallpaperComponent;
708322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //clearWallpaperComponentLocked();
709322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //return;
7108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Using image wallpaper");
711322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
712f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
713a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
714f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
715f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
71680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                String msg = "Selected service does not require "
717f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + android.Manifest.permission.BIND_WALLPAPER
71880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        + ": " + componentName;
71980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                if (fromUser) {
72080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    throw new SecurityException(msg);
72180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
72280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                Slog.w(TAG, msg);
72380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return false;
724f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
725f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
726eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            WallpaperInfo wi = null;
727eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
728f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
72937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
7304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                // Make sure the selected service is actually a wallpaper service.
7314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                List<ResolveInfo> ris = mContext.getPackageManager()
732eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        .queryIntentServices(intent, PackageManager.GET_META_DATA);
7334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                for (int i=0; i<ris.size(); i++) {
7344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    ServiceInfo rsi = ris.get(i).serviceInfo;
7354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    if (rsi.name.equals(si.name) &&
7364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                            rsi.packageName.equals(si.packageName)) {
737eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        try {
738eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            wi = new WallpaperInfo(mContext, ris.get(i));
739eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (XmlPullParserException e) {
74080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            if (fromUser) {
74180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                                throw new IllegalArgumentException(e);
74280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            }
74380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            Slog.w(TAG, e);
74480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            return false;
745eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (IOException e) {
74680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            if (fromUser) {
74780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                                throw new IllegalArgumentException(e);
74880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            }
74980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            Slog.w(TAG, e);
75080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            return false;
751eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
7524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        break;
7534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    }
7544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
755eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                if (wi == null) {
75680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    String msg = "Selected service is not a wallpaper: "
75780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            + componentName;
75880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    if (fromUser) {
75980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        throw new SecurityException(msg);
76080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    }
76180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    Slog.w(TAG, msg);
76280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return false;
7634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
7649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
765f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
766f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            // Bind the service!
7678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
76837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
769a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            intent.setComponent(componentName);
77037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int serviceUserId = wallpaper.userId;
77137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // Because the image wallpaper is running in the system ui
77237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (componentName.equals(wallpaper.imageWallpaperComponent)) {
77337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                serviceUserId = 0;
77437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
775dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
776dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                    com.android.internal.R.string.wallpaper_binding_label);
777dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
778eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    mContext, 0,
779eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
780eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
781eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            0));
78237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
78380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                String msg = "Unable to bind service: "
78480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        + componentName;
78580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                if (fromUser) {
78680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    throw new IllegalArgumentException(msg);
78780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
78880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                Slog.w(TAG, msg);
78980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return false;
790f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
79137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
79237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                detachWallpaperLocked(mLastWallpaper);
79337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
79437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.wallpaperComponent = componentName;
79537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection = newConn;
79637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.lastDiedTime = SystemClock.uptimeMillis();
797f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
79837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.userId == mCurrentUserId) {
79937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (DEBUG)
80037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        Slog.v(TAG, "Adding window token: " + newConn.mToken);
80137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mIWindowManager.addWindowToken(newConn.mToken,
80237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            WindowManager.LayoutParams.TYPE_WALLPAPER);
80337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mLastWallpaper = wallpaper;
80437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                }
805f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RemoteException e) {
806f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
807f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
80880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            String msg = "Unknown component " + componentName;
80980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            if (fromUser) {
81080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                throw new IllegalArgumentException(msg);
81180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
81280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            Slog.w(TAG, msg);
81380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            return false;
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
81580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        return true;
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
81737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
81837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void detachWallpaperLocked(WallpaperData wallpaper) {
81937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.connection != null) {
82037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection.mEngine != null) {
8214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                try {
82237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.connection.mEngine.destroy();
8234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                } catch (RemoteException e) {
8244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
8254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
82637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mContext.unbindService(wallpaper.connection);
827e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            try {
82837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (DEBUG)
82937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
83037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
831e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            } catch (RemoteException e) {
832e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            }
83337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection.mService = null;
83437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection.mEngine = null;
83537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection = null;
8364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
8374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
83837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
83937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void clearWallpaperComponentLocked(WallpaperData wallpaper) {
84037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperComponent = null;
84137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        detachWallpaperLocked(wallpaper);
84237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
84337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
84437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
8454c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
8463be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn            conn.mService.attach(conn, conn.mToken,
8473be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
84837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.width, wallpaper.height);
8494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (RemoteException e) {
8508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
85137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!wallpaper.wallpaperUpdating) {
85237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bindWallpaperComponentLocked(null, false, false, wallpaper);
85321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
8544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
8554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
85637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
85737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void notifyCallbacksLocked(WallpaperData wallpaper) {
85837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final int n = wallpaper.callbacks.beginBroadcast();
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
86137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The RemoteCallbackList will take care of removing
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the dead object for us.
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
86837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.callbacks.finishBroadcast();
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendBroadcast(intent);
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPermission(String permission) {
8749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", must have permission " + permission);
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
88037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private static JournaledFile makeJournaledFile(int userId) {
881135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
8829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return new JournaledFile(new File(base), new File(base + ".tmp"));
8839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
8849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
88537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void saveSettingsLocked(WallpaperData wallpaper) {
88637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        JournaledFile journal = makeJournaledFile(wallpaper.userId);
8879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileOutputStream stream = null;
8889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
8899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileOutputStream(journal.chooseForWrite(), false);
8909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlSerializer out = new FastXmlSerializer();
8919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.setOutput(stream, "utf-8");
8929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startDocument(null, true);
8939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
8949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startTag(null, "wp");
89537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "width", Integer.toString(wallpaper.width));
89637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "height", Integer.toString(wallpaper.height));
89737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "name", wallpaper.name);
89837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.wallpaperComponent != null
89937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    && !wallpaper.wallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
9004c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                out.attribute(null, "component",
90137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperComponent.flattenToShortString());
9024c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
9039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endTag(null, "wp");
9049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
9059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endDocument();
9069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream.close();
9079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.commit();
9089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
9099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
9109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (stream != null) {
9119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    stream.close();
9129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
9139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (IOException ex) {
9149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                // Ignore
9159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
9169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.rollback();
9179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
9189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
9199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
92037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void migrateFromOld() {
92137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
92237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
92337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (oldWallpaper.exists()) {
92437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
92537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            oldWallpaper.renameTo(newWallpaper);
92637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
92737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (oldInfo.exists()) {
92837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
92937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            oldInfo.renameTo(newInfo);
93037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
93137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
93237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
93337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void loadSettingsLocked(int userId) {
9348a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
935a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron
93637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        JournaledFile journal = makeJournaledFile(userId);
9379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileInputStream stream = null;
9389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        File file = journal.chooseForRead();
93937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (!file.exists()) {
94037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // This should only happen one time, when upgrading from a legacy system
94137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            migrateFromOld();
94237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
94337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
94437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
94537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper = new WallpaperData(userId);
94637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperMap.put(userId, wallpaper);
94737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
9489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
9499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
9509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileInputStream(file);
9519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlPullParser parser = Xml.newPullParser();
9529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            parser.setInput(stream, null);
9539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
9549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int type;
9559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            do {
9569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = parser.next();
9579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (type == XmlPullParser.START_TAG) {
9589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    String tag = parser.getName();
9599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if ("wp".equals(tag)) {
96037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
96137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.height = Integer.parseInt(parser
96237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                .getAttributeValue(null, "height"));
96337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.name = parser.getAttributeValue(null, "name");
9644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        String comp = parser.getAttributeValue(null, "component");
96537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.nextWallpaperComponent = comp != null
9664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                ? ComponentName.unflattenFromString(comp)
9674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                : null;
96837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (wallpaper.nextWallpaperComponent == null
96937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                || "android".equals(wallpaper.nextWallpaperComponent
97037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                        .getPackageName())) {
97137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper.nextWallpaperComponent = wallpaper.imageWallpaperComponent;
9729ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        }
973a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron
974a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                        if (DEBUG) {
97537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mWidth:" + wallpaper.width);
97637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mHeight:" + wallpaper.height);
97737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mName:" + wallpaper.name);
97837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mNextWallpaperComponent:"
97937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                    + wallpaper.nextWallpaperComponent);
980a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                        }
9819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
9829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
9839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } while (type != XmlPullParser.END_DOCUMENT);
9849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            success = true;
9859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NullPointerException e) {
9868a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NumberFormatException e) {
9888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (XmlPullParserException e) {
9908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
9928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IndexOutOfBoundsException e) {
9948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
9969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
9979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (stream != null) {
9989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                stream.close();
9999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
10019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // Ignore
10029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
10039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
100537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.width = -1;
100637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.height = -1;
100737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = "";
10089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
100944bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn
101044bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        // We always want to have some reasonable width hint.
101144bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
101244bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        Display d = wm.getDefaultDisplay();
101344bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        int baseSize = d.getMaximumSizeDimension();
101437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.width < baseSize) {
101537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.width = baseSize;
101644bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        }
101737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.height < baseSize) {
101837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.height = baseSize;
101944bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        }
10209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
10219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
1022194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick    // Called by SystemBackupAgent after files are restored to disk.
10239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    void settingsRestored() {
102437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        // TODO: If necessary, make it work for secondary users as well. This currently assumes
102537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        // restores only to the primary user
10268a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "settingsRestored");
102737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = null;
10289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
10299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
103037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            loadSettingsLocked(0);
103137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper = mWallpaperMap.get(0);
103237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.nextWallpaperComponent != null
103337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    && !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
103437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
103537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper)) {
1036e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // No such live wallpaper or other failure; fall back to the default
1037e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // live wallpaper (since the profile being restored indicated that the
1038e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // user had selected a live rather than static one).
103937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    bindWallpaperComponentLocked(null, false, false, wallpaper);
1040e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                }
10419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = true;
10429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } else {
1043a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                // If there's a wallpaper name, we use that.  If that can't be loaded, then we
1044a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                // use the default.
104537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if ("".equals(wallpaper.name)) {
10468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
1047a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                    success = true;
1048a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                } else {
10498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
105037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    success = restoreNamedResourceLocked(wallpaper);
1051a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                }
10528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
1053a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (success) {
105437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
105537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper);
1056a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                }
10579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
10599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
106137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
106237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = "";
106337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            getWallpaperDir(0).delete();
10649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
1065194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick
1066194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick        synchronized (mLock) {
106737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            saveSettingsLocked(wallpaper);
1068194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick        }
10699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
10709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
107137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
107237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
107337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            String resName = wallpaper.name.substring(4);
10749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String pkg = null;
10769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int colon = resName.indexOf(':');
10779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0) {
10789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                pkg = resName.substring(0, colon);
10799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String ident = null;
10829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int slash = resName.lastIndexOf('/');
10839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (slash > 0) {
10849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                ident = resName.substring(slash+1);
10859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String type = null;
10889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0 && slash > 0 && (slash-colon) > 1) {
10899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = resName.substring(colon+1, slash);
10909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (pkg != null && ident != null && type != null) {
10939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                int resId = -1;
10949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                InputStream res = null;
10959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                FileOutputStream fos = null;
10969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                try {
10979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
10989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Resources r = c.getResources();
10999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    resId = r.getIdentifier(resName, null, null);
11009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (resId == 0) {
11018a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
11029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                                + " ident=" + ident);
11039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        return false;
11049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    res = r.openRawResource(resId);
110737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperFile.exists()) {
110837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperFile.delete();
11091afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn                    }
111037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    fos = new FileOutputStream(wallpaper.wallpaperFile);
11119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    byte[] buffer = new byte[32768];
11139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    int amt;
11149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    while ((amt=res.read(buffer)) > 0) {
11159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        fos.write(buffer, 0, amt);
11169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    // mWallpaperObserver will notice the close and send the change broadcast
11189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11198a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "Restored wallpaper: " + resName);
11209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return true;
11219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (NameNotFoundException e) {
11228a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "Package name " + pkg + " not found");
11239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (Resources.NotFoundException e) {
11248a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "Resource not found: " + resId);
11259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (IOException e) {
11268a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "IOException while restoring wallpaper ", e);
11279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } finally {
11289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (res != null) {
11299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
11309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            res.close();
11319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
11329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (fos != null) {
11348bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn                        FileUtils.sync(fos);
11359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
11369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            fos.close();
11379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
11389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
11409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
11419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
11429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return false;
11439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
114437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
1145eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    @Override
1146eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1147eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1148eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
1149eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
1150eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Permission Denial: can't dump wallpaper service from from pid="
1151eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + Binder.getCallingPid()
1152eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + ", uid=" + Binder.getCallingUid());
1153eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return;
1154eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
1155eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
1156eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
1157eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Current Wallpaper Service state:");
115837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            for (int i = 0; i < mWallpaperMap.size(); i++) {
115937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                WallpaperData wallpaper = mWallpaperMap.valueAt(i);
116037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(" User " + wallpaper.userId + ":");
116137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mWidth=");
116237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print(wallpaper.width);
116337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print(" mHeight=");
116437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.height);
116537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mName=");
116637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.name);
116737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mWallpaperComponent=");
116837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.wallpaperComponent);
116937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.connection != null) {
117037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperConnection conn = wallpaper.connection;
117137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("  Wallpaper connection ");
117237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print(conn);
117337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(":");
117437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (conn.mInfo != null) {
117537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        pw.print("    mInfo.component=");
117637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        pw.println(conn.mInfo.getComponent());
117737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
117837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mToken=");
117937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mToken);
118037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mService=");
118137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mService);
118237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mEngine=");
118337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mEngine);
118437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mLastDiedTime=");
118537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
118637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                }
1187eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
1188eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
1189eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1191