WallpaperManagerService.java revision f21adf6fc19bc9c6908c6f1aaae203389f104bfa
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; 24111bd4acdb378266221b430a284f88a3990a3958Christopher Tateimport android.backup.BackupManager; 254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ComponentName; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.ServiceConnection; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ResolveInfo; 314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.content.pm.ServiceInfo; 329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.pm.PackageManager.NameNotFoundException; 339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.content.res.Resources; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.IBinder; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.FileObserver; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteCallbackList; 404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.os.ServiceManager; 414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperConnection; 424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperEngine; 434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.IWallpaperService; 444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.service.wallpaper.WallpaperService; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport android.util.Xml; 474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.IWindowManager; 484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport android.view.WindowManager; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException; 519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.InputStream; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileInputStream; 559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.FileOutputStream; 564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackbornimport java.util.List; 579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParser; 599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlPullParserException; 609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport org.xmlpull.v1.XmlSerializer; 619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 62f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackbornimport com.android.internal.service.wallpaper.ImageWallpaper; 639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport com.android.internal.util.FastXmlSerializer; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 658cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackbornclass WallpaperManagerService extends IWallpaperManager.Stub { 664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn static final String TAG = "WallpaperService"; 674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn static final boolean DEBUG = true; 689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn Object mLock = new Object(); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final File WALLPAPER_DIR = new File( 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "/data/data/com.android.settings/files"); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String WALLPAPER = "wallpaper"; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * List of callbacks registered they should each be notified 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the wallpaper is changed. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 808cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks 818cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn = new RemoteCallbackList<IWallpaperManagerCallback>(); 829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that the wallpaper has changed. The CREATE is triggered when there is no 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * everytime the wallpaper is changed. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final FileObserver mWallpaperObserver = new FileObserver( 909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onEvent(int event, String path) { 93e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato if (path == null) { 94e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato return; 95e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato } 969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // changing the wallpaper means we'll need to back up the new one 989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato long origId = Binder.clearCallingIdentity(); 999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato BackupManager bm = new BackupManager(mContext); 1009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato bm.dataChanged(); 1019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Binder.restoreCallingIdentity(origId); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato File changedFile = new File(WALLPAPER_DIR, path); 1049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (WALLPAPER_FILE.equals(changedFile)) { 1059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato notifyCallbacksLocked(); 1069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1114c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn final Context mContext; 1124c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn final IWindowManager mIWindowManager; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1144c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn int mWidth = -1; 1154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn int mHeight = -1; 1164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn String mName = ""; 1174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ComponentName mWallpaperComponent; 1184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn WallpaperConnection mWallpaperConnection; 1194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn class WallpaperConnection extends IWallpaperConnection.Stub 1214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn implements ServiceConnection { 1224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn final Binder mToken = new Binder(); 1234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn IWallpaperService mService; 1244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn IWallpaperEngine mEngine; 1254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void onServiceConnected(ComponentName name, IBinder service) { 1274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn synchronized (mLock) { 1284c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (mWallpaperConnection == this) { 1294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mService = IWallpaperService.Stub.asInterface(service); 1304c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn attachServiceLocked(this); 1314c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1324c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1334c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1354c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void onServiceDisconnected(ComponentName name) { 1364c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn synchronized (mLock) { 1374c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mService = null; 1384c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mEngine = null; 1394c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1404c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1424c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void attachEngine(IWallpaperEngine engine) { 1434c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mEngine = engine; 1444c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1454c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1464c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public ParcelFileDescriptor setWallpaper(String name) { 1474c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn synchronized (mLock) { 1484c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (mWallpaperConnection == this) { 1494c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name); 1504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (pfd != null) { 1514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn saveSettingsLocked(); 1524c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn return pfd; 1544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn return null; 1564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 1594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 1608cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn public WallpaperManagerService(Context context) { 1614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (DEBUG) Log.d(TAG, "WallpaperService startup"); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mIWindowManager = IWindowManager.Stub.asInterface( 1644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ServiceManager.getService(Context.WINDOW_SERVICE)); 165e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato WALLPAPER_DIR.mkdirs(); 1669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato loadSettingsLocked(); 167e712ee3fe1b9ec950dbe5d77993751c2b7b1011cJoe Onorato mWallpaperObserver.startWatching(); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWallpaperObserver.stopWatching(); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 176f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn public void systemReady() { 177f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn synchronized (mLock) { 178f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn try { 179f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(mWallpaperComponent); 180f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } catch (RuntimeException e) { 181f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn Log.w(TAG, "Failure starting previous wallpaper", e); 182f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn try { 183f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(null); 184f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } catch (RuntimeException e2) { 185f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn Log.w(TAG, "Failure starting default wallpaper", e2); 186f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn clearWallpaperComponentLocked(); 187f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 188f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 189f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 190f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 191f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearWallpaper() { 1939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 1949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato File f = WALLPAPER_FILE; 1959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (f.exists()) { 1969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato f.delete(); 1979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 198f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(null); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setDimensionHints(int width, int height) throws RemoteException { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (width <= 0 || height <= 0) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("width and height must be > 0"); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 2109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (width != mWidth || height != mHeight) { 2119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mWidth = width; 2129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mHeight = height; 2139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato saveSettingsLocked(); 2149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getWidthHint() throws RemoteException { 2199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 2209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return mWidth; 2219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeightHint() throws RemoteException { 2259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 2269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return mHeight; 2279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2308cc6a5026aeb5cf9cc36529426fe0cc66714f5fbDianne Hackborn public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb) { 2319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 2329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 2339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mCallbacks.register(cb); 2349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato File f = WALLPAPER_FILE; 2359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (!f.exists()) { 2369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return null; 2379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 2389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return ParcelFileDescriptor.open(f, MODE_READ_ONLY); 2399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (FileNotFoundException e) { 2409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato /* Shouldn't happen as we check to see if the file exists */ 2414c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn Log.w(TAG, "Error getting wallpaper", e); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return null; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato public ParcelFileDescriptor setWallpaper(String name) { 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermission(android.Manifest.permission.SET_WALLPAPER); 2499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 2504c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name); 2514c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (pfd != null) { 252f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(null); 2534c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn saveSettingsLocked(); 2544c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn return pfd; 2564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 2594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ParcelFileDescriptor updateWallpaperBitmapLocked(String name) { 2604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (name == null) name = ""; 2614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn try { 2624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE, 2634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn MODE_CREATE|MODE_READ_WRITE); 2649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mName = name; 2654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn return fd; 2664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } catch (FileNotFoundException e) { 2674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn Log.w(TAG, "Error setting wallpaper", e); 2684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn return null; 2704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 2714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 2724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn public void setWallpaperComponent(ComponentName name) { 2734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT); 2744c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn synchronized (mLock) { 2754c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 2769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 277f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(name); 278f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } finally { 279f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn Binder.restoreCallingIdentity(ident); 280f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 281f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 282f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 283f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 284f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn void bindWallpaperComponentLocked(ComponentName name) { 285f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn // Has the component changed? 286f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (mWallpaperConnection != null) { 287f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (mWallpaperComponent == null) { 288f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (name == null) { 289f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn // Still using default wallpaper. 290f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn return; 2914c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 292f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } else if (mWallpaperComponent.equals(name)) { 293f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn // Changing to same wallpaper. 294f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn return; 295f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 296f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 297f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 298f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn try { 299f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn ComponentName realName = name; 300f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (realName == null) { 301f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn // The default component is our static image wallpaper. 302f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn realName = new ComponentName("android", 303f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn ImageWallpaper.class.getName()); 304f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 305f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn ServiceInfo si = mContext.getPackageManager().getServiceInfo(realName, 306f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS); 307f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) { 308f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn throw new SecurityException("Selected service does not require " 309f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn + android.Manifest.permission.BIND_WALLPAPER 310f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn + ": " + realName); 311f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 312f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 313f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); 314f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (name != null) { 3154c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn // Make sure the selected service is actually a wallpaper service. 3164c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn List<ResolveInfo> ris = mContext.getPackageManager() 3174c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn .queryIntentServices(intent, 0); 3184c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn for (int i=0; i<ris.size(); i++) { 3194c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ServiceInfo rsi = ris.get(i).serviceInfo; 3204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (rsi.name.equals(si.name) && 3214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn rsi.packageName.equals(si.packageName)) { 3224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ris = null; 3234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn break; 3244c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3254c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3264c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (ris != null) { 3274c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn throw new SecurityException("Selected service is not a wallpaper: " 328f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn + realName); 3294c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 331f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 332f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn // Bind the service! 333f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn WallpaperConnection newConn = new WallpaperConnection(); 334f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn intent.setComponent(realName); 335f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (!mContext.bindService(intent, newConn, 336f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn Context.BIND_AUTO_CREATE)) { 337f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn throw new IllegalArgumentException("Unable to bind service: " 338f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn + name); 339f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 340f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 341f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn clearWallpaperComponentLocked(); 342f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn mWallpaperComponent = name; 343f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn mWallpaperConnection = newConn; 344f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn try { 345f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn if (DEBUG) Log.v(TAG, "Adding window token: " + newConn.mToken); 346f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn mIWindowManager.addWindowToken(newConn.mToken, 347f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn WindowManager.LayoutParams.TYPE_WALLPAPER); 348f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } catch (RemoteException e) { 349f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } 350f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn 351f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn } catch (PackageManager.NameNotFoundException e) { 352f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn throw new IllegalArgumentException("Unknown component " + name); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3554c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 3564c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn void clearWallpaperComponentLocked() { 3574c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mWallpaperComponent = null; 3584c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (mWallpaperConnection != null) { 3594c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (mWallpaperConnection.mEngine != null) { 3604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn try { 3614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mWallpaperConnection.mEngine.destroy(); 3624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } catch (RemoteException e) { 3634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3644c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3654c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mContext.unbindService(mWallpaperConnection); 3664c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mWallpaperConnection = null; 3674c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3684c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3694c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 3704c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn void attachServiceLocked(WallpaperConnection conn) { 3714c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn try { 3724c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn conn.mService.attach(conn, conn.mToken, mWidth, mHeight); 3734c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } catch (RemoteException e) { 3744c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn Log.w(TAG, "Failed attaching wallpaper; clearing", e); 375f21adf6fc19bc9c6908c6f1aaae203389f104bfaDianne Hackborn bindWallpaperComponentLocked(null); 3764c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3774c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 3784c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn 3799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato private void notifyCallbacksLocked() { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int n = mCallbacks.beginBroadcast(); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < n; i++) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCallbacks.getBroadcastItem(i).onWallpaperChanged(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The RemoteCallbackList will take care of removing 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the dead object for us. 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCallbacks.finishBroadcast(); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkPermission(String permission) { 3969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Access denied to process: " + Binder.getCallingPid() 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", must have permission " + permission); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato private static JournaledFile makeJournaledFile() { 4039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato final String base = "/data/system/wallpaper_info.xml"; 4049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return new JournaledFile(new File(base), new File(base + ".tmp")); 4059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato private void saveSettingsLocked() { 4089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato JournaledFile journal = makeJournaledFile(); 4099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato FileOutputStream stream = null; 4109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 4119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato stream = new FileOutputStream(journal.chooseForWrite(), false); 4129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato XmlSerializer out = new FastXmlSerializer(); 4139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.setOutput(stream, "utf-8"); 4149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.startDocument(null, true); 4159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.startTag(null, "wp"); 4179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.attribute(null, "width", Integer.toString(mWidth)); 4189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.attribute(null, "height", Integer.toString(mHeight)); 4199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.attribute(null, "name", mName); 4204c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn if (mWallpaperComponent != null) { 4214c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn out.attribute(null, "component", 4224c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mWallpaperComponent.flattenToShortString()); 4234c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn } 4249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.endTag(null, "wp"); 4259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato out.endDocument(); 4279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato stream.close(); 4289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato journal.commit(); 4299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException e) { 4309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 4319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (stream != null) { 4329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato stream.close(); 4339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException ex) { 4359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // Ignore 4369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato journal.rollback(); 4389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato private void loadSettingsLocked() { 4429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato JournaledFile journal = makeJournaledFile(); 4439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato FileInputStream stream = null; 4449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato File file = journal.chooseForRead(); 4459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato boolean success = false; 4469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 4479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato stream = new FileInputStream(file); 4489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato XmlPullParser parser = Xml.newPullParser(); 4499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato parser.setInput(stream, null); 4509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato int type; 4529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato do { 4539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato type = parser.next(); 4549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (type == XmlPullParser.START_TAG) { 4559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato String tag = parser.getName(); 4569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if ("wp".equals(tag)) { 4579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mWidth = Integer.parseInt(parser.getAttributeValue(null, "width")); 4589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mHeight = Integer.parseInt(parser.getAttributeValue(null, "height")); 4599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mName = parser.getAttributeValue(null, "name"); 4604c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn String comp = parser.getAttributeValue(null, "component"); 4614c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn mWallpaperComponent = comp != null 4624c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn ? ComponentName.unflattenFromString(comp) 4634c62fc0e1e5ea9c69a12a7d1cf8b3ec8b2d114a3Dianne Hackborn : null; 4649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } while (type != XmlPullParser.END_DOCUMENT); 4679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato success = true; 4689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (NullPointerException e) { 4692d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato Log.w(TAG, "failed parsing " + file + " " + e); 4709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (NumberFormatException e) { 4712d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato Log.w(TAG, "failed parsing " + file + " " + e); 4729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (XmlPullParserException e) { 4732d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato Log.w(TAG, "failed parsing " + file + " " + e); 4749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException e) { 4752d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato Log.w(TAG, "failed parsing " + file + " " + e); 4769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IndexOutOfBoundsException e) { 4772d9c9e3f6780b70fc98cfa0102824308e8ed28e9Joe Onorato Log.w(TAG, "failed parsing " + file + " " + e); 4789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 4809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (stream != null) { 4819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato stream.close(); 4829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException e) { 4849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // Ignore 4859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (!success) { 4889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mWidth = -1; 4899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mHeight = -1; 4909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mName = ""; 4919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 4939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 4949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato void settingsRestored() { 4959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato boolean success = false; 4969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato synchronized (mLock) { 4979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato loadSettingsLocked(); 4989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // If there's a wallpaper name, we use that. If that can't be loaded, then we 4999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // use the default. 5009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if ("".equals(mName)) { 5019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato success = true; 5029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } else { 5039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato success = restoreNamedResourceLocked(); 5049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (!success) { 5089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.e(TAG, "Failed to restore wallpaper: '" + mName + "'"); 5099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato mName = ""; 5109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato WALLPAPER_FILE.delete(); 5119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato saveSettingsLocked(); 5139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato boolean restoreNamedResourceLocked() { 5169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) { 5179bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato String resName = mName.substring(4); 5189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato String pkg = null; 5209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato int colon = resName.indexOf(':'); 5219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (colon > 0) { 5229bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato pkg = resName.substring(0, colon); 5239bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5249bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5259bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato String ident = null; 5269bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato int slash = resName.lastIndexOf('/'); 5279bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (slash > 0) { 5289bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato ident = resName.substring(slash+1); 5299bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5309bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato String type = null; 5329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (colon > 0 && slash > 0 && (slash-colon) > 1) { 5339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato type = resName.substring(colon+1, slash); 5349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (pkg != null && ident != null && type != null) { 5379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato int resId = -1; 5389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato InputStream res = null; 5399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato FileOutputStream fos = null; 5409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 5419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED); 5429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Resources r = c.getResources(); 5439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato resId = r.getIdentifier(resName, null, null); 5449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (resId == 0) { 5459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type 5469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato + " ident=" + ident); 5479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return false; 5489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato res = r.openRawResource(resId); 5519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato fos = new FileOutputStream(WALLPAPER_FILE); 5529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato byte[] buffer = new byte[32768]; 5549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato int amt; 5559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato while ((amt=res.read(buffer)) > 0) { 5569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato fos.write(buffer, 0, amt); 5579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato // mWallpaperObserver will notice the close and send the change broadcast 5599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato 5609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.d(TAG, "Restored wallpaper: " + resName); 5619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return true; 5629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (NameNotFoundException e) { 5639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.e(TAG, "Package name " + pkg + " not found"); 5649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (Resources.NotFoundException e) { 5659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.e(TAG, "Resource not found: " + resId); 5669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException e) { 5679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato Log.e(TAG, "IOException while restoring wallpaper ", e); 5689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } finally { 5699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (res != null) { 5709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 5719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato res.close(); 5729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException ex) {} 5739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato if (fos != null) { 5759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato try { 5769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato fos.close(); 5779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } catch (IOException ex) {} 5789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato return false; 5839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 585