WallpaperManagerService.java revision f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8
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;
484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.ServiceManager;
490cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackbornimport android.os.SystemClock;
50f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle;
514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperConnection;
524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperEngine;
534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperService;
544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService;
558a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
5637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport android.util.SparseArray;
579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.util.Xml;
5844bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackbornimport android.view.Display;
594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.IWindowManager;
604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.WindowManager;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.FileDescriptor;
639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException;
649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.InputStream;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException;
679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileInputStream;
689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileOutputStream;
69eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackbornimport java.io.PrintWriter;
704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.List;
719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParser;
739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParserException;
749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlSerializer;
759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
7621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor;
772269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.util.FastXmlSerializer;
781afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornimport com.android.internal.util.JournaledFile;
7937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasaniimport com.android.server.am.ActivityManagerService;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
818cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornclass WallpaperManagerService extends IWallpaperManager.Stub {
824c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    static final String TAG = "WallpaperService";
83cbf15048240ecf460957ac3de98a7efbccbbb754Dianne Hackborn    static final boolean DEBUG = false;
849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
85407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy    final Object mLock = new Object[0];
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
870cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    /**
880cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * Minimum time between crashes of a wallpaper service for us to consider
890cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     * restarting it vs. just reverting to the static wallpaper.
900cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn     */
910cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final long MIN_WALLPAPER_CRASH_TIME = 10000;
920cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn
9337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static final File WALLPAPER_BASE_DIR = new File("/data/system/users");
940cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn    static final String WALLPAPER = "wallpaper";
9537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static final String WALLPAPER_INFO = "wallpaper_info.xml";
969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that the wallpaper has changed. The CREATE is triggered when there is no
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * everytime the wallpaper is changed.
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private class WallpaperObserver extends FileObserver {
10437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
10537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final WallpaperData mWallpaper;
10637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final File mWallpaperDir;
10737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final File mWallpaperFile;
10837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
10937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public WallpaperObserver(WallpaperData wallpaper) {
11037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
11137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    CLOSE_WRITE | DELETE | DELETE_SELF);
11237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperDir = getWallpaperDir(wallpaper.userId);
11337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaper = wallpaper;
11437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
11537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
11637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
11737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        @Override
11837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public void onEvent(int event, String path) {
11937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (path == null) {
12037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                return;
12137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
12237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            synchronized (mLock) {
12337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                // changing the wallpaper means we'll need to back up the new one
12437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                long origId = Binder.clearCallingIdentity();
12537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                BackupManager bm = new BackupManager(mContext);
12637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bm.dataChanged();
12737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                Binder.restoreCallingIdentity(origId);
12837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
12937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                File changedFile = new File(mWallpaperDir, path);
13037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaperFile.equals(changedFile)) {
13137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    notifyCallbacksLocked(mWallpaper);
13237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
13337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            || mWallpaper.imageWallpaperPending) {
13437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (event == CLOSE_WRITE) {
13537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            mWallpaper.imageWallpaperPending = false;
1369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        }
13737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        bindWallpaperComponentLocked(mWallpaper.imageWallpaperComponent, true,
13837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                false, mWallpaper);
13937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        saveSettingsLocked(mWallpaper);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
14337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
14437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
14537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
1464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final Context mContext;
1474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    final IWindowManager mIWindowManager;
14821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    final MyPackageMonitor mMonitor;
14937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    WallpaperData mLastWallpaper;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
15207213e6d8895af10951851435adf96a779863f6cDianne Hackborn
15337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    int mCurrentUserId;
15437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
15537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    static class WallpaperData {
15637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
15737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int userId;
15837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
15937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File wallpaperFile;
16037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
16137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
16237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Client is currently writing a new image wallpaper.
16337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
16437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        boolean imageWallpaperPending;
16537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
16637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
16737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Resource name if using a picture from the wallpaper gallery
16837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
16937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        String name = "";
17037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
17137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
17237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * The component name of the currently set live wallpaper.
17337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
17437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName wallpaperComponent;
17537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
17637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
17737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * The component name of the wallpaper that should be set next.
17837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
17937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName nextWallpaperComponent;
18037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
18137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
18237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * Name of the component used to display bitmap wallpapers from either the gallery or
18337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * built-in wallpapers.
18437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
18537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        ComponentName imageWallpaperComponent = new ComponentName("com.android.systemui",
18637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                "com.android.systemui.ImageWallpaper");
18737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
18837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperConnection connection;
18937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        long lastDiedTime;
19037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        boolean wallpaperUpdating;
19137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperObserver wallpaperObserver;
19237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
19337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        /**
19437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         * List of callbacks registered they should each be notified when the wallpaper is changed.
19537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani         */
19637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        private RemoteCallbackList<IWallpaperManagerCallback> callbacks
19737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                = new RemoteCallbackList<IWallpaperManagerCallback>();
19837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
19937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int width = -1;
20037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        int height = -1;
20137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
20237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData(int userId) {
20337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            this.userId = userId;
20437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
20537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
20637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
20707213e6d8895af10951851435adf96a779863f6cDianne Hackborn
2084c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    class WallpaperConnection extends IWallpaperConnection.Stub
2094c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            implements ServiceConnection {
210eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        final WallpaperInfo mInfo;
2114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        final Binder mToken = new Binder();
2124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperService mService;
2134c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        IWallpaperEngine mEngine;
21437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData mWallpaper;
2154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
21637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
217eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            mInfo = info;
21837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaper = wallpaper;
219eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
220eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
2214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceConnected(ComponentName name, IBinder service) {
2224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
22337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
22437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
2254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    mService = IWallpaperService.Stub.asInterface(service);
22637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    attachServiceLocked(this, mWallpaper);
227eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // XXX should probably do saveSettingsLocked() later
228eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // when we have an engine, but I'm not sure about
229eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // locking there and anyway we always need to be able to
230eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    // recover if there is something wrong.
23137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    saveSettingsLocked(mWallpaper);
2324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
2334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2344c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void onServiceDisconnected(ComponentName name) {
2374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
2384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mService = null;
2394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                mEngine = null;
24037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
24137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
24237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (!mWallpaper.wallpaperUpdating
24337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
24437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                > SystemClock.uptimeMillis()
24537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && mWallpaper.userId == mCurrentUserId) {
2468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        Slog.w(TAG, "Reverting to built-in wallpaper!");
24737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperLocked(true, mWallpaper.userId);
2480cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                    }
2490cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
2504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
25237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
2534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public void attachEngine(IWallpaperEngine engine) {
2544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            mEngine = engine;
2554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
25637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
2574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        public ParcelFileDescriptor setWallpaper(String name) {
2584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            synchronized (mLock) {
25937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mWallpaper.connection == this) {
26037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    return updateWallpaperBitmapLocked(name, mWallpaper);
2614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
2624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                return null;
2634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
2644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
2654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
26637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
26721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    class MyPackageMonitor extends PackageMonitor {
26821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
26921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onPackageUpdateFinished(String packageName, int uid) {
27021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mLock) {
27137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
27237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
27337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent != null
27437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
27537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperUpdating = false;
27637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        ComponentName comp = wallpaper.wallpaperComponent;
27737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperComponentLocked(wallpaper);
27837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        // Do this only for the current user's wallpaper
27937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (wallpaper.userId == mCurrentUserId
28037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                && !bindWallpaperComponentLocked(comp, false, false, wallpaper)) {
28137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.w(TAG, "Wallpaper no longer available; reverting to default");
28237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            clearWallpaperLocked(false, wallpaper.userId);
28337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        }
28480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    }
28580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
28680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
28780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        }
28880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn
28980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        @Override
29080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        public void onPackageModified(String packageName) {
29180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            synchronized (mLock) {
29237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
29337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
29437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent == null
29537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
29637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        continue;
29737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
298d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    doPackagesChangedLocked(true, wallpaper);
29921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
30021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
30121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
30221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
30321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
30421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onPackageUpdateStarted(String packageName, int uid) {
30521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mLock) {
30637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                for (int i = 0; i < mWallpaperMap.size(); i++) {
30737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
30837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperComponent != null
30937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
31037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperUpdating = true;
31137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
31221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
31321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
31421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
31521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
31621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
31721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
318d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            synchronized (mLock) {
319d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                boolean changed = false;
320d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                for (int i = 0; i < mWallpaperMap.size(); i++) {
321d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
322d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    boolean res = doPackagesChangedLocked(doit, wallpaper);
323d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    changed |= res;
324d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
325d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                return changed;
32637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
32721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
32821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
32921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
33021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onSomePackagesChanged() {
331d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            synchronized (mLock) {
332d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                for (int i = 0; i < mWallpaperMap.size(); i++) {
333d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    WallpaperData wallpaper = mWallpaperMap.valueAt(i);
334d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    doPackagesChangedLocked(true, wallpaper);
335d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
33637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
33721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
33837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
339d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn        boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
34021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            boolean changed = false;
341d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.wallpaperComponent != null) {
342d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                int change = isPackageDisappearing(wallpaper.wallpaperComponent
343d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        .getPackageName());
344d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                if (change == PACKAGE_PERMANENT_CHANGE
345d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        || change == PACKAGE_TEMPORARY_CHANGE) {
346d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    changed = true;
347d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    if (doit) {
348d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        Slog.w(TAG, "Wallpaper uninstalled, removing: "
34937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                + wallpaper.wallpaperComponent);
35037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        clearWallpaperLocked(false, wallpaper.userId);
35121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
35221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
353d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
354d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.nextWallpaperComponent != null) {
355d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
356d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        .getPackageName());
357d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                if (change == PACKAGE_PERMANENT_CHANGE
358d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                        || change == PACKAGE_TEMPORARY_CHANGE) {
359d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    wallpaper.nextWallpaperComponent = null;
360d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
361d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
362d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.wallpaperComponent != null
363d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
364d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                try {
365d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    mContext.getPackageManager().getServiceInfo(
366d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            wallpaper.wallpaperComponent, 0);
367d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                } catch (NameNotFoundException e) {
368d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    Slog.w(TAG, "Wallpaper component gone, removing: "
369d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            + wallpaper.wallpaperComponent);
370d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    clearWallpaperLocked(false, wallpaper.userId);
371d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                }
372d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            }
373d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn            if (wallpaper.nextWallpaperComponent != null
374d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
375d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                try {
376d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    mContext.getPackageManager().getServiceInfo(
377d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                            wallpaper.nextWallpaperComponent, 0);
378d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                } catch (NameNotFoundException e) {
379d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn                    wallpaper.nextWallpaperComponent = null;
38021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
38121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
38221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return changed;
38321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
38421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
38521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
3868cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn    public WallpaperManagerService(Context context) {
3878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "WallpaperService startup");
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
3894c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        mIWindowManager = IWindowManager.Stub.asInterface(
3904c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                ServiceManager.getService(Context.WINDOW_SERVICE));
39121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        mMonitor = new MyPackageMonitor();
392d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn        mMonitor.register(context, null, true);
39337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WALLPAPER_BASE_DIR.mkdirs();
39437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        loadSettingsLocked(0);
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private static File getWallpaperDir(int userId) {
39837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        return new File(WALLPAPER_BASE_DIR + "/" + userId);
39937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
40037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void finalize() throws Throwable {
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.finalize();
40437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        for (int i = 0; i < mWallpaperMap.size(); i++) {
40537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.valueAt(i);
40637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.wallpaperObserver.stopWatching();
40737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
409135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
410f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    public void systemReady() {
4118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "systemReady");
41237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(0);
41337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        switchWallpaper(wallpaper);
41437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
41537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperObserver.startWatching();
41637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
417135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        IntentFilter userFilter = new IntentFilter();
418135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        userFilter.addAction(Intent.ACTION_USER_SWITCHED);
419135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        userFilter.addAction(Intent.ACTION_USER_REMOVED);
420135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        mContext.registerReceiver(new BroadcastReceiver() {
42137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            @Override
422135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            public void onReceive(Context context, Intent intent) {
423135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                String action = intent.getAction();
424135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                if (Intent.ACTION_USER_SWITCHED.equals(action)) {
425135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                    switchUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
426135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
427135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                    removeUser(intent.getIntExtra(Intent.EXTRA_USERID, 0));
428135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                }
42937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
430135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        }, userFilter);
43137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
43237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
43337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    String getName() {
43437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        return mWallpaperMap.get(0).name;
43537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
43637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
437135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    void removeUser(int userId) {
438135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        synchronized (mLock) {
439135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
440135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            if (wallpaper != null) {
441135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                wallpaper.wallpaperObserver.stopWatching();
442135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani                mWallpaperMap.remove(userId);
443135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            }
444135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
445135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            wallpaperFile.delete();
446135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
447135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani            wallpaperInfoFile.delete();
448135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        }
449135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani    }
450135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani
45137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void switchUser(int userId) {
45237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        synchronized (mLock) {
45337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mCurrentUserId = userId;
45437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
45537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper == null) {
45637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper = new WallpaperData(userId);
45737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                mWallpaperMap.put(userId, wallpaper);
45837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                loadSettingsLocked(userId);
45937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
46037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.wallpaperObserver.startWatching();
46137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
46237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            switchWallpaper(wallpaper);
46337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
46437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
46537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
46637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void switchWallpaper(WallpaperData wallpaper) {
467f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        synchronized (mLock) {
46880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            RuntimeException e = null;
469f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
47037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                ComponentName cname = wallpaper.wallpaperComponent != null ?
47137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
47237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (bindWallpaperComponentLocked(cname, true, false, wallpaper)) {
47380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return;
474f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                }
47580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            } catch (RuntimeException e1) {
47680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                e = e1;
477f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
47880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            Slog.w(TAG, "Failure starting previous wallpaper", e);
47937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            clearWallpaperLocked(false, wallpaper.userId);
480f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
481f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
48237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearWallpaper() {
4848a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "clearWallpaper");
4859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
486f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            clearWallpaperLocked(false, UserHandle.getCallingUserId());
48721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
48821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
48921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
49037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void clearWallpaperLocked(boolean defaultFailed, int userId) {
49137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
49237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File f = new File(getWallpaperDir(userId), WALLPAPER);
49321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (f.exists()) {
49421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            f.delete();
49521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
49621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        final long ident = Binder.clearCallingIdentity();
49780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        RuntimeException e = null;
49821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        try {
49937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.imageWallpaperPending = false;
50037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (userId != mCurrentUserId) return;
50180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            if (bindWallpaperComponentLocked(defaultFailed
50237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    ? wallpaper.imageWallpaperComponent
50337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    : null, true, false, wallpaper)) {
50480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return;
50580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
50680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        } catch (IllegalArgumentException e1) {
50780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            e = e1;
50821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        } finally {
50921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            Binder.restoreCallingIdentity(ident);
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
51180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn
51280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // This can happen if the default wallpaper component doesn't
51380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // exist.  This should be a system configuration problem, but
51480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // let's not let it crash the system and just live with no
51580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        // wallpaper.
51680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        Slog.e(TAG, "Default wallpaper component not found!", e);
51737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        clearWallpaperComponentLocked(wallpaper);
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setDimensionHints(int width, int height) throws RemoteException {
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
523f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        int userId = UserHandle.getCallingUserId();
52437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
52537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
52637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
52737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (width <= 0 || height <= 0) {
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("width and height must be > 0");
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
53337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (width != wallpaper.width || height != wallpaper.height) {
53437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.width = width;
53537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.height = height;
53637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                saveSettingsLocked(wallpaper);
53737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (mCurrentUserId != userId) return; // Don't change the properties now
53837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.connection != null) {
53937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.connection.mEngine != null) {
540284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        try {
54137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper.connection.mEngine.setDesiredSize(
542284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                                    width, height);
543284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        } catch (RemoteException e) {
544284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                        }
54537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        notifyCallbacksLocked(wallpaper);
546284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                    }
547284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
5489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWidthHint() throws RemoteException {
5539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
554f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
55537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            return wallpaper.width;
5569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getHeightHint() throws RemoteException {
5609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
561f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn            WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
56237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            return wallpaper.height;
5639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
566284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
567284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn            Bundle outParams) {
5689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
56937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // This returns the current user's wallpaper, if called by a system service. Else it
57037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // returns the wallpaper for the calling user.
57137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int callingUid = Binder.getCallingUid();
57237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int wallpaperUserId = 0;
57337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (callingUid == android.os.Process.SYSTEM_UID) {
57437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaperUserId = mCurrentUserId;
57537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            } else {
576f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn                wallpaperUserId = UserHandle.getUserId(callingUid);
57737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
57837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
5799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
580284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                if (outParams != null) {
58137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    outParams.putInt("width", wallpaper.width);
58237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    outParams.putInt("height", wallpaper.height);
583284ac93aa30642fda87d5c40263a1263677c21cdDianne Hackborn                }
58437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.callbacks.register(cb);
58537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
5869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (!f.exists()) {
5879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return null;
5889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
5899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
5909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (FileNotFoundException e) {
5919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                /* Shouldn't happen as we check to see if the file exists */
5928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Error getting wallpaper", e);
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return null;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
598eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    public WallpaperInfo getWallpaperInfo() {
599f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        int userId = UserHandle.getCallingUserId();
600eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
60137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperData wallpaper = mWallpaperMap.get(userId);
60237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection != null) {
60337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                return wallpaper.connection.mInfo;
604eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
605eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return null;
606eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
607eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
60837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
6099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public ParcelFileDescriptor setWallpaper(String name) {
6108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "setWallpaper");
611f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        int userId = UserHandle.getCallingUserId();
61237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
61337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
61437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
61537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        checkPermission(android.Manifest.permission.SET_WALLPAPER);
6179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
6180cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            final long ident = Binder.clearCallingIdentity();
6190cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            try {
62037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
6210cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                if (pfd != null) {
62237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.imageWallpaperPending = true;
6230cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                }
6240cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                return pfd;
6250cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn            } finally {
6260cd48879dca53a9f4d449126d406527bc4b94bafDianne Hackborn                Binder.restoreCallingIdentity(ident);
6274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
6284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
6294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
6304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
63137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
6324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        if (name == null) name = "";
6334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
63437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File dir = getWallpaperDir(wallpaper.userId);
63537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!dir.exists()) {
63637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                dir.mkdir();
637ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                FileUtils.setPermissions(
63837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        dir.getPath(),
639ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
640ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn                        -1, -1);
641ebac48c6adf738cb27ea59669c9eca4467063d18Dianne Hackborn            }
64237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            ParcelFileDescriptor fd = ParcelFileDescriptor.open(new File(dir, WALLPAPER),
6434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    MODE_CREATE|MODE_READ_WRITE);
64437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = name;
6454c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            return fd;
6464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (FileNotFoundException e) {
6478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "Error setting wallpaper", e);
6484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
6494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        return null;
6504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
6514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn
6524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    public void setWallpaperComponent(ComponentName name) {
6538a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
654f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn        int userId = UserHandle.getCallingUserId();
65537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
65637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
65737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
65837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
6594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
6604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        synchronized (mLock) {
6614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
6629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
66337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.imageWallpaperPending = false;
66437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bindWallpaperComponentLocked(name, false, true, wallpaper);
665f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } finally {
666f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                Binder.restoreCallingIdentity(ident);
667f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
668f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
669f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn    }
670f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
67137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
67237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            boolean fromUser, WallpaperData wallpaper) {
6738a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
674f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        // Has the component changed?
6759ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn        if (!force) {
67637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection != null) {
67737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.wallpaperComponent == null) {
6789ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    if (componentName == null) {
6799ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
6809ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        // Still using default wallpaper.
68180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        return true;
6829ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    }
68337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                } else if (wallpaper.wallpaperComponent.equals(componentName)) {
6849ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    // Changing to same wallpaper.
6859ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                    if (DEBUG) Slog.v(TAG, "same wallpaper");
68680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return true;
6874c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
688f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
689f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        }
690f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
691f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        try {
692a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            if (componentName == null) {
693322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                String defaultComponent =
694322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    mContext.getString(com.android.internal.R.string.default_wallpaper_component);
695a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (defaultComponent != null) {
696322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // See if there is a default wallpaper component specified
697a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                    componentName = ComponentName.unflattenFromString(defaultComponent);
6988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
699322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
700a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (componentName == null) {
701322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    // Fall back to static image wallpaper
70237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    componentName = wallpaper.imageWallpaperComponent;
703322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //clearWallpaperComponentLocked();
704322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                    //return;
7058a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Using image wallpaper");
706322b6ee7e158b0b979d8156df8fd59f4a9b95ab9Mike Cleron                }
707f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
708a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
709f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                    PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
710f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
71180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                String msg = "Selected service does not require "
712f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn                        + android.Manifest.permission.BIND_WALLPAPER
71380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        + ": " + componentName;
71480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                if (fromUser) {
71580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    throw new SecurityException(msg);
71680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
71780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                Slog.w(TAG, msg);
71880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return false;
719f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
720f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
721eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            WallpaperInfo wi = null;
722eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
723f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
72437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (componentName != null && !componentName.equals(wallpaper.imageWallpaperComponent)) {
7254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                // Make sure the selected service is actually a wallpaper service.
7264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                List<ResolveInfo> ris = mContext.getPackageManager()
727eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        .queryIntentServices(intent, PackageManager.GET_META_DATA);
7284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                for (int i=0; i<ris.size(); i++) {
7294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    ServiceInfo rsi = ris.get(i).serviceInfo;
7304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    if (rsi.name.equals(si.name) &&
7314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                            rsi.packageName.equals(si.packageName)) {
732eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        try {
733eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            wi = new WallpaperInfo(mContext, ris.get(i));
734eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (XmlPullParserException e) {
73580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            if (fromUser) {
73680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                                throw new IllegalArgumentException(e);
73780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            }
73880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            Slog.w(TAG, e);
73980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            return false;
740eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        } catch (IOException e) {
74180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            if (fromUser) {
74280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                                throw new IllegalArgumentException(e);
74380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            }
74480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            Slog.w(TAG, e);
74580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            return false;
746eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                        }
7474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        break;
7484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                    }
7494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
750eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                if (wi == null) {
75180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    String msg = "Selected service is not a wallpaper: "
75280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                            + componentName;
75380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    if (fromUser) {
75480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        throw new SecurityException(msg);
75580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    }
75680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    Slog.w(TAG, msg);
75780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    return false;
7584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
7599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
760f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn
761f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            // Bind the service!
7628a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
76337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
764a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron            intent.setComponent(componentName);
76537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            int serviceUserId = wallpaper.userId;
76637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // Because the image wallpaper is running in the system ui
76737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (componentName.equals(wallpaper.imageWallpaperComponent)) {
76837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                serviceUserId = 0;
76937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
770dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
771dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                    com.android.internal.R.string.wallpaper_binding_label);
772dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
773eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    mContext, 0,
774eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
775eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
776eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                            0));
77737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
77880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                String msg = "Unable to bind service: "
77980b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                        + componentName;
78080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                if (fromUser) {
78180b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                    throw new IllegalArgumentException(msg);
78280b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                }
78380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                Slog.w(TAG, msg);
78480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                return false;
785f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
78637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
78737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                detachWallpaperLocked(mLastWallpaper);
78837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            }
78937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.wallpaperComponent = componentName;
79037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection = newConn;
79137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.lastDiedTime = SystemClock.uptimeMillis();
792f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            try {
79337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.userId == mCurrentUserId) {
79437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (DEBUG)
79537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        Slog.v(TAG, "Adding window token: " + newConn.mToken);
79637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mIWindowManager.addWindowToken(newConn.mToken,
79737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            WindowManager.LayoutParams.TYPE_WALLPAPER);
79837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    mLastWallpaper = wallpaper;
79937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                }
800f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            } catch (RemoteException e) {
801f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn            }
802f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
80380b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            String msg = "Unknown component " + componentName;
80480b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            if (fromUser) {
80580b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn                throw new IllegalArgumentException(msg);
80680b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            }
80780b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            Slog.w(TAG, msg);
80880b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn            return false;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
81080b902ffbe2fd5b5d3719b6fc2a8f629374968ddDianne Hackborn        return true;
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
81237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
81337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void detachWallpaperLocked(WallpaperData wallpaper) {
81437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.connection != null) {
81537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.connection.mEngine != null) {
8164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                try {
81737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.connection.mEngine.destroy();
8184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                } catch (RemoteException e) {
8194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                }
8204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
82137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mContext.unbindService(wallpaper.connection);
822e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            try {
82337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (DEBUG)
82437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
82537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
826e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            } catch (RemoteException e) {
827e9e9bca842473f2e9d343d4248be98f8731a79d1Dianne Hackborn            }
82837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection.mService = null;
82937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection.mEngine = null;
83037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.connection = null;
8314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
8324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
83337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
83437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void clearWallpaperComponentLocked(WallpaperData wallpaper) {
83537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.wallpaperComponent = null;
83637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        detachWallpaperLocked(wallpaper);
83737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
83837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
83937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
8404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        try {
8413be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn            conn.mService.attach(conn, conn.mToken,
8423be63c09309b21c01b535271625d4c39045690e5Dianne Hackborn                    WindowManager.LayoutParams.TYPE_WALLPAPER, false,
84337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    wallpaper.width, wallpaper.height);
8444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        } catch (RemoteException e) {
8458a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
84637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (!wallpaper.wallpaperUpdating) {
84737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                bindWallpaperComponentLocked(null, false, false, wallpaper);
84821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
8494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn        }
8504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn    }
85137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
85237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void notifyCallbacksLocked(WallpaperData wallpaper) {
85337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        final int n = wallpaper.callbacks.beginBroadcast();
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < n; i++) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
85637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // The RemoteCallbackList will take care of removing
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the dead object for us.
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
86337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        wallpaper.callbacks.finishBroadcast();
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.sendBroadcast(intent);
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void checkPermission(String permission) {
8699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", must have permission " + permission);
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
87537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private static JournaledFile makeJournaledFile(int userId) {
876135936072b24b090fb63940aea41b408d855a4f3Amith Yamasani        final String base = getWallpaperDir(userId) + "/" + WALLPAPER_INFO;
8779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return new JournaledFile(new File(base), new File(base + ".tmp"));
8789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
8799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
88037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void saveSettingsLocked(WallpaperData wallpaper) {
88137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        JournaledFile journal = makeJournaledFile(wallpaper.userId);
8829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileOutputStream stream = null;
8839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
8849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileOutputStream(journal.chooseForWrite(), false);
8859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlSerializer out = new FastXmlSerializer();
8869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.setOutput(stream, "utf-8");
8879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startDocument(null, true);
8889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
8899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.startTag(null, "wp");
89037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "width", Integer.toString(wallpaper.width));
89137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "height", Integer.toString(wallpaper.height));
89237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            out.attribute(null, "name", wallpaper.name);
89337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.wallpaperComponent != null
89437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    && !wallpaper.wallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
8954c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                out.attribute(null, "component",
89637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperComponent.flattenToShortString());
8974c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn            }
8989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endTag(null, "wp");
8999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
9009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            out.endDocument();
9019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream.close();
9029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.commit();
9039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
9049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
9059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (stream != null) {
9069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    stream.close();
9079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
9089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (IOException ex) {
9099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                // Ignore
9109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
9119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            journal.rollback();
9129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
9139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
9149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
91537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void migrateFromOld() {
91637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
91737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
91837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (oldWallpaper.exists()) {
91937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
92037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            oldWallpaper.renameTo(newWallpaper);
92137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
92237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (oldInfo.exists()) {
92337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
92437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            oldInfo.renameTo(newInfo);
92537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
92637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    }
92737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
92837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    private void loadSettingsLocked(int userId) {
9298a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
930a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron
93137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        JournaledFile journal = makeJournaledFile(userId);
9329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        FileInputStream stream = null;
9339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        File file = journal.chooseForRead();
93437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (!file.exists()) {
93537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            // This should only happen one time, when upgrading from a legacy system
93637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            migrateFromOld();
93737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
93837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = mWallpaperMap.get(userId);
93937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper == null) {
94037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper = new WallpaperData(userId);
94137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            mWallpaperMap.put(userId, wallpaper);
94237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        }
9439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
9449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
9459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            stream = new FileInputStream(file);
9469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            XmlPullParser parser = Xml.newPullParser();
9479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            parser.setInput(stream, null);
9489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
9499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int type;
9509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            do {
9519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = parser.next();
9529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                if (type == XmlPullParser.START_TAG) {
9539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    String tag = parser.getName();
9549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if ("wp".equals(tag)) {
95537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
95637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.height = Integer.parseInt(parser
95737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                .getAttributeValue(null, "height"));
95837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.name = parser.getAttributeValue(null, "name");
9594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                        String comp = parser.getAttributeValue(null, "component");
96037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.nextWallpaperComponent = comp != null
9614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                ? ComponentName.unflattenFromString(comp)
9624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn                                : null;
96337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        if (wallpaper.nextWallpaperComponent == null
96437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                || "android".equals(wallpaper.nextWallpaperComponent
96537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                        .getPackageName())) {
96637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper.nextWallpaperComponent = wallpaper.imageWallpaperComponent;
9679ea31639738e8d2c90dc3a4fcd535d09a0b7209aDianne Hackborn                        }
968a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron
969a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                        if (DEBUG) {
97037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mWidth:" + wallpaper.width);
97137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mHeight:" + wallpaper.height);
97237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mName:" + wallpaper.name);
97337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            Slog.v(TAG, "mNextWallpaperComponent:"
97437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                                    + wallpaper.nextWallpaperComponent);
975a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                        }
9769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
9779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
9789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } while (type != XmlPullParser.END_DOCUMENT);
9799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            success = true;
9809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NullPointerException e) {
9818a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (NumberFormatException e) {
9838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (XmlPullParserException e) {
9858a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
9878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IndexOutOfBoundsException e) {
9898a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "failed parsing " + file + " " + e);
9909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
9919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        try {
9929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (stream != null) {
9939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                stream.close();
9949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
9959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } catch (IOException e) {
9969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // Ignore
9979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
9989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
9999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
100037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.width = -1;
100137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.height = -1;
100237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = "";
10039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
100444bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn
100544bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        // We always want to have some reasonable width hint.
100644bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
100744bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        Display d = wm.getDefaultDisplay();
100844bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        int baseSize = d.getMaximumSizeDimension();
100937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.width < baseSize) {
101037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.width = baseSize;
101144bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        }
101237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.height < baseSize) {
101337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.height = baseSize;
101444bc17c6b517aef35a390c81b5aa79c4f284f744Dianne Hackborn        }
10159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
10169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
1017194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick    // Called by SystemBackupAgent after files are restored to disk.
10189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    void settingsRestored() {
101937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        // TODO: If necessary, make it work for secondary users as well. This currently assumes
102037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        // restores only to the primary user
10218a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "settingsRestored");
102237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        WallpaperData wallpaper = null;
10239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        boolean success = false;
10249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        synchronized (mLock) {
102537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            loadSettingsLocked(0);
102637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper = mWallpaperMap.get(0);
102737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            if (wallpaper.nextWallpaperComponent != null
102837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    && !wallpaper.nextWallpaperComponent.equals(wallpaper.imageWallpaperComponent)) {
102937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
103037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper)) {
1031e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // No such live wallpaper or other failure; fall back to the default
1032e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // live wallpaper (since the profile being restored indicated that the
1033e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                    // user had selected a live rather than static one).
103437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    bindWallpaperComponentLocked(null, false, false, wallpaper);
1035e3ab4d0f181e875c534653dd9491d956cb3bbcd9Christopher Tate                }
10369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                success = true;
10379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } else {
1038a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                // If there's a wallpaper name, we use that.  If that can't be loaded, then we
1039a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                // use the default.
104037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if ("".equals(wallpaper.name)) {
10418a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
1042a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                    success = true;
1043a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                } else {
10448a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
104537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    success = restoreNamedResourceLocked(wallpaper);
1046a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                }
10478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
1048a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                if (success) {
104937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
105037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                            wallpaper);
1051a428b2c260dddd267b541909517cc4f6cf769714Mike Cleron                }
10529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
10549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!success) {
105637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
105737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            wallpaper.name = "";
105837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            getWallpaperDir(0).delete();
10599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
1060194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick
1061194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick        synchronized (mLock) {
106237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            saveSettingsLocked(wallpaper);
1063194b19a4b3ff877d2720ed35e607e329fcfa8186Brad Fitzpatrick        }
10649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
10659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
106637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani    boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
106737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani        if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
106837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            String resName = wallpaper.name.substring(4);
10699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String pkg = null;
10719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int colon = resName.indexOf(':');
10729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0) {
10739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                pkg = resName.substring(0, colon);
10749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String ident = null;
10779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            int slash = resName.lastIndexOf('/');
10789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (slash > 0) {
10799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                ident = resName.substring(slash+1);
10809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            String type = null;
10839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (colon > 0 && slash > 0 && (slash-colon) > 1) {
10849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                type = resName.substring(colon+1, slash);
10859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
10869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
10879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (pkg != null && ident != null && type != null) {
10889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                int resId = -1;
10899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                InputStream res = null;
10909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                FileOutputStream fos = null;
10919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                try {
10929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
10939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    Resources r = c.getResources();
10949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    resId = r.getIdentifier(resName, null, null);
10959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (resId == 0) {
10968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
10979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                                + " ident=" + ident);
10989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        return false;
10999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    res = r.openRawResource(resId);
110237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (wallpaper.wallpaperFile.exists()) {
110337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        wallpaper.wallpaperFile.delete();
11041afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackborn                    }
110537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    fos = new FileOutputStream(wallpaper.wallpaperFile);
11069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    byte[] buffer = new byte[32768];
11089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    int amt;
11099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    while ((amt=res.read(buffer)) > 0) {
11109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        fos.write(buffer, 0, amt);
11119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    // mWallpaperObserver will notice the close and send the change broadcast
11139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
11148a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.v(TAG, "Restored wallpaper: " + resName);
11159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    return true;
11169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (NameNotFoundException e) {
11178a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "Package name " + pkg + " not found");
11189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (Resources.NotFoundException e) {
11198a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "Resource not found: " + resId);
11209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } catch (IOException e) {
11218a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.e(TAG, "IOException while restoring wallpaper ", e);
11229bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                } finally {
11239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (res != null) {
11249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
11259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            res.close();
11269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
11279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    if (fos != null) {
11298bdf5935c0db4a66ab33a10b43398d2523cfa15dDianne Hackborn                        FileUtils.sync(fos);
11309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        try {
11319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                            fos.close();
11329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                        } catch (IOException ex) {}
11339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                    }
11349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                }
11359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
11369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
11379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return false;
11389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
113937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani
1140eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    @Override
1141eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1142eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
1143eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
1144eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
1145eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Permission Denial: can't dump wallpaper service from from pid="
1146eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + Binder.getCallingPid()
1147eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn                    + ", uid=" + Binder.getCallingUid());
1148eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            return;
1149eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
1150eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn
1151eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        synchronized (mLock) {
1152eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            pw.println("Current Wallpaper Service state:");
115337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani            for (int i = 0; i < mWallpaperMap.size(); i++) {
115437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                WallpaperData wallpaper = mWallpaperMap.valueAt(i);
115537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(" User " + wallpaper.userId + ":");
115637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mWidth=");
115737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print(wallpaper.width);
115837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print(" mHeight=");
115937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.height);
116037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mName=");
116137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.name);
116237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.print("  mWallpaperComponent=");
116337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                pw.println(wallpaper.wallpaperComponent);
116437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                if (wallpaper.connection != null) {
116537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    WallpaperConnection conn = wallpaper.connection;
116637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("  Wallpaper connection ");
116737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print(conn);
116837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(":");
116937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    if (conn.mInfo != null) {
117037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        pw.print("    mInfo.component=");
117137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                        pw.println(conn.mInfo.getComponent());
117237ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    }
117337ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mToken=");
117437ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mToken);
117537ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mService=");
117637ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mService);
117737ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mEngine=");
117837ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(conn.mEngine);
117937ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.print("    mLastDiedTime=");
118037ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                    pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
118137ce3a8af6faab675319d0803b288ab1dddc76beAmith Yamasani                }
1182eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn            }
1183eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn        }
1184eb034652c2037a47ebfd99779e8383bb8bb528afDianne Hackborn    }
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1186