ContextImpl.java revision 31fd85f39b554e09b2e6c1c2ccf5c186859880fa
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpackage android.app; 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport com.android.internal.policy.PolicyManager; 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport com.android.internal.util.XmlUtils; 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport com.google.android.collect.Maps; 22ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.BroadcastReceiver; 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.ComponentName; 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.ContentResolver; 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.Context; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.ContextWrapper; 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.IContentProvider; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.Intent; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.IntentFilter; 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.IIntentReceiver; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.IntentSender; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.ReceiverCallNotAllowedException; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.ServiceConnection; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.SharedPreferences; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.ActivityInfo; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.ApplicationInfo; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.ComponentInfo; 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.FeatureInfo; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.IPackageDataObserver; 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.IPackageDeleteObserver; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.IPackageInstallObserver; 45b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savilleimport android.content.pm.IPackageMoveObserver; 46b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Savilleimport android.content.pm.IPackageManager; 472a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.IPackageStatsObserver; 482a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.InstrumentationInfo; 492a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.PackageInfo; 502a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.PackageManager; 512a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.PermissionGroupInfo; 522a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.PermissionInfo; 532a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.ProviderInfo; 542a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.content.pm.ResolveInfo; 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.ServiceInfo; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.pm.PackageParser.Package; 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.res.AssetManager; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.res.Resources; 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.content.res.XmlResourceParser; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.database.sqlite.SQLiteDatabase; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.database.sqlite.SQLiteDatabase.CursorFactory; 622a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.graphics.Bitmap; 632a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetlandimport android.graphics.drawable.Drawable; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.hardware.SensorManager; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.location.ILocationManager; 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.location.LocationManager; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.media.AudioManager; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.ConnectivityManager; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.IConnectivityManager; 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.ThrottleManager; 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.IThrottleManager; 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.Uri; 73ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuangimport android.net.wifi.IWifiManager; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.net.wifi.WifiManager; 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Binder; 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Bundle; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.DropBoxManager; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Environment; 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.FileUtils; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Handler; 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.IBinder; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.IPowerManager; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Looper; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.PowerManager; 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Process; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.RemoteException; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.ServiceManager; 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.StatFs; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.Vibrator; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.FileUtils.FileStatus; 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.os.storage.StorageManager; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.provider.Settings; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.telephony.TelephonyManager; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.text.ClipboardManager; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.util.AndroidRuntimeException; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.util.Log; 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.view.ContextThemeWrapper; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.view.LayoutInflater; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.view.WindowManagerImpl; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.view.accessibility.AccessibilityManager; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.accounts.AccountManager; 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport android.accounts.IAccountManager; 104ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuangimport android.app.admin.DevicePolicyManager; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport com.android.internal.os.IDropBoxManagerService; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.io.File; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.io.FileInputStream; 110ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuangimport java.io.FileNotFoundException; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.io.FileOutputStream; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.io.IOException; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.io.InputStream; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.lang.ref.WeakReference; 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.ArrayList; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.HashMap; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.HashSet; 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.Iterator; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.List; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.Map; 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.Map.Entry; 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.Set; 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.WeakHashMap; 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.concurrent.CountDownLatch; 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectimport java.util.concurrent.ExecutorService; 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclass ReceiverRestrictedContext extends ContextWrapper { 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ReceiverRestrictedContext(Context base) { 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project super(base); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return registerReceiver(receiver, filter, null, null); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String broadcastPermission, Handler scheduler) { 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new ReceiverCallNotAllowedException( 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "IntentReceiver components are not allowed to register to receive intents"); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //ex.fillInStackTrace(); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //Log.e("IntentReceiver", ex.getMessage(), ex); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //return mContext.registerReceiver(receiver, filter, broadcastPermission, 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // scheduler); 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public boolean bindService(Intent service, ServiceConnection conn, int flags) { 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new ReceiverCallNotAllowedException( 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "IntentReceiver components are not allowed to bind to services"); 15209070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood //ex.fillInStackTrace(); 153f614d64d4b4dfcd20c77ac3ccf2d9c9090a49303The Android Open Source Project //Log.e("IntentReceiver", ex.getMessage(), ex); 154e25ff1c682ae5cc87af5e76de7e31a2702b620f3Robert CH Chou //return mContext.bindService(service, interfaceName, conn, flags); 155509f7399b8f246f506307b22039e63323ec09622Dima Zavin } 156509f7399b8f246f506307b22039e63323ec09622Dima Zavin} 15709070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood 15837e9e904360d6a8757c958dacaab1343eacb7fa8Erik Gilling/** 159af82f21df7b87af2b378a46c8f338ebdd9c66175Xavier Ducrohet * Common implementation of Context API, which provides the base 16009070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood * context object for Activity and other application components. 16109070d9e8685645f4ca8ecca62ae489472aed646Mike Lockwood */ 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectclass ContextImpl extends Context { 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private final static String TAG = "ApplicationContext"; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private final static boolean DEBUG = false; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private final static boolean DEBUG_ICONS = false; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static final Object sSync = new Object(); 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static AlarmManager sAlarmManager; 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static PowerManager sPowerManager; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static ConnectivityManager sConnectivityManager; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static ThrottleManager sThrottleManager; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static WifiManager sWifiManager; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static LocationManager sLocationManager; 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs = 175b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes new HashMap<String, SharedPreferencesImpl>(); 176b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes 177b4add9b74525210478bac702d27fdaf9cf7ab18fElliott Hughes private AudioManager mAudioManager; 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /*package*/ LoadedApk mPackageInfo; 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private Resources mResources; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /*package*/ ActivityThread mMainThread; 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private Context mOuterContext; 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private IBinder mActivityToken = null; 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private ApplicationContentResolver mContentResolver; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private int mThemeResource = 0; 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private Resources.Theme mTheme = null; 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private PackageManager mPackageManager; 187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private NotificationManager mNotificationManager = null; 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private ActivityManager mActivityManager = null; 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private WallpaperManager mWallpaperManager = null; 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private Context mReceiverRestrictedContext = null; 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private SearchManager mSearchManager = null; 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private SensorManager mSensorManager = null; 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private StorageManager mStorageManager = null; 194ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang private Vibrator mVibrator = null; 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private LayoutInflater mLayoutInflater = null; 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private StatusBarManager mStatusBarManager = null; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private TelephonyManager mTelephonyManager = null; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private ClipboardManager mClipboardManager = null; 199ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang private boolean mRestricted; 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private AccountManager mAccountManager; // protected by mSync 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private DropBoxManager mDropBoxManager = null; 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private DevicePolicyManager mDevicePolicyManager = null; 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private UiModeManager mUiModeManager = null; 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private DownloadManager mDownloadManager = null; 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private final Object mSync = new Object(); 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mDatabasesDir; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mPreferencesDir; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mFilesDir; 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mCacheDir; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mExternalFilesDir; 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File mExternalCacheDir; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static long sInstanceCount = 0; 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static final String[] EMPTY_FILE_LIST = {}; 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // For debug only 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project protected void finalize() throws Throwable { 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project super.finalize(); 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project --sInstanceCount; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 22824ce4bc8d7c4706286ef0530870dea80a1a0cd11Bruce Beare public static long getInstanceCount() { 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sInstanceCount; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 231ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public AssetManager getAssets() { 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mResources.getAssets(); 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Resources getResources() { 23995ec983887867a117f4ef87073495111aff4a506Dima Zavin return mResources; 240931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin } 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public PackageManager getPackageManager() { 244931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin if (mPackageManager != null) { 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageManager; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project IPackageManager pm = ActivityThread.getPackageManager(); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (pm != null) { 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Doesn't matter if we make more than one instance. 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (mPackageManager = new ApplicationPackageManager(this, pm)); 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public ContentResolver getContentResolver() { 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mContentResolver; 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 262ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang @Override 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Looper getMainLooper() { 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mMainThread.getLooper(); 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 266ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Context getApplicationContext() { 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (mPackageInfo != null) ? 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mPackageInfo.getApplication() : mMainThread.getApplication(); 271ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void setTheme(int resid) { 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mThemeResource = resid; 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Resources.Theme getTheme() { 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mTheme == null) { 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mThemeResource == 0) { 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mThemeResource = com.android.internal.R.style.Theme; 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mTheme = mResources.newTheme(); 285931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin mTheme.applyStyle(mThemeResource, true); 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mTheme; 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public ClassLoader getClassLoader() { 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageInfo != null ? 293ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public String getPackageName() { 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPackageInfo != null) { 299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageInfo.getPackageName(); 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new RuntimeException("Not supported in system context"); 302ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public ApplicationInfo getApplicationInfo() { 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPackageInfo != null) { 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageInfo.getApplicationInfo(); 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new RuntimeException("Not supported in system context"); 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public String getPackageResourcePath() { 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPackageInfo != null) { 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageInfo.getResDir(); 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new RuntimeException("Not supported in system context"); 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public String getPackageCodePath() { 322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPackageInfo != null) { 323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPackageInfo.getAppDir(); 324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new RuntimeException("Not supported in system context"); 326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private static File makeBackupFile(File prefsFile) { 329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return new File(prefsFile.getPath() + ".bak"); 330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getSharedPrefsFile(String name) { 333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return makeFilename(getPreferencesDir(), name + ".xml"); 334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public SharedPreferences getSharedPreferences(String name, int mode) { 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedPreferencesImpl sp; 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File prefsFile; 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project boolean needInitialLoad = false; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (sSharedPrefs) { 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sp = sSharedPrefs.get(name); 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sp != null && !sp.hasFileChangedUnexpectedly()) { 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sp; 345b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project prefsFile = getSharedPrefsFile(name); 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sp == null) { 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sp = new SharedPreferencesImpl(prefsFile, mode, null); 349ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang sSharedPrefs.put(name, sp); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project needInitialLoad = true; 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (sp) { 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (needInitialLoad && sp.isLoaded()) { 356b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville // lost the race to load; another thread handled it 357b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville return sp; 358b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 359b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville File backup = makeBackupFile(prefsFile); 360b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville if (backup.exists()) { 361b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville prefsFile.delete(); 362b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville backup.renameTo(prefsFile); 363b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Debugging 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prefsFile.exists() && !prefsFile.canRead()) { 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission"); 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Map map = null; 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (prefsFile.exists() && prefsFile.canRead()) { 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileInputStream str = new FileInputStream(prefsFile); 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project map = XmlUtils.readMapXml(str); 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project str.close(); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (org.xmlpull.v1.XmlPullParserException e) { 377ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang Log.w(TAG, "getSharedPreferences", e); 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (FileNotFoundException e) { 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "getSharedPreferences", e); 380ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } catch (IOException e) { 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "getSharedPreferences", e); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sp.replace(map); 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sp; 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File getPreferencesDir() { 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (mSync) { 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPreferencesDir == null) { 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mPreferencesDir; 395b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville } 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public FileInputStream openFileInput(String name) 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throws FileNotFoundException { 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File f = makeFilename(getFilesDir(), name); 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return new FileInputStream(f); 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public FileOutputStream openFileOutput(String name, int mode) 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throws FileNotFoundException { 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project final boolean append = (mode&MODE_APPEND) != 0; 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File f = makeFilename(getFilesDir(), name); 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileOutputStream fos = new FileOutputStream(f, append); 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setFilePermissionsFromMode(f.getPath(), mode, 0); 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fos; 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (FileNotFoundException e) { 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File parent = f.getParentFile(); 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project parent.mkdir(); 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileUtils.setPermissions( 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project parent.getPath(), 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project -1, -1); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileOutputStream fos = new FileOutputStream(f, append); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setFilePermissionsFromMode(f.getPath(), mode, 0); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return fos; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public boolean deleteFile(String name) { 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File f = makeFilename(getFilesDir(), name); 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return f.delete(); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getFilesDir() { 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (mSync) { 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mFilesDir == null) { 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mFilesDir = new File(getDataDirFile(), "files"); 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mFilesDir.exists()) { 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!mFilesDir.mkdirs()) { 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Unable to create files directory"); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileUtils.setPermissions( 446b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville mFilesDir.getPath(), 447b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project -1, -1); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mFilesDir; 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getExternalFilesDir(String type) { 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (mSync) { 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mExternalFilesDir == null) { 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory( 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getPackageName()); 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mExternalFilesDir.exists()) { 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (new File(Environment.getExternalStorageAndroidDataDir(), 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ".nomedia")).createNewFile(); 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (IOException e) { 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mExternalFilesDir.mkdirs()) { 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Unable to create external files directory"); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (type == null) { 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mExternalFilesDir; 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File dir = new File(mExternalFilesDir, type); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!dir.exists()) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!dir.mkdirs()) { 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Unable to create external media directory " + dir); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return dir; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getCacheDir() { 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (mSync) { 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mCacheDir == null) { 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mCacheDir = new File(getDataDirFile(), "cache"); 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mCacheDir.exists()) { 493ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang if(!mCacheDir.mkdirs()) { 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Unable to create cache directory"); 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 497ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang FileUtils.setPermissions( 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mCacheDir.getPath(), 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project -1, -1); 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mCacheDir; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getExternalCacheDir() { 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project synchronized (mSync) { 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mExternalCacheDir == null) { 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory( 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getPackageName()); 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mExternalCacheDir.exists()) { 514b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville try { 515b98762f7824c291dc5d9a9b757af434ef31d8c81Wink Saville (new File(Environment.getExternalStorageAndroidDataDir(), 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ".nomedia")).createNewFile(); 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (IOException e) { 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!mExternalCacheDir.mkdirs()) { 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Log.w(TAG, "Unable to create external cache directory"); 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return null; 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mExternalCacheDir; 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getFileStreamPath(String name) { 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return makeFilename(getFilesDir(), name); 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public String[] fileList() { 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project final String[] list = getFilesDir().list(); 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (list != null) ? list : EMPTY_FILE_LIST; 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 539ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang @Override 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project File f = validateFilePath(name, true); 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory); 5432d13d1408bef9e26cc418e6fc2579dfd12378a3cJP Abgrall setFilePermissionsFromMode(f.getPath(), mode, 0); 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return db; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public boolean deleteDatabase(String name) { 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 550ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang File f = validateFilePath(name, false); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return f.delete(); 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (Exception e) { 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return false; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public File getDatabasePath(String name) { 559ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang return validateFilePath(name, false); 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public String[] databaseList() { 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project final String[] list = getDatabasesDir().list(); 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return (list != null) ? list : EMPTY_FILE_LIST; 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project private File getDatabasesDir() { 570931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin synchronized (mSync) { 571eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom if (mDatabasesDir == null) { 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mDatabasesDir = new File(getDataDirFile(), "databases"); 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mDatabasesDir.getPath().equals("databases")) { 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mDatabasesDir = new File("/data/system"); 576eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom } 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return mDatabasesDir; 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public Drawable getWallpaper() { 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return getWallpaperManager().getDrawable(); 584ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } 585ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 586ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang @Override 587ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang public Drawable peekWallpaper() { 588ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang return getWallpaperManager().peekDrawable(); 589ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang } 59031dbed7b60d8237d6d05dc6bf230167a5854b77aElliott Hughes 59131dbed7b60d8237d6d05dc6bf230167a5854b77aElliott Hughes @Override 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public int getWallpaperDesiredMinimumWidth() { 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return getWallpaperManager().getDesiredMinimumWidth(); 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5962a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland @Override 5972a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland public int getWallpaperDesiredMinimumHeight() { 5982a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland return getWallpaperManager().getDesiredMinimumHeight(); 5992a63bb7abf1b27a7a2e8fd5951d77f71a2f290d4Brian Swetland } 600931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin 601931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin @Override 602931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin public void setWallpaper(Bitmap bitmap) throws IOException { 603931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin getWallpaperManager().setBitmap(bitmap); 604931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin } 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void setWallpaper(InputStream data) throws IOException { 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getWallpaperManager().setStream(data); 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void clearWallpaper() throws IOException { 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getWallpaperManager().clear(); 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void startActivity(Intent intent) { 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new AndroidRuntimeException( 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "Calling startActivity() from outside of an Activity " 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project + " context requires the FLAG_ACTIVITY_NEW_TASK flag." 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project + " Is this really what you want?"); 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getInstrumentation().execStartActivity( 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1); 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void startIntentSender(IntentSender intent, 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throws IntentSender.SendIntentException { 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = null; 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fillInIntent != null) { 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int result = ActivityManagerNative.getDefault() 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project .startActivityIntentSender(mMainThread.getApplicationThread(), intent, 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fillInIntent, resolvedType, null, null, 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 0, flagsMask, flagsValues); 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (result == IActivityManager.START_CANCELED) { 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project throw new IntentSender.SendIntentException(); 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Instrumentation.checkStartActivityResult(result, null); 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendBroadcast(Intent intent) { 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ActivityManagerNative.getDefault().broadcastIntent( 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getApplicationThread(), intent, resolvedType, null, 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Activity.RESULT_OK, null, null, null, false, false); 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendBroadcast(Intent intent, String receiverPermission) { 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 664931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin ActivityManagerNative.getDefault().broadcastIntent( 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getApplicationThread(), intent, resolvedType, null, 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Activity.RESULT_OK, null, null, receiverPermission, false, false); 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendOrderedBroadcast(Intent intent, 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String receiverPermission) { 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ActivityManagerNative.getDefault().broadcastIntent( 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getApplicationThread(), intent, resolvedType, null, 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Activity.RESULT_OK, null, null, receiverPermission, true, false); 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendOrderedBroadcast(Intent intent, 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String receiverPermission, BroadcastReceiver resultReceiver, 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Handler scheduler, int initialCode, String initialData, 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Bundle initialExtras) { 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project IIntentReceiver rd = null; 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (resultReceiver != null) { 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (mPackageInfo != null) { 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (scheduler == null) { 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scheduler = mMainThread.getHandler(); 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 694931175a1c5f01f57781c9fcf64beade6ed5148ffDima Zavin rd = mPackageInfo.getReceiverDispatcher( 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project resultReceiver, getOuterContext(), scheduler, 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getInstrumentation(), false); 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (scheduler == null) { 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project scheduler = mMainThread.getHandler(); 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rd = new LoadedApk.ReceiverDispatcher( 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ActivityManagerNative.getDefault().broadcastIntent( 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getApplicationThread(), intent, resolvedType, rd, 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project initialCode, initialData, initialExtras, receiverPermission, 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project true, false); 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 714ee52055ae5eeb951bb4805bd8aa57d63718e1ce7Tsu Chiang Chuang 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendStickyBroadcast(Intent intent) { 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project try { 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ActivityManagerNative.getDefault().broadcastIntent( 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mMainThread.getApplicationThread(), intent, resolvedType, null, 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Activity.RESULT_OK, null, null, null, false, true); 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } catch (RemoteException e) { 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project @Override 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project public void sendStickyOrderedBroadcast(Intent intent, 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project BroadcastReceiver resultReceiver, 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project Handler scheduler, int initialCode, String initialData, 730eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom Bundle initialExtras) { 731eb31c0bdc0eac0898f01cdc1737cea94269f8f27Brian Carlstrom IIntentReceiver rd = null; 732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (resultReceiver != null) { 733 if (mPackageInfo != null) { 734 if (scheduler == null) { 735 scheduler = mMainThread.getHandler(); 736 } 737 rd = mPackageInfo.getReceiverDispatcher( 738 resultReceiver, getOuterContext(), scheduler, 739 mMainThread.getInstrumentation(), false); 740 } else { 741 if (scheduler == null) { 742 scheduler = mMainThread.getHandler(); 743 } 744 rd = new LoadedApk.ReceiverDispatcher( 745 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); 746 } 747 } 748 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 749 try { 750 ActivityManagerNative.getDefault().broadcastIntent( 751 mMainThread.getApplicationThread(), intent, resolvedType, rd, 752 initialCode, initialData, initialExtras, null, 753 true, true); 754 } catch (RemoteException e) { 755 } 756 } 757 758 @Override 759 public void removeStickyBroadcast(Intent intent) { 760 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); 761 if (resolvedType != null) { 762 intent = new Intent(intent); 763 intent.setDataAndType(intent.getData(), resolvedType); 764 } 765 try { 766 ActivityManagerNative.getDefault().unbroadcastIntent( 767 mMainThread.getApplicationThread(), intent); 768 } catch (RemoteException e) { 769 } 770 } 771 772 @Override 773 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 774 return registerReceiver(receiver, filter, null, null); 775 } 776 777 @Override 778 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 779 String broadcastPermission, Handler scheduler) { 780 return registerReceiverInternal(receiver, filter, broadcastPermission, 781 scheduler, getOuterContext()); 782 } 783 784 private Intent registerReceiverInternal(BroadcastReceiver receiver, 785 IntentFilter filter, String broadcastPermission, 786 Handler scheduler, Context context) { 787 IIntentReceiver rd = null; 788 if (receiver != null) { 789 if (mPackageInfo != null && context != null) { 790 if (scheduler == null) { 791 scheduler = mMainThread.getHandler(); 792 } 793 rd = mPackageInfo.getReceiverDispatcher( 794 receiver, context, scheduler, 795 mMainThread.getInstrumentation(), true); 796 } else { 797 if (scheduler == null) { 798 scheduler = mMainThread.getHandler(); 799 } 800 rd = new LoadedApk.ReceiverDispatcher( 801 receiver, context, scheduler, null, true).getIIntentReceiver(); 802 } 803 } 804 try { 805 return ActivityManagerNative.getDefault().registerReceiver( 806 mMainThread.getApplicationThread(), 807 rd, filter, broadcastPermission); 808 } catch (RemoteException e) { 809 return null; 810 } 811 } 812 813 @Override 814 public void unregisterReceiver(BroadcastReceiver receiver) { 815 if (mPackageInfo != null) { 816 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( 817 getOuterContext(), receiver); 818 try { 819 ActivityManagerNative.getDefault().unregisterReceiver(rd); 820 } catch (RemoteException e) { 821 } 822 } else { 823 throw new RuntimeException("Not supported in system context"); 824 } 825 } 826 827 @Override 828 public ComponentName startService(Intent service) { 829 try { 830 ComponentName cn = ActivityManagerNative.getDefault().startService( 831 mMainThread.getApplicationThread(), service, 832 service.resolveTypeIfNeeded(getContentResolver())); 833 if (cn != null && cn.getPackageName().equals("!")) { 834 throw new SecurityException( 835 "Not allowed to start service " + service 836 + " without permission " + cn.getClassName()); 837 } 838 return cn; 839 } catch (RemoteException e) { 840 return null; 841 } 842 } 843 844 @Override 845 public boolean stopService(Intent service) { 846 try { 847 int res = ActivityManagerNative.getDefault().stopService( 848 mMainThread.getApplicationThread(), service, 849 service.resolveTypeIfNeeded(getContentResolver())); 850 if (res < 0) { 851 throw new SecurityException( 852 "Not allowed to stop service " + service); 853 } 854 return res != 0; 855 } catch (RemoteException e) { 856 return false; 857 } 858 } 859 860 @Override 861 public boolean bindService(Intent service, ServiceConnection conn, 862 int flags) { 863 IServiceConnection sd; 864 if (mPackageInfo != null) { 865 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), 866 mMainThread.getHandler(), flags); 867 } else { 868 throw new RuntimeException("Not supported in system context"); 869 } 870 try { 871 int res = ActivityManagerNative.getDefault().bindService( 872 mMainThread.getApplicationThread(), getActivityToken(), 873 service, service.resolveTypeIfNeeded(getContentResolver()), 874 sd, flags); 875 if (res < 0) { 876 throw new SecurityException( 877 "Not allowed to bind to service " + service); 878 } 879 return res != 0; 880 } catch (RemoteException e) { 881 return false; 882 } 883 } 884 885 @Override 886 public void unbindService(ServiceConnection conn) { 887 if (mPackageInfo != null) { 888 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( 889 getOuterContext(), conn); 890 try { 891 ActivityManagerNative.getDefault().unbindService(sd); 892 } catch (RemoteException e) { 893 } 894 } else { 895 throw new RuntimeException("Not supported in system context"); 896 } 897 } 898 899 @Override 900 public boolean startInstrumentation(ComponentName className, 901 String profileFile, Bundle arguments) { 902 try { 903 return ActivityManagerNative.getDefault().startInstrumentation( 904 className, profileFile, 0, arguments, null); 905 } catch (RemoteException e) { 906 // System has crashed, nothing we can do. 907 } 908 return false; 909 } 910 911 @Override 912 public Object getSystemService(String name) { 913 if (WINDOW_SERVICE.equals(name)) { 914 return WindowManagerImpl.getDefault(); 915 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) { 916 synchronized (mSync) { 917 LayoutInflater inflater = mLayoutInflater; 918 if (inflater != null) { 919 return inflater; 920 } 921 mLayoutInflater = inflater = 922 PolicyManager.makeNewLayoutInflater(getOuterContext()); 923 return inflater; 924 } 925 } else if (ACTIVITY_SERVICE.equals(name)) { 926 return getActivityManager(); 927 } else if (INPUT_METHOD_SERVICE.equals(name)) { 928 return InputMethodManager.getInstance(this); 929 } else if (ALARM_SERVICE.equals(name)) { 930 return getAlarmManager(); 931 } else if (ACCOUNT_SERVICE.equals(name)) { 932 return getAccountManager(); 933 } else if (POWER_SERVICE.equals(name)) { 934 return getPowerManager(); 935 } else if (CONNECTIVITY_SERVICE.equals(name)) { 936 return getConnectivityManager(); 937 } else if (THROTTLE_SERVICE.equals(name)) { 938 return getThrottleManager(); 939 } else if (WIFI_SERVICE.equals(name)) { 940 return getWifiManager(); 941 } else if (NOTIFICATION_SERVICE.equals(name)) { 942 return getNotificationManager(); 943 } else if (KEYGUARD_SERVICE.equals(name)) { 944 return new KeyguardManager(); 945 } else if (ACCESSIBILITY_SERVICE.equals(name)) { 946 return AccessibilityManager.getInstance(this); 947 } else if (LOCATION_SERVICE.equals(name)) { 948 return getLocationManager(); 949 } else if (SEARCH_SERVICE.equals(name)) { 950 return getSearchManager(); 951 } else if (SENSOR_SERVICE.equals(name)) { 952 return getSensorManager(); 953 } else if (STORAGE_SERVICE.equals(name)) { 954 return getStorageManager(); 955 } else if (VIBRATOR_SERVICE.equals(name)) { 956 return getVibrator(); 957 } else if (STATUS_BAR_SERVICE.equals(name)) { 958 synchronized (mSync) { 959 if (mStatusBarManager == null) { 960 mStatusBarManager = new StatusBarManager(getOuterContext()); 961 } 962 return mStatusBarManager; 963 } 964 } else if (AUDIO_SERVICE.equals(name)) { 965 return getAudioManager(); 966 } else if (TELEPHONY_SERVICE.equals(name)) { 967 return getTelephonyManager(); 968 } else if (CLIPBOARD_SERVICE.equals(name)) { 969 return getClipboardManager(); 970 } else if (WALLPAPER_SERVICE.equals(name)) { 971 return getWallpaperManager(); 972 } else if (DROPBOX_SERVICE.equals(name)) { 973 return getDropBoxManager(); 974 } else if (DEVICE_POLICY_SERVICE.equals(name)) { 975 return getDevicePolicyManager(); 976 } else if (UI_MODE_SERVICE.equals(name)) { 977 return getUiModeManager(); 978 } else if (DOWNLOAD_SERVICE.equals(name)) { 979 return getDownloadManager(); 980 } 981 982 return null; 983 } 984 985 private AccountManager getAccountManager() { 986 synchronized (mSync) { 987 if (mAccountManager == null) { 988 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); 989 IAccountManager service = IAccountManager.Stub.asInterface(b); 990 mAccountManager = new AccountManager(this, service); 991 } 992 return mAccountManager; 993 } 994 } 995 996 private ActivityManager getActivityManager() { 997 synchronized (mSync) { 998 if (mActivityManager == null) { 999 mActivityManager = new ActivityManager(getOuterContext(), 1000 mMainThread.getHandler()); 1001 } 1002 } 1003 return mActivityManager; 1004 } 1005 1006 private AlarmManager getAlarmManager() { 1007 synchronized (sSync) { 1008 if (sAlarmManager == null) { 1009 IBinder b = ServiceManager.getService(ALARM_SERVICE); 1010 IAlarmManager service = IAlarmManager.Stub.asInterface(b); 1011 sAlarmManager = new AlarmManager(service); 1012 } 1013 } 1014 return sAlarmManager; 1015 } 1016 1017 private PowerManager getPowerManager() { 1018 synchronized (sSync) { 1019 if (sPowerManager == null) { 1020 IBinder b = ServiceManager.getService(POWER_SERVICE); 1021 IPowerManager service = IPowerManager.Stub.asInterface(b); 1022 sPowerManager = new PowerManager(service, mMainThread.getHandler()); 1023 } 1024 } 1025 return sPowerManager; 1026 } 1027 1028 private ConnectivityManager getConnectivityManager() 1029 { 1030 synchronized (sSync) { 1031 if (sConnectivityManager == null) { 1032 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE); 1033 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 1034 sConnectivityManager = new ConnectivityManager(service); 1035 } 1036 } 1037 return sConnectivityManager; 1038 } 1039 1040 private ThrottleManager getThrottleManager() 1041 { 1042 synchronized (sSync) { 1043 if (sThrottleManager == null) { 1044 IBinder b = ServiceManager.getService(THROTTLE_SERVICE); 1045 IThrottleManager service = IThrottleManager.Stub.asInterface(b); 1046 sThrottleManager = new ThrottleManager(service); 1047 } 1048 } 1049 return sThrottleManager; 1050 } 1051 1052 private WifiManager getWifiManager() 1053 { 1054 synchronized (sSync) { 1055 if (sWifiManager == null) { 1056 IBinder b = ServiceManager.getService(WIFI_SERVICE); 1057 IWifiManager service = IWifiManager.Stub.asInterface(b); 1058 sWifiManager = new WifiManager(service, mMainThread.getHandler()); 1059 } 1060 } 1061 return sWifiManager; 1062 } 1063 1064 private NotificationManager getNotificationManager() { 1065 synchronized (mSync) { 1066 if (mNotificationManager == null) { 1067 mNotificationManager = new NotificationManager( 1068 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog), 1069 mMainThread.getHandler()); 1070 } 1071 } 1072 return mNotificationManager; 1073 } 1074 1075 private WallpaperManager getWallpaperManager() { 1076 synchronized (mSync) { 1077 if (mWallpaperManager == null) { 1078 mWallpaperManager = new WallpaperManager(getOuterContext(), 1079 mMainThread.getHandler()); 1080 } 1081 } 1082 return mWallpaperManager; 1083 } 1084 1085 private TelephonyManager getTelephonyManager() { 1086 synchronized (mSync) { 1087 if (mTelephonyManager == null) { 1088 mTelephonyManager = new TelephonyManager(getOuterContext()); 1089 } 1090 } 1091 return mTelephonyManager; 1092 } 1093 1094 private ClipboardManager getClipboardManager() { 1095 synchronized (mSync) { 1096 if (mClipboardManager == null) { 1097 mClipboardManager = new ClipboardManager(getOuterContext(), 1098 mMainThread.getHandler()); 1099 } 1100 } 1101 return mClipboardManager; 1102 } 1103 1104 private LocationManager getLocationManager() { 1105 synchronized (sSync) { 1106 if (sLocationManager == null) { 1107 IBinder b = ServiceManager.getService(LOCATION_SERVICE); 1108 ILocationManager service = ILocationManager.Stub.asInterface(b); 1109 sLocationManager = new LocationManager(service); 1110 } 1111 } 1112 return sLocationManager; 1113 } 1114 1115 private SearchManager getSearchManager() { 1116 synchronized (mSync) { 1117 if (mSearchManager == null) { 1118 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler()); 1119 } 1120 } 1121 return mSearchManager; 1122 } 1123 1124 private SensorManager getSensorManager() { 1125 synchronized (mSync) { 1126 if (mSensorManager == null) { 1127 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper()); 1128 } 1129 } 1130 return mSensorManager; 1131 } 1132 1133 private StorageManager getStorageManager() { 1134 synchronized (mSync) { 1135 if (mStorageManager == null) { 1136 try { 1137 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper()); 1138 } catch (RemoteException rex) { 1139 Log.e(TAG, "Failed to create StorageManager", rex); 1140 mStorageManager = null; 1141 } 1142 } 1143 } 1144 return mStorageManager; 1145 } 1146 1147 private Vibrator getVibrator() { 1148 synchronized (mSync) { 1149 if (mVibrator == null) { 1150 mVibrator = new Vibrator(); 1151 } 1152 } 1153 return mVibrator; 1154 } 1155 1156 private AudioManager getAudioManager() 1157 { 1158 if (mAudioManager == null) { 1159 mAudioManager = new AudioManager(this); 1160 } 1161 return mAudioManager; 1162 } 1163 1164 /* package */ static DropBoxManager createDropBoxManager() { 1165 IBinder b = ServiceManager.getService(DROPBOX_SERVICE); 1166 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); 1167 return new DropBoxManager(service); 1168 } 1169 1170 private DropBoxManager getDropBoxManager() { 1171 synchronized (mSync) { 1172 if (mDropBoxManager == null) { 1173 mDropBoxManager = createDropBoxManager(); 1174 } 1175 } 1176 return mDropBoxManager; 1177 } 1178 1179 private DevicePolicyManager getDevicePolicyManager() { 1180 synchronized (mSync) { 1181 if (mDevicePolicyManager == null) { 1182 mDevicePolicyManager = DevicePolicyManager.create(this, 1183 mMainThread.getHandler()); 1184 } 1185 } 1186 return mDevicePolicyManager; 1187 } 1188 1189 private UiModeManager getUiModeManager() { 1190 synchronized (mSync) { 1191 if (mUiModeManager == null) { 1192 mUiModeManager = new UiModeManager(); 1193 } 1194 } 1195 return mUiModeManager; 1196 } 1197 1198 private DownloadManager getDownloadManager() { 1199 synchronized (mSync) { 1200 if (mDownloadManager == null) { 1201 mDownloadManager = new DownloadManager(getContentResolver(), getPackageName()); 1202 } 1203 } 1204 return mDownloadManager; 1205 } 1206 1207 @Override 1208 public int checkPermission(String permission, int pid, int uid) { 1209 if (permission == null) { 1210 throw new IllegalArgumentException("permission is null"); 1211 } 1212 1213 if (!Process.supportsProcesses()) { 1214 return PackageManager.PERMISSION_GRANTED; 1215 } 1216 try { 1217 return ActivityManagerNative.getDefault().checkPermission( 1218 permission, pid, uid); 1219 } catch (RemoteException e) { 1220 return PackageManager.PERMISSION_DENIED; 1221 } 1222 } 1223 1224 @Override 1225 public int checkCallingPermission(String permission) { 1226 if (permission == null) { 1227 throw new IllegalArgumentException("permission is null"); 1228 } 1229 1230 if (!Process.supportsProcesses()) { 1231 return PackageManager.PERMISSION_GRANTED; 1232 } 1233 int pid = Binder.getCallingPid(); 1234 if (pid != Process.myPid()) { 1235 return checkPermission(permission, pid, 1236 Binder.getCallingUid()); 1237 } 1238 return PackageManager.PERMISSION_DENIED; 1239 } 1240 1241 @Override 1242 public int checkCallingOrSelfPermission(String permission) { 1243 if (permission == null) { 1244 throw new IllegalArgumentException("permission is null"); 1245 } 1246 1247 return checkPermission(permission, Binder.getCallingPid(), 1248 Binder.getCallingUid()); 1249 } 1250 1251 private void enforce( 1252 String permission, int resultOfCheck, 1253 boolean selfToo, int uid, String message) { 1254 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1255 throw new SecurityException( 1256 (message != null ? (message + ": ") : "") + 1257 (selfToo 1258 ? "Neither user " + uid + " nor current process has " 1259 : "User " + uid + " does not have ") + 1260 permission + 1261 "."); 1262 } 1263 } 1264 1265 public void enforcePermission( 1266 String permission, int pid, int uid, String message) { 1267 enforce(permission, 1268 checkPermission(permission, pid, uid), 1269 false, 1270 uid, 1271 message); 1272 } 1273 1274 public void enforceCallingPermission(String permission, String message) { 1275 enforce(permission, 1276 checkCallingPermission(permission), 1277 false, 1278 Binder.getCallingUid(), 1279 message); 1280 } 1281 1282 public void enforceCallingOrSelfPermission( 1283 String permission, String message) { 1284 enforce(permission, 1285 checkCallingOrSelfPermission(permission), 1286 true, 1287 Binder.getCallingUid(), 1288 message); 1289 } 1290 1291 @Override 1292 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 1293 try { 1294 ActivityManagerNative.getDefault().grantUriPermission( 1295 mMainThread.getApplicationThread(), toPackage, uri, 1296 modeFlags); 1297 } catch (RemoteException e) { 1298 } 1299 } 1300 1301 @Override 1302 public void revokeUriPermission(Uri uri, int modeFlags) { 1303 try { 1304 ActivityManagerNative.getDefault().revokeUriPermission( 1305 mMainThread.getApplicationThread(), uri, 1306 modeFlags); 1307 } catch (RemoteException e) { 1308 } 1309 } 1310 1311 @Override 1312 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 1313 if (!Process.supportsProcesses()) { 1314 return PackageManager.PERMISSION_GRANTED; 1315 } 1316 try { 1317 return ActivityManagerNative.getDefault().checkUriPermission( 1318 uri, pid, uid, modeFlags); 1319 } catch (RemoteException e) { 1320 return PackageManager.PERMISSION_DENIED; 1321 } 1322 } 1323 1324 @Override 1325 public int checkCallingUriPermission(Uri uri, int modeFlags) { 1326 if (!Process.supportsProcesses()) { 1327 return PackageManager.PERMISSION_GRANTED; 1328 } 1329 int pid = Binder.getCallingPid(); 1330 if (pid != Process.myPid()) { 1331 return checkUriPermission(uri, pid, 1332 Binder.getCallingUid(), modeFlags); 1333 } 1334 return PackageManager.PERMISSION_DENIED; 1335 } 1336 1337 @Override 1338 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 1339 return checkUriPermission(uri, Binder.getCallingPid(), 1340 Binder.getCallingUid(), modeFlags); 1341 } 1342 1343 @Override 1344 public int checkUriPermission(Uri uri, String readPermission, 1345 String writePermission, int pid, int uid, int modeFlags) { 1346 if (DEBUG) { 1347 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" 1348 + readPermission + " writePermission=" + writePermission 1349 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); 1350 } 1351 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 1352 if (readPermission == null 1353 || checkPermission(readPermission, pid, uid) 1354 == PackageManager.PERMISSION_GRANTED) { 1355 return PackageManager.PERMISSION_GRANTED; 1356 } 1357 } 1358 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 1359 if (writePermission == null 1360 || checkPermission(writePermission, pid, uid) 1361 == PackageManager.PERMISSION_GRANTED) { 1362 return PackageManager.PERMISSION_GRANTED; 1363 } 1364 } 1365 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) 1366 : PackageManager.PERMISSION_DENIED; 1367 } 1368 1369 private String uriModeFlagToString(int uriModeFlags) { 1370 switch (uriModeFlags) { 1371 case Intent.FLAG_GRANT_READ_URI_PERMISSION | 1372 Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1373 return "read and write"; 1374 case Intent.FLAG_GRANT_READ_URI_PERMISSION: 1375 return "read"; 1376 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION: 1377 return "write"; 1378 } 1379 throw new IllegalArgumentException( 1380 "Unknown permission mode flags: " + uriModeFlags); 1381 } 1382 1383 private void enforceForUri( 1384 int modeFlags, int resultOfCheck, boolean selfToo, 1385 int uid, Uri uri, String message) { 1386 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { 1387 throw new SecurityException( 1388 (message != null ? (message + ": ") : "") + 1389 (selfToo 1390 ? "Neither user " + uid + " nor current process has " 1391 : "User " + uid + " does not have ") + 1392 uriModeFlagToString(modeFlags) + 1393 " permission on " + 1394 uri + 1395 "."); 1396 } 1397 } 1398 1399 public void enforceUriPermission( 1400 Uri uri, int pid, int uid, int modeFlags, String message) { 1401 enforceForUri( 1402 modeFlags, checkUriPermission(uri, pid, uid, modeFlags), 1403 false, uid, uri, message); 1404 } 1405 1406 public void enforceCallingUriPermission( 1407 Uri uri, int modeFlags, String message) { 1408 enforceForUri( 1409 modeFlags, checkCallingUriPermission(uri, modeFlags), 1410 false, Binder.getCallingUid(), uri, message); 1411 } 1412 1413 public void enforceCallingOrSelfUriPermission( 1414 Uri uri, int modeFlags, String message) { 1415 enforceForUri( 1416 modeFlags, 1417 checkCallingOrSelfUriPermission(uri, modeFlags), true, 1418 Binder.getCallingUid(), uri, message); 1419 } 1420 1421 public void enforceUriPermission( 1422 Uri uri, String readPermission, String writePermission, 1423 int pid, int uid, int modeFlags, String message) { 1424 enforceForUri(modeFlags, 1425 checkUriPermission( 1426 uri, readPermission, writePermission, pid, uid, 1427 modeFlags), 1428 false, 1429 uid, 1430 uri, 1431 message); 1432 } 1433 1434 @Override 1435 public Context createPackageContext(String packageName, int flags) 1436 throws PackageManager.NameNotFoundException { 1437 if (packageName.equals("system") || packageName.equals("android")) { 1438 return new ContextImpl(mMainThread.getSystemContext()); 1439 } 1440 1441 LoadedApk pi = 1442 mMainThread.getPackageInfo(packageName, flags); 1443 if (pi != null) { 1444 ContextImpl c = new ContextImpl(); 1445 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; 1446 c.init(pi, null, mMainThread, mResources); 1447 if (c.mResources != null) { 1448 return c; 1449 } 1450 } 1451 1452 // Should be a better exception. 1453 throw new PackageManager.NameNotFoundException( 1454 "Application package " + packageName + " not found"); 1455 } 1456 1457 @Override 1458 public boolean isRestricted() { 1459 return mRestricted; 1460 } 1461 1462 private File getDataDirFile() { 1463 if (mPackageInfo != null) { 1464 return mPackageInfo.getDataDirFile(); 1465 } 1466 throw new RuntimeException("Not supported in system context"); 1467 } 1468 1469 @Override 1470 public File getDir(String name, int mode) { 1471 name = "app_" + name; 1472 File file = makeFilename(getDataDirFile(), name); 1473 if (!file.exists()) { 1474 file.mkdir(); 1475 setFilePermissionsFromMode(file.getPath(), mode, 1476 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); 1477 } 1478 return file; 1479 } 1480 1481 static ContextImpl createSystemContext(ActivityThread mainThread) { 1482 ContextImpl context = new ContextImpl(); 1483 context.init(Resources.getSystem(), mainThread); 1484 return context; 1485 } 1486 1487 ContextImpl() { 1488 // For debug only 1489 //++sInstanceCount; 1490 mOuterContext = this; 1491 } 1492 1493 /** 1494 * Create a new ApplicationContext from an existing one. The new one 1495 * works and operates the same as the one it is copying. 1496 * 1497 * @param context Existing application context. 1498 */ 1499 public ContextImpl(ContextImpl context) { 1500 ++sInstanceCount; 1501 mPackageInfo = context.mPackageInfo; 1502 mResources = context.mResources; 1503 mMainThread = context.mMainThread; 1504 mContentResolver = context.mContentResolver; 1505 mOuterContext = this; 1506 } 1507 1508 final void init(LoadedApk packageInfo, 1509 IBinder activityToken, ActivityThread mainThread) { 1510 init(packageInfo, activityToken, mainThread, null); 1511 } 1512 1513 final void init(LoadedApk packageInfo, 1514 IBinder activityToken, ActivityThread mainThread, 1515 Resources container) { 1516 mPackageInfo = packageInfo; 1517 mResources = mPackageInfo.getResources(mainThread); 1518 1519 if (mResources != null && container != null 1520 && container.getCompatibilityInfo().applicationScale != 1521 mResources.getCompatibilityInfo().applicationScale) { 1522 if (DEBUG) { 1523 Log.d(TAG, "loaded context has different scaling. Using container's" + 1524 " compatiblity info:" + container.getDisplayMetrics()); 1525 } 1526 mResources = mainThread.getTopLevelResources( 1527 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy()); 1528 } 1529 mMainThread = mainThread; 1530 mContentResolver = new ApplicationContentResolver(this, mainThread); 1531 1532 setActivityToken(activityToken); 1533 } 1534 1535 final void init(Resources resources, ActivityThread mainThread) { 1536 mPackageInfo = null; 1537 mResources = resources; 1538 mMainThread = mainThread; 1539 mContentResolver = new ApplicationContentResolver(this, mainThread); 1540 } 1541 1542 final void scheduleFinalCleanup(String who, String what) { 1543 mMainThread.scheduleContextCleanup(this, who, what); 1544 } 1545 1546 final void performFinalCleanup(String who, String what) { 1547 //Log.i(TAG, "Cleanup up context: " + this); 1548 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); 1549 } 1550 1551 final Context getReceiverRestrictedContext() { 1552 if (mReceiverRestrictedContext != null) { 1553 return mReceiverRestrictedContext; 1554 } 1555 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); 1556 } 1557 1558 final void setActivityToken(IBinder token) { 1559 mActivityToken = token; 1560 } 1561 1562 final void setOuterContext(Context context) { 1563 mOuterContext = context; 1564 } 1565 1566 final Context getOuterContext() { 1567 return mOuterContext; 1568 } 1569 1570 final IBinder getActivityToken() { 1571 return mActivityToken; 1572 } 1573 1574 private static void setFilePermissionsFromMode(String name, int mode, 1575 int extraPermissions) { 1576 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR 1577 |FileUtils.S_IRGRP|FileUtils.S_IWGRP 1578 |extraPermissions; 1579 if ((mode&MODE_WORLD_READABLE) != 0) { 1580 perms |= FileUtils.S_IROTH; 1581 } 1582 if ((mode&MODE_WORLD_WRITEABLE) != 0) { 1583 perms |= FileUtils.S_IWOTH; 1584 } 1585 if (DEBUG) { 1586 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) 1587 + ", perms=0x" + Integer.toHexString(perms)); 1588 } 1589 FileUtils.setPermissions(name, perms, -1, -1); 1590 } 1591 1592 private File validateFilePath(String name, boolean createDirectory) { 1593 File dir; 1594 File f; 1595 1596 if (name.charAt(0) == File.separatorChar) { 1597 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); 1598 dir = new File(dirPath); 1599 name = name.substring(name.lastIndexOf(File.separatorChar)); 1600 f = new File(dir, name); 1601 } else { 1602 dir = getDatabasesDir(); 1603 f = makeFilename(dir, name); 1604 } 1605 1606 if (createDirectory && !dir.isDirectory() && dir.mkdir()) { 1607 FileUtils.setPermissions(dir.getPath(), 1608 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 1609 -1, -1); 1610 } 1611 1612 return f; 1613 } 1614 1615 private File makeFilename(File base, String name) { 1616 if (name.indexOf(File.separatorChar) < 0) { 1617 return new File(base, name); 1618 } 1619 throw new IllegalArgumentException( 1620 "File " + name + " contains a path separator"); 1621 } 1622 1623 // ---------------------------------------------------------------------- 1624 // ---------------------------------------------------------------------- 1625 // ---------------------------------------------------------------------- 1626 1627 private static final class ApplicationContentResolver extends ContentResolver { 1628 public ApplicationContentResolver(Context context, ActivityThread mainThread) { 1629 super(context); 1630 mMainThread = mainThread; 1631 } 1632 1633 @Override 1634 protected IContentProvider acquireProvider(Context context, String name) { 1635 return mMainThread.acquireProvider(context, name); 1636 } 1637 1638 @Override 1639 protected IContentProvider acquireExistingProvider(Context context, String name) { 1640 return mMainThread.acquireExistingProvider(context, name); 1641 } 1642 1643 @Override 1644 public boolean releaseProvider(IContentProvider provider) { 1645 return mMainThread.releaseProvider(provider); 1646 } 1647 1648 private final ActivityThread mMainThread; 1649 } 1650 1651 // ---------------------------------------------------------------------- 1652 // ---------------------------------------------------------------------- 1653 // ---------------------------------------------------------------------- 1654 1655 /*package*/ 1656 static final class ApplicationPackageManager extends PackageManager { 1657 @Override 1658 public PackageInfo getPackageInfo(String packageName, int flags) 1659 throws NameNotFoundException { 1660 try { 1661 PackageInfo pi = mPM.getPackageInfo(packageName, flags); 1662 if (pi != null) { 1663 return pi; 1664 } 1665 } catch (RemoteException e) { 1666 throw new RuntimeException("Package manager has died", e); 1667 } 1668 1669 throw new NameNotFoundException(packageName); 1670 } 1671 1672 @Override 1673 public String[] currentToCanonicalPackageNames(String[] names) { 1674 try { 1675 return mPM.currentToCanonicalPackageNames(names); 1676 } catch (RemoteException e) { 1677 throw new RuntimeException("Package manager has died", e); 1678 } 1679 } 1680 1681 @Override 1682 public String[] canonicalToCurrentPackageNames(String[] names) { 1683 try { 1684 return mPM.canonicalToCurrentPackageNames(names); 1685 } catch (RemoteException e) { 1686 throw new RuntimeException("Package manager has died", e); 1687 } 1688 } 1689 1690 @Override 1691 public Intent getLaunchIntentForPackage(String packageName) { 1692 // First see if the package has an INFO activity; the existence of 1693 // such an activity is implied to be the desired front-door for the 1694 // overall package (such as if it has multiple launcher entries). 1695 Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 1696 intentToResolve.addCategory(Intent.CATEGORY_INFO); 1697 intentToResolve.setPackage(packageName); 1698 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0); 1699 1700 // Otherwise, try to find a main launcher activity. 1701 if (resolveInfo == null) { 1702 // reuse the intent instance 1703 intentToResolve.removeCategory(Intent.CATEGORY_INFO); 1704 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 1705 intentToResolve.setPackage(packageName); 1706 resolveInfo = resolveActivity(intentToResolve, 0); 1707 } 1708 if (resolveInfo == null) { 1709 return null; 1710 } 1711 Intent intent = new Intent(Intent.ACTION_MAIN); 1712 intent.setClassName(packageName, resolveInfo.activityInfo.name); 1713 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1714 return intent; 1715 } 1716 1717 @Override 1718 public int[] getPackageGids(String packageName) 1719 throws NameNotFoundException { 1720 try { 1721 int[] gids = mPM.getPackageGids(packageName); 1722 if (gids == null || gids.length > 0) { 1723 return gids; 1724 } 1725 } catch (RemoteException e) { 1726 throw new RuntimeException("Package manager has died", e); 1727 } 1728 1729 throw new NameNotFoundException(packageName); 1730 } 1731 1732 @Override 1733 public PermissionInfo getPermissionInfo(String name, int flags) 1734 throws NameNotFoundException { 1735 try { 1736 PermissionInfo pi = mPM.getPermissionInfo(name, flags); 1737 if (pi != null) { 1738 return pi; 1739 } 1740 } catch (RemoteException e) { 1741 throw new RuntimeException("Package manager has died", e); 1742 } 1743 1744 throw new NameNotFoundException(name); 1745 } 1746 1747 @Override 1748 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) 1749 throws NameNotFoundException { 1750 try { 1751 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags); 1752 if (pi != null) { 1753 return pi; 1754 } 1755 } catch (RemoteException e) { 1756 throw new RuntimeException("Package manager has died", e); 1757 } 1758 1759 throw new NameNotFoundException(group); 1760 } 1761 1762 @Override 1763 public PermissionGroupInfo getPermissionGroupInfo(String name, 1764 int flags) throws NameNotFoundException { 1765 try { 1766 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags); 1767 if (pgi != null) { 1768 return pgi; 1769 } 1770 } catch (RemoteException e) { 1771 throw new RuntimeException("Package manager has died", e); 1772 } 1773 1774 throw new NameNotFoundException(name); 1775 } 1776 1777 @Override 1778 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 1779 try { 1780 return mPM.getAllPermissionGroups(flags); 1781 } catch (RemoteException e) { 1782 throw new RuntimeException("Package manager has died", e); 1783 } 1784 } 1785 1786 @Override 1787 public ApplicationInfo getApplicationInfo(String packageName, int flags) 1788 throws NameNotFoundException { 1789 try { 1790 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags); 1791 if (ai != null) { 1792 return ai; 1793 } 1794 } catch (RemoteException e) { 1795 throw new RuntimeException("Package manager has died", e); 1796 } 1797 1798 throw new NameNotFoundException(packageName); 1799 } 1800 1801 @Override 1802 public ActivityInfo getActivityInfo(ComponentName className, int flags) 1803 throws NameNotFoundException { 1804 try { 1805 ActivityInfo ai = mPM.getActivityInfo(className, flags); 1806 if (ai != null) { 1807 return ai; 1808 } 1809 } catch (RemoteException e) { 1810 throw new RuntimeException("Package manager has died", e); 1811 } 1812 1813 throw new NameNotFoundException(className.toString()); 1814 } 1815 1816 @Override 1817 public ActivityInfo getReceiverInfo(ComponentName className, int flags) 1818 throws NameNotFoundException { 1819 try { 1820 ActivityInfo ai = mPM.getReceiverInfo(className, flags); 1821 if (ai != null) { 1822 return ai; 1823 } 1824 } catch (RemoteException e) { 1825 throw new RuntimeException("Package manager has died", e); 1826 } 1827 1828 throw new NameNotFoundException(className.toString()); 1829 } 1830 1831 @Override 1832 public ServiceInfo getServiceInfo(ComponentName className, int flags) 1833 throws NameNotFoundException { 1834 try { 1835 ServiceInfo si = mPM.getServiceInfo(className, flags); 1836 if (si != null) { 1837 return si; 1838 } 1839 } catch (RemoteException e) { 1840 throw new RuntimeException("Package manager has died", e); 1841 } 1842 1843 throw new NameNotFoundException(className.toString()); 1844 } 1845 1846 @Override 1847 public ProviderInfo getProviderInfo(ComponentName className, int flags) 1848 throws NameNotFoundException { 1849 try { 1850 ProviderInfo pi = mPM.getProviderInfo(className, flags); 1851 if (pi != null) { 1852 return pi; 1853 } 1854 } catch (RemoteException e) { 1855 throw new RuntimeException("Package manager has died", e); 1856 } 1857 1858 throw new NameNotFoundException(className.toString()); 1859 } 1860 1861 @Override 1862 public String[] getSystemSharedLibraryNames() { 1863 try { 1864 return mPM.getSystemSharedLibraryNames(); 1865 } catch (RemoteException e) { 1866 throw new RuntimeException("Package manager has died", e); 1867 } 1868 } 1869 1870 @Override 1871 public FeatureInfo[] getSystemAvailableFeatures() { 1872 try { 1873 return mPM.getSystemAvailableFeatures(); 1874 } catch (RemoteException e) { 1875 throw new RuntimeException("Package manager has died", e); 1876 } 1877 } 1878 1879 @Override 1880 public boolean hasSystemFeature(String name) { 1881 try { 1882 return mPM.hasSystemFeature(name); 1883 } catch (RemoteException e) { 1884 throw new RuntimeException("Package manager has died", e); 1885 } 1886 } 1887 1888 @Override 1889 public int checkPermission(String permName, String pkgName) { 1890 try { 1891 return mPM.checkPermission(permName, pkgName); 1892 } catch (RemoteException e) { 1893 throw new RuntimeException("Package manager has died", e); 1894 } 1895 } 1896 1897 @Override 1898 public boolean addPermission(PermissionInfo info) { 1899 try { 1900 return mPM.addPermission(info); 1901 } catch (RemoteException e) { 1902 throw new RuntimeException("Package manager has died", e); 1903 } 1904 } 1905 1906 @Override 1907 public boolean addPermissionAsync(PermissionInfo info) { 1908 try { 1909 return mPM.addPermissionAsync(info); 1910 } catch (RemoteException e) { 1911 throw new RuntimeException("Package manager has died", e); 1912 } 1913 } 1914 1915 @Override 1916 public void removePermission(String name) { 1917 try { 1918 mPM.removePermission(name); 1919 } catch (RemoteException e) { 1920 throw new RuntimeException("Package manager has died", e); 1921 } 1922 } 1923 1924 @Override 1925 public int checkSignatures(String pkg1, String pkg2) { 1926 try { 1927 return mPM.checkSignatures(pkg1, pkg2); 1928 } catch (RemoteException e) { 1929 throw new RuntimeException("Package manager has died", e); 1930 } 1931 } 1932 1933 @Override 1934 public int checkSignatures(int uid1, int uid2) { 1935 try { 1936 return mPM.checkUidSignatures(uid1, uid2); 1937 } catch (RemoteException e) { 1938 throw new RuntimeException("Package manager has died", e); 1939 } 1940 } 1941 1942 @Override 1943 public String[] getPackagesForUid(int uid) { 1944 try { 1945 return mPM.getPackagesForUid(uid); 1946 } catch (RemoteException e) { 1947 throw new RuntimeException("Package manager has died", e); 1948 } 1949 } 1950 1951 @Override 1952 public String getNameForUid(int uid) { 1953 try { 1954 return mPM.getNameForUid(uid); 1955 } catch (RemoteException e) { 1956 throw new RuntimeException("Package manager has died", e); 1957 } 1958 } 1959 1960 @Override 1961 public int getUidForSharedUser(String sharedUserName) 1962 throws NameNotFoundException { 1963 try { 1964 int uid = mPM.getUidForSharedUser(sharedUserName); 1965 if(uid != -1) { 1966 return uid; 1967 } 1968 } catch (RemoteException e) { 1969 throw new RuntimeException("Package manager has died", e); 1970 } 1971 throw new NameNotFoundException("No shared userid for user:"+sharedUserName); 1972 } 1973 1974 @Override 1975 public List<PackageInfo> getInstalledPackages(int flags) { 1976 try { 1977 return mPM.getInstalledPackages(flags); 1978 } catch (RemoteException e) { 1979 throw new RuntimeException("Package manager has died", e); 1980 } 1981 } 1982 1983 @Override 1984 public List<ApplicationInfo> getInstalledApplications(int flags) { 1985 try { 1986 return mPM.getInstalledApplications(flags); 1987 } catch (RemoteException e) { 1988 throw new RuntimeException("Package manager has died", e); 1989 } 1990 } 1991 1992 @Override 1993 public ResolveInfo resolveActivity(Intent intent, int flags) { 1994 try { 1995 return mPM.resolveIntent( 1996 intent, 1997 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 1998 flags); 1999 } catch (RemoteException e) { 2000 throw new RuntimeException("Package manager has died", e); 2001 } 2002 } 2003 2004 @Override 2005 public List<ResolveInfo> queryIntentActivities(Intent intent, 2006 int flags) { 2007 try { 2008 return mPM.queryIntentActivities( 2009 intent, 2010 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2011 flags); 2012 } catch (RemoteException e) { 2013 throw new RuntimeException("Package manager has died", e); 2014 } 2015 } 2016 2017 @Override 2018 public List<ResolveInfo> queryIntentActivityOptions( 2019 ComponentName caller, Intent[] specifics, Intent intent, 2020 int flags) { 2021 final ContentResolver resolver = mContext.getContentResolver(); 2022 2023 String[] specificTypes = null; 2024 if (specifics != null) { 2025 final int N = specifics.length; 2026 for (int i=0; i<N; i++) { 2027 Intent sp = specifics[i]; 2028 if (sp != null) { 2029 String t = sp.resolveTypeIfNeeded(resolver); 2030 if (t != null) { 2031 if (specificTypes == null) { 2032 specificTypes = new String[N]; 2033 } 2034 specificTypes[i] = t; 2035 } 2036 } 2037 } 2038 } 2039 2040 try { 2041 return mPM.queryIntentActivityOptions(caller, specifics, 2042 specificTypes, intent, intent.resolveTypeIfNeeded(resolver), 2043 flags); 2044 } catch (RemoteException e) { 2045 throw new RuntimeException("Package manager has died", e); 2046 } 2047 } 2048 2049 @Override 2050 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) { 2051 try { 2052 return mPM.queryIntentReceivers( 2053 intent, 2054 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2055 flags); 2056 } catch (RemoteException e) { 2057 throw new RuntimeException("Package manager has died", e); 2058 } 2059 } 2060 2061 @Override 2062 public ResolveInfo resolveService(Intent intent, int flags) { 2063 try { 2064 return mPM.resolveService( 2065 intent, 2066 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2067 flags); 2068 } catch (RemoteException e) { 2069 throw new RuntimeException("Package manager has died", e); 2070 } 2071 } 2072 2073 @Override 2074 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) { 2075 try { 2076 return mPM.queryIntentServices( 2077 intent, 2078 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2079 flags); 2080 } catch (RemoteException e) { 2081 throw new RuntimeException("Package manager has died", e); 2082 } 2083 } 2084 2085 @Override 2086 public ProviderInfo resolveContentProvider(String name, 2087 int flags) { 2088 try { 2089 return mPM.resolveContentProvider(name, flags); 2090 } catch (RemoteException e) { 2091 throw new RuntimeException("Package manager has died", e); 2092 } 2093 } 2094 2095 @Override 2096 public List<ProviderInfo> queryContentProviders(String processName, 2097 int uid, int flags) { 2098 try { 2099 return mPM.queryContentProviders(processName, uid, flags); 2100 } catch (RemoteException e) { 2101 throw new RuntimeException("Package manager has died", e); 2102 } 2103 } 2104 2105 @Override 2106 public InstrumentationInfo getInstrumentationInfo( 2107 ComponentName className, int flags) 2108 throws NameNotFoundException { 2109 try { 2110 InstrumentationInfo ii = mPM.getInstrumentationInfo( 2111 className, flags); 2112 if (ii != null) { 2113 return ii; 2114 } 2115 } catch (RemoteException e) { 2116 throw new RuntimeException("Package manager has died", e); 2117 } 2118 2119 throw new NameNotFoundException(className.toString()); 2120 } 2121 2122 @Override 2123 public List<InstrumentationInfo> queryInstrumentation( 2124 String targetPackage, int flags) { 2125 try { 2126 return mPM.queryInstrumentation(targetPackage, flags); 2127 } catch (RemoteException e) { 2128 throw new RuntimeException("Package manager has died", e); 2129 } 2130 } 2131 2132 @Override public Drawable getDrawable(String packageName, int resid, 2133 ApplicationInfo appInfo) { 2134 ResourceName name = new ResourceName(packageName, resid); 2135 Drawable dr = getCachedIcon(name); 2136 if (dr != null) { 2137 return dr; 2138 } 2139 if (appInfo == null) { 2140 try { 2141 appInfo = getApplicationInfo(packageName, 0); 2142 } catch (NameNotFoundException e) { 2143 return null; 2144 } 2145 } 2146 try { 2147 Resources r = getResourcesForApplication(appInfo); 2148 dr = r.getDrawable(resid); 2149 if (false) { 2150 RuntimeException e = new RuntimeException("here"); 2151 e.fillInStackTrace(); 2152 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid) 2153 + " from package " + packageName 2154 + ": app scale=" + r.getCompatibilityInfo().applicationScale 2155 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale, 2156 e); 2157 } 2158 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x" 2159 + Integer.toHexString(resid) + " from " + r 2160 + ": " + dr); 2161 putCachedIcon(name, dr); 2162 return dr; 2163 } catch (NameNotFoundException e) { 2164 Log.w("PackageManager", "Failure retrieving resources for" 2165 + appInfo.packageName); 2166 } catch (RuntimeException e) { 2167 // If an exception was thrown, fall through to return 2168 // default icon. 2169 Log.w("PackageManager", "Failure retrieving icon 0x" 2170 + Integer.toHexString(resid) + " in package " 2171 + packageName, e); 2172 } 2173 return null; 2174 } 2175 2176 @Override public Drawable getActivityIcon(ComponentName activityName) 2177 throws NameNotFoundException { 2178 return getActivityInfo(activityName, 0).loadIcon(this); 2179 } 2180 2181 @Override public Drawable getActivityIcon(Intent intent) 2182 throws NameNotFoundException { 2183 if (intent.getComponent() != null) { 2184 return getActivityIcon(intent.getComponent()); 2185 } 2186 2187 ResolveInfo info = resolveActivity( 2188 intent, PackageManager.MATCH_DEFAULT_ONLY); 2189 if (info != null) { 2190 return info.activityInfo.loadIcon(this); 2191 } 2192 2193 throw new NameNotFoundException(intent.toURI()); 2194 } 2195 2196 @Override public Drawable getDefaultActivityIcon() { 2197 return Resources.getSystem().getDrawable( 2198 com.android.internal.R.drawable.sym_def_app_icon); 2199 } 2200 2201 @Override public Drawable getApplicationIcon(ApplicationInfo info) { 2202 return info.loadIcon(this); 2203 } 2204 2205 @Override public Drawable getApplicationIcon(String packageName) 2206 throws NameNotFoundException { 2207 return getApplicationIcon(getApplicationInfo(packageName, 0)); 2208 } 2209 2210 @Override 2211 public Drawable getActivityLogo(ComponentName activityName) 2212 throws NameNotFoundException { 2213 return getActivityInfo(activityName, 0).loadLogo(this); 2214 } 2215 2216 @Override 2217 public Drawable getActivityLogo(Intent intent) 2218 throws NameNotFoundException { 2219 if (intent.getComponent() != null) { 2220 return getActivityLogo(intent.getComponent()); 2221 } 2222 2223 ResolveInfo info = resolveActivity( 2224 intent, PackageManager.MATCH_DEFAULT_ONLY); 2225 if (info != null) { 2226 return info.activityInfo.loadLogo(this); 2227 } 2228 2229 throw new NameNotFoundException(intent.toUri(0)); 2230 } 2231 2232 @Override 2233 public Drawable getApplicationLogo(ApplicationInfo info) { 2234 return info.loadLogo(this); 2235 } 2236 2237 @Override 2238 public Drawable getApplicationLogo(String packageName) 2239 throws NameNotFoundException { 2240 return getApplicationLogo(getApplicationInfo(packageName, 0)); 2241 } 2242 2243 @Override public Resources getResourcesForActivity( 2244 ComponentName activityName) throws NameNotFoundException { 2245 return getResourcesForApplication( 2246 getActivityInfo(activityName, 0).applicationInfo); 2247 } 2248 2249 @Override public Resources getResourcesForApplication( 2250 ApplicationInfo app) throws NameNotFoundException { 2251 if (app.packageName.equals("system")) { 2252 return mContext.mMainThread.getSystemContext().getResources(); 2253 } 2254 Resources r = mContext.mMainThread.getTopLevelResources( 2255 app.uid == Process.myUid() ? app.sourceDir 2256 : app.publicSourceDir, mContext.mPackageInfo); 2257 if (r != null) { 2258 return r; 2259 } 2260 throw new NameNotFoundException("Unable to open " + app.publicSourceDir); 2261 } 2262 2263 @Override public Resources getResourcesForApplication( 2264 String appPackageName) throws NameNotFoundException { 2265 return getResourcesForApplication( 2266 getApplicationInfo(appPackageName, 0)); 2267 } 2268 2269 int mCachedSafeMode = -1; 2270 @Override public boolean isSafeMode() { 2271 try { 2272 if (mCachedSafeMode < 0) { 2273 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0; 2274 } 2275 return mCachedSafeMode != 0; 2276 } catch (RemoteException e) { 2277 throw new RuntimeException("Package manager has died", e); 2278 } 2279 } 2280 2281 static void configurationChanged() { 2282 synchronized (sSync) { 2283 sIconCache.clear(); 2284 sStringCache.clear(); 2285 } 2286 } 2287 2288 ApplicationPackageManager(ContextImpl context, 2289 IPackageManager pm) { 2290 mContext = context; 2291 mPM = pm; 2292 } 2293 2294 private Drawable getCachedIcon(ResourceName name) { 2295 synchronized (sSync) { 2296 WeakReference<Drawable> wr = sIconCache.get(name); 2297 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for " 2298 + name + ": " + wr); 2299 if (wr != null) { // we have the activity 2300 Drawable dr = wr.get(); 2301 if (dr != null) { 2302 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for " 2303 + name + ": " + dr); 2304 return dr; 2305 } 2306 // our entry has been purged 2307 sIconCache.remove(name); 2308 } 2309 } 2310 return null; 2311 } 2312 2313 private void putCachedIcon(ResourceName name, Drawable dr) { 2314 synchronized (sSync) { 2315 sIconCache.put(name, new WeakReference<Drawable>(dr)); 2316 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for " 2317 + name + ": " + dr); 2318 } 2319 } 2320 2321 static final void handlePackageBroadcast(int cmd, String[] pkgList, 2322 boolean hasPkgInfo) { 2323 boolean immediateGc = false; 2324 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) { 2325 immediateGc = true; 2326 } 2327 if (pkgList != null && (pkgList.length > 0)) { 2328 boolean needCleanup = false; 2329 for (String ssp : pkgList) { 2330 synchronized (sSync) { 2331 if (sIconCache.size() > 0) { 2332 Iterator<ResourceName> it = sIconCache.keySet().iterator(); 2333 while (it.hasNext()) { 2334 ResourceName nm = it.next(); 2335 if (nm.packageName.equals(ssp)) { 2336 //Log.i(TAG, "Removing cached drawable for " + nm); 2337 it.remove(); 2338 needCleanup = true; 2339 } 2340 } 2341 } 2342 if (sStringCache.size() > 0) { 2343 Iterator<ResourceName> it = sStringCache.keySet().iterator(); 2344 while (it.hasNext()) { 2345 ResourceName nm = it.next(); 2346 if (nm.packageName.equals(ssp)) { 2347 //Log.i(TAG, "Removing cached string for " + nm); 2348 it.remove(); 2349 needCleanup = true; 2350 } 2351 } 2352 } 2353 } 2354 } 2355 if (needCleanup || hasPkgInfo) { 2356 if (immediateGc) { 2357 // Schedule an immediate gc. 2358 Runtime.getRuntime().gc(); 2359 } else { 2360 ActivityThread.currentActivityThread().scheduleGcIdler(); 2361 } 2362 } 2363 } 2364 } 2365 2366 private static final class ResourceName { 2367 final String packageName; 2368 final int iconId; 2369 2370 ResourceName(String _packageName, int _iconId) { 2371 packageName = _packageName; 2372 iconId = _iconId; 2373 } 2374 2375 ResourceName(ApplicationInfo aInfo, int _iconId) { 2376 this(aInfo.packageName, _iconId); 2377 } 2378 2379 ResourceName(ComponentInfo cInfo, int _iconId) { 2380 this(cInfo.applicationInfo.packageName, _iconId); 2381 } 2382 2383 ResourceName(ResolveInfo rInfo, int _iconId) { 2384 this(rInfo.activityInfo.applicationInfo.packageName, _iconId); 2385 } 2386 2387 @Override 2388 public boolean equals(Object o) { 2389 if (this == o) return true; 2390 if (o == null || getClass() != o.getClass()) return false; 2391 2392 ResourceName that = (ResourceName) o; 2393 2394 if (iconId != that.iconId) return false; 2395 return !(packageName != null ? 2396 !packageName.equals(that.packageName) : that.packageName != null); 2397 2398 } 2399 2400 @Override 2401 public int hashCode() { 2402 int result; 2403 result = packageName.hashCode(); 2404 result = 31 * result + iconId; 2405 return result; 2406 } 2407 2408 @Override 2409 public String toString() { 2410 return "{ResourceName " + packageName + " / " + iconId + "}"; 2411 } 2412 } 2413 2414 private CharSequence getCachedString(ResourceName name) { 2415 synchronized (sSync) { 2416 WeakReference<CharSequence> wr = sStringCache.get(name); 2417 if (wr != null) { // we have the activity 2418 CharSequence cs = wr.get(); 2419 if (cs != null) { 2420 return cs; 2421 } 2422 // our entry has been purged 2423 sStringCache.remove(name); 2424 } 2425 } 2426 return null; 2427 } 2428 2429 private void putCachedString(ResourceName name, CharSequence cs) { 2430 synchronized (sSync) { 2431 sStringCache.put(name, new WeakReference<CharSequence>(cs)); 2432 } 2433 } 2434 2435 @Override 2436 public CharSequence getText(String packageName, int resid, 2437 ApplicationInfo appInfo) { 2438 ResourceName name = new ResourceName(packageName, resid); 2439 CharSequence text = getCachedString(name); 2440 if (text != null) { 2441 return text; 2442 } 2443 if (appInfo == null) { 2444 try { 2445 appInfo = getApplicationInfo(packageName, 0); 2446 } catch (NameNotFoundException e) { 2447 return null; 2448 } 2449 } 2450 try { 2451 Resources r = getResourcesForApplication(appInfo); 2452 text = r.getText(resid); 2453 putCachedString(name, text); 2454 return text; 2455 } catch (NameNotFoundException e) { 2456 Log.w("PackageManager", "Failure retrieving resources for" 2457 + appInfo.packageName); 2458 } catch (RuntimeException e) { 2459 // If an exception was thrown, fall through to return 2460 // default icon. 2461 Log.w("PackageManager", "Failure retrieving text 0x" 2462 + Integer.toHexString(resid) + " in package " 2463 + packageName, e); 2464 } 2465 return null; 2466 } 2467 2468 @Override 2469 public XmlResourceParser getXml(String packageName, int resid, 2470 ApplicationInfo appInfo) { 2471 if (appInfo == null) { 2472 try { 2473 appInfo = getApplicationInfo(packageName, 0); 2474 } catch (NameNotFoundException e) { 2475 return null; 2476 } 2477 } 2478 try { 2479 Resources r = getResourcesForApplication(appInfo); 2480 return r.getXml(resid); 2481 } catch (RuntimeException e) { 2482 // If an exception was thrown, fall through to return 2483 // default icon. 2484 Log.w("PackageManager", "Failure retrieving xml 0x" 2485 + Integer.toHexString(resid) + " in package " 2486 + packageName, e); 2487 } catch (NameNotFoundException e) { 2488 Log.w("PackageManager", "Failure retrieving resources for" 2489 + appInfo.packageName); 2490 } 2491 return null; 2492 } 2493 2494 @Override 2495 public CharSequence getApplicationLabel(ApplicationInfo info) { 2496 return info.loadLabel(this); 2497 } 2498 2499 @Override 2500 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, 2501 String installerPackageName) { 2502 try { 2503 mPM.installPackage(packageURI, observer, flags, installerPackageName); 2504 } catch (RemoteException e) { 2505 // Should never happen! 2506 } 2507 } 2508 2509 @Override 2510 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) { 2511 try { 2512 mPM.movePackage(packageName, observer, flags); 2513 } catch (RemoteException e) { 2514 // Should never happen! 2515 } 2516 } 2517 2518 @Override 2519 public String getInstallerPackageName(String packageName) { 2520 try { 2521 return mPM.getInstallerPackageName(packageName); 2522 } catch (RemoteException e) { 2523 // Should never happen! 2524 } 2525 return null; 2526 } 2527 2528 @Override 2529 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { 2530 try { 2531 mPM.deletePackage(packageName, observer, flags); 2532 } catch (RemoteException e) { 2533 // Should never happen! 2534 } 2535 } 2536 @Override 2537 public void clearApplicationUserData(String packageName, 2538 IPackageDataObserver observer) { 2539 try { 2540 mPM.clearApplicationUserData(packageName, observer); 2541 } catch (RemoteException e) { 2542 // Should never happen! 2543 } 2544 } 2545 @Override 2546 public void deleteApplicationCacheFiles(String packageName, 2547 IPackageDataObserver observer) { 2548 try { 2549 mPM.deleteApplicationCacheFiles(packageName, observer); 2550 } catch (RemoteException e) { 2551 // Should never happen! 2552 } 2553 } 2554 @Override 2555 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) { 2556 try { 2557 mPM.freeStorageAndNotify(idealStorageSize, observer); 2558 } catch (RemoteException e) { 2559 // Should never happen! 2560 } 2561 } 2562 2563 @Override 2564 public void freeStorage(long freeStorageSize, IntentSender pi) { 2565 try { 2566 mPM.freeStorage(freeStorageSize, pi); 2567 } catch (RemoteException e) { 2568 // Should never happen! 2569 } 2570 } 2571 2572 @Override 2573 public void getPackageSizeInfo(String packageName, 2574 IPackageStatsObserver observer) { 2575 try { 2576 mPM.getPackageSizeInfo(packageName, observer); 2577 } catch (RemoteException e) { 2578 // Should never happen! 2579 } 2580 } 2581 @Override 2582 public void addPackageToPreferred(String packageName) { 2583 try { 2584 mPM.addPackageToPreferred(packageName); 2585 } catch (RemoteException e) { 2586 // Should never happen! 2587 } 2588 } 2589 2590 @Override 2591 public void removePackageFromPreferred(String packageName) { 2592 try { 2593 mPM.removePackageFromPreferred(packageName); 2594 } catch (RemoteException e) { 2595 // Should never happen! 2596 } 2597 } 2598 2599 @Override 2600 public List<PackageInfo> getPreferredPackages(int flags) { 2601 try { 2602 return mPM.getPreferredPackages(flags); 2603 } catch (RemoteException e) { 2604 // Should never happen! 2605 } 2606 return new ArrayList<PackageInfo>(); 2607 } 2608 2609 @Override 2610 public void addPreferredActivity(IntentFilter filter, 2611 int match, ComponentName[] set, ComponentName activity) { 2612 try { 2613 mPM.addPreferredActivity(filter, match, set, activity); 2614 } catch (RemoteException e) { 2615 // Should never happen! 2616 } 2617 } 2618 2619 @Override 2620 public void replacePreferredActivity(IntentFilter filter, 2621 int match, ComponentName[] set, ComponentName activity) { 2622 try { 2623 mPM.replacePreferredActivity(filter, match, set, activity); 2624 } catch (RemoteException e) { 2625 // Should never happen! 2626 } 2627 } 2628 2629 @Override 2630 public void clearPackagePreferredActivities(String packageName) { 2631 try { 2632 mPM.clearPackagePreferredActivities(packageName); 2633 } catch (RemoteException e) { 2634 // Should never happen! 2635 } 2636 } 2637 2638 @Override 2639 public int getPreferredActivities(List<IntentFilter> outFilters, 2640 List<ComponentName> outActivities, String packageName) { 2641 try { 2642 return mPM.getPreferredActivities(outFilters, outActivities, packageName); 2643 } catch (RemoteException e) { 2644 // Should never happen! 2645 } 2646 return 0; 2647 } 2648 2649 @Override 2650 public void setComponentEnabledSetting(ComponentName componentName, 2651 int newState, int flags) { 2652 try { 2653 mPM.setComponentEnabledSetting(componentName, newState, flags); 2654 } catch (RemoteException e) { 2655 // Should never happen! 2656 } 2657 } 2658 2659 @Override 2660 public int getComponentEnabledSetting(ComponentName componentName) { 2661 try { 2662 return mPM.getComponentEnabledSetting(componentName); 2663 } catch (RemoteException e) { 2664 // Should never happen! 2665 } 2666 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2667 } 2668 2669 @Override 2670 public void setApplicationEnabledSetting(String packageName, 2671 int newState, int flags) { 2672 try { 2673 mPM.setApplicationEnabledSetting(packageName, newState, flags); 2674 } catch (RemoteException e) { 2675 // Should never happen! 2676 } 2677 } 2678 2679 @Override 2680 public int getApplicationEnabledSetting(String packageName) { 2681 try { 2682 return mPM.getApplicationEnabledSetting(packageName); 2683 } catch (RemoteException e) { 2684 // Should never happen! 2685 } 2686 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 2687 } 2688 2689 @Override 2690 public void setPackageObbPath(String packageName, String path) { 2691 try { 2692 mPM.setPackageObbPath(packageName, path); 2693 } catch (RemoteException e) { 2694 // Should never happen! 2695 } 2696 } 2697 2698 private final ContextImpl mContext; 2699 private final IPackageManager mPM; 2700 2701 private static final Object sSync = new Object(); 2702 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache 2703 = new HashMap<ResourceName, WeakReference<Drawable> >(); 2704 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache 2705 = new HashMap<ResourceName, WeakReference<CharSequence> >(); 2706 } 2707 2708 // ---------------------------------------------------------------------- 2709 // ---------------------------------------------------------------------- 2710 // ---------------------------------------------------------------------- 2711 2712 private static final class SharedPreferencesImpl implements SharedPreferences { 2713 2714 // Lock ordering rules: 2715 // - acquire SharedPreferencesImpl.this before EditorImpl.this 2716 // - acquire mWritingToDiskLock before EditorImpl.this 2717 2718 private final File mFile; 2719 private final File mBackupFile; 2720 private final int mMode; 2721 2722 private Map<String, Object> mMap; // guarded by 'this' 2723 private long mTimestamp; // guarded by 'this' 2724 private int mDiskWritesInFlight = 0; // guarded by 'this' 2725 private boolean mLoaded = false; // guarded by 'this' 2726 2727 private final Object mWritingToDiskLock = new Object(); 2728 private static final Object mContent = new Object(); 2729 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners; 2730 2731 SharedPreferencesImpl( 2732 File file, int mode, Map initialContents) { 2733 mFile = file; 2734 mBackupFile = makeBackupFile(file); 2735 mMode = mode; 2736 mLoaded = initialContents != null; 2737 mMap = initialContents != null ? initialContents : new HashMap<String, Object>(); 2738 FileStatus stat = new FileStatus(); 2739 if (FileUtils.getFileStatus(file.getPath(), stat)) { 2740 mTimestamp = stat.mtime; 2741 } 2742 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>(); 2743 } 2744 2745 // Has this SharedPreferences ever had values assigned to it? 2746 boolean isLoaded() { 2747 synchronized (this) { 2748 return mLoaded; 2749 } 2750 } 2751 2752 // Has the file changed out from under us? i.e. writes that 2753 // we didn't instigate. 2754 public boolean hasFileChangedUnexpectedly() { 2755 synchronized (this) { 2756 if (mDiskWritesInFlight > 0) { 2757 // If we know we caused it, it's not unexpected. 2758 Log.d(TAG, "disk write in flight, not unexpected."); 2759 return false; 2760 } 2761 } 2762 FileStatus stat = new FileStatus(); 2763 if (!FileUtils.getFileStatus(mFile.getPath(), stat)) { 2764 return true; 2765 } 2766 synchronized (this) { 2767 return mTimestamp != stat.mtime; 2768 } 2769 } 2770 2771 public void replace(Map newContents) { 2772 synchronized (this) { 2773 mLoaded = true; 2774 if (newContents != null) { 2775 mMap = newContents; 2776 } 2777 } 2778 } 2779 2780 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 2781 synchronized(this) { 2782 mListeners.put(listener, mContent); 2783 } 2784 } 2785 2786 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { 2787 synchronized(this) { 2788 mListeners.remove(listener); 2789 } 2790 } 2791 2792 public Map<String, ?> getAll() { 2793 synchronized(this) { 2794 //noinspection unchecked 2795 return new HashMap<String, Object>(mMap); 2796 } 2797 } 2798 2799 public String getString(String key, String defValue) { 2800 synchronized (this) { 2801 String v = (String)mMap.get(key); 2802 return v != null ? v : defValue; 2803 } 2804 } 2805 2806 public int getInt(String key, int defValue) { 2807 synchronized (this) { 2808 Integer v = (Integer)mMap.get(key); 2809 return v != null ? v : defValue; 2810 } 2811 } 2812 public long getLong(String key, long defValue) { 2813 synchronized (this) { 2814 Long v = (Long)mMap.get(key); 2815 return v != null ? v : defValue; 2816 } 2817 } 2818 public float getFloat(String key, float defValue) { 2819 synchronized (this) { 2820 Float v = (Float)mMap.get(key); 2821 return v != null ? v : defValue; 2822 } 2823 } 2824 public boolean getBoolean(String key, boolean defValue) { 2825 synchronized (this) { 2826 Boolean v = (Boolean)mMap.get(key); 2827 return v != null ? v : defValue; 2828 } 2829 } 2830 2831 public boolean contains(String key) { 2832 synchronized (this) { 2833 return mMap.containsKey(key); 2834 } 2835 } 2836 2837 public Editor edit() { 2838 return new EditorImpl(); 2839 } 2840 2841 // Return value from EditorImpl#commitToMemory() 2842 private static class MemoryCommitResult { 2843 public boolean changesMade; // any keys different? 2844 public List<String> keysModified; // may be null 2845 public Set<OnSharedPreferenceChangeListener> listeners; // may be null 2846 public Map<?, ?> mapToWriteToDisk; 2847 public final CountDownLatch writtenToDiskLatch = new CountDownLatch(1); 2848 public volatile boolean writeToDiskResult = false; 2849 2850 public void setDiskWriteResult(boolean result) { 2851 writeToDiskResult = result; 2852 writtenToDiskLatch.countDown(); 2853 } 2854 } 2855 2856 public final class EditorImpl implements Editor { 2857 private final Map<String, Object> mModified = Maps.newHashMap(); 2858 private boolean mClear = false; 2859 2860 public Editor putString(String key, String value) { 2861 synchronized (this) { 2862 mModified.put(key, value); 2863 return this; 2864 } 2865 } 2866 public Editor putInt(String key, int value) { 2867 synchronized (this) { 2868 mModified.put(key, value); 2869 return this; 2870 } 2871 } 2872 public Editor putLong(String key, long value) { 2873 synchronized (this) { 2874 mModified.put(key, value); 2875 return this; 2876 } 2877 } 2878 public Editor putFloat(String key, float value) { 2879 synchronized (this) { 2880 mModified.put(key, value); 2881 return this; 2882 } 2883 } 2884 public Editor putBoolean(String key, boolean value) { 2885 synchronized (this) { 2886 mModified.put(key, value); 2887 return this; 2888 } 2889 } 2890 2891 public Editor remove(String key) { 2892 synchronized (this) { 2893 mModified.put(key, this); 2894 return this; 2895 } 2896 } 2897 2898 public Editor clear() { 2899 synchronized (this) { 2900 mClear = true; 2901 return this; 2902 } 2903 } 2904 2905 public void apply() { 2906 final MemoryCommitResult mcr = commitToMemory(); 2907 final Runnable awaitCommit = new Runnable() { 2908 public void run() { 2909 try { 2910 mcr.writtenToDiskLatch.await(); 2911 } catch (InterruptedException ignored) { 2912 } 2913 } 2914 }; 2915 2916 QueuedWork.add(awaitCommit); 2917 2918 Runnable postWriteRunnable = new Runnable() { 2919 public void run() { 2920 awaitCommit.run(); 2921 QueuedWork.remove(awaitCommit); 2922 } 2923 }; 2924 2925 SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable); 2926 2927 // Okay to notify the listeners before it's hit disk 2928 // because the listeners should always get the same 2929 // SharedPreferences instance back, which has the 2930 // changes reflected in memory. 2931 notifyListeners(mcr); 2932 } 2933 2934 // Returns true if any changes were made 2935 private MemoryCommitResult commitToMemory() { 2936 MemoryCommitResult mcr = new MemoryCommitResult(); 2937 synchronized (SharedPreferencesImpl.this) { 2938 // We optimistically don't make a deep copy until 2939 // a memory commit comes in when we're already 2940 // writing to disk. 2941 if (mDiskWritesInFlight > 0) { 2942 // We can't modify our mMap as a currently 2943 // in-flight write owns it. Clone it before 2944 // modifying it. 2945 // noinspection unchecked 2946 mMap = new HashMap<String, Object>(mMap); 2947 } 2948 mcr.mapToWriteToDisk = mMap; 2949 mDiskWritesInFlight++; 2950 2951 boolean hasListeners = mListeners.size() > 0; 2952 if (hasListeners) { 2953 mcr.keysModified = new ArrayList<String>(); 2954 mcr.listeners = 2955 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet()); 2956 } 2957 2958 synchronized (this) { 2959 if (mClear) { 2960 if (!mMap.isEmpty()) { 2961 mcr.changesMade = true; 2962 mMap.clear(); 2963 } 2964 mClear = false; 2965 } 2966 2967 for (Entry<String, Object> e : mModified.entrySet()) { 2968 String k = e.getKey(); 2969 Object v = e.getValue(); 2970 if (v == this) { // magic value for a removal mutation 2971 if (!mMap.containsKey(k)) { 2972 continue; 2973 } 2974 mMap.remove(k); 2975 } else { 2976 boolean isSame = false; 2977 if (mMap.containsKey(k)) { 2978 Object existingValue = mMap.get(k); 2979 if (existingValue != null && existingValue.equals(v)) { 2980 continue; 2981 } 2982 } 2983 mMap.put(k, v); 2984 } 2985 2986 mcr.changesMade = true; 2987 if (hasListeners) { 2988 mcr.keysModified.add(k); 2989 } 2990 } 2991 2992 mModified.clear(); 2993 } 2994 } 2995 return mcr; 2996 } 2997 2998 public boolean commit() { 2999 MemoryCommitResult mcr = commitToMemory(); 3000 SharedPreferencesImpl.this.enqueueDiskWrite( 3001 mcr, null /* sync write on this thread okay */); 3002 try { 3003 mcr.writtenToDiskLatch.await(); 3004 } catch (InterruptedException e) { 3005 return false; 3006 } 3007 notifyListeners(mcr); 3008 return mcr.writeToDiskResult; 3009 } 3010 3011 private void notifyListeners(final MemoryCommitResult mcr) { 3012 if (mcr.listeners == null || mcr.keysModified == null || 3013 mcr.keysModified.size() == 0) { 3014 return; 3015 } 3016 if (Looper.myLooper() == Looper.getMainLooper()) { 3017 for (int i = mcr.keysModified.size() - 1; i >= 0; i--) { 3018 final String key = mcr.keysModified.get(i); 3019 for (OnSharedPreferenceChangeListener listener : mcr.listeners) { 3020 if (listener != null) { 3021 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key); 3022 } 3023 } 3024 } 3025 } else { 3026 // Run this function on the main thread. 3027 ActivityThread.sMainThreadHandler.post(new Runnable() { 3028 public void run() { 3029 notifyListeners(mcr); 3030 } 3031 }); 3032 } 3033 } 3034 } 3035 3036 /** 3037 * Enqueue an already-committed-to-memory result to be written 3038 * to disk. 3039 * 3040 * They will be written to disk one-at-a-time in the order 3041 * that they're enqueued. 3042 * 3043 * @param postWriteRunnable if non-null, we're being called 3044 * from apply() and this is the runnable to run after 3045 * the write proceeds. if null (from a regular commit()), 3046 * then we're allowed to do this disk write on the main 3047 * thread (which in addition to reducing allocations and 3048 * creating a background thread, this has the advantage that 3049 * we catch them in userdebug StrictMode reports to convert 3050 * them where possible to apply() ...) 3051 */ 3052 private void enqueueDiskWrite(final MemoryCommitResult mcr, 3053 final Runnable postWriteRunnable) { 3054 final Runnable writeToDiskRunnable = new Runnable() { 3055 public void run() { 3056 synchronized (mWritingToDiskLock) { 3057 writeToFile(mcr); 3058 } 3059 synchronized (SharedPreferencesImpl.this) { 3060 mDiskWritesInFlight--; 3061 } 3062 if (postWriteRunnable != null) { 3063 postWriteRunnable.run(); 3064 } 3065 } 3066 }; 3067 3068 final boolean isFromSyncCommit = (postWriteRunnable == null); 3069 3070 // Typical #commit() path with fewer allocations, doing a write on 3071 // the current thread. 3072 if (isFromSyncCommit) { 3073 boolean wasEmpty = false; 3074 synchronized (SharedPreferencesImpl.this) { 3075 wasEmpty = mDiskWritesInFlight == 1; 3076 } 3077 if (wasEmpty) { 3078 writeToDiskRunnable.run(); 3079 return; 3080 } 3081 } 3082 3083 QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable); 3084 } 3085 3086 private static FileOutputStream createFileOutputStream(File file) { 3087 FileOutputStream str = null; 3088 try { 3089 str = new FileOutputStream(file); 3090 } catch (FileNotFoundException e) { 3091 File parent = file.getParentFile(); 3092 if (!parent.mkdir()) { 3093 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file); 3094 return null; 3095 } 3096 FileUtils.setPermissions( 3097 parent.getPath(), 3098 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, 3099 -1, -1); 3100 try { 3101 str = new FileOutputStream(file); 3102 } catch (FileNotFoundException e2) { 3103 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2); 3104 } 3105 } 3106 return str; 3107 } 3108 3109 // Note: must hold mWritingToDiskLock 3110 private void writeToFile(MemoryCommitResult mcr) { 3111 // Rename the current file so it may be used as a backup during the next read 3112 if (mFile.exists()) { 3113 if (!mcr.changesMade) { 3114 // If the file already exists, but no changes were 3115 // made to the underlying map, it's wasteful to 3116 // re-write the file. Return as if we wrote it 3117 // out. 3118 mcr.setDiskWriteResult(true); 3119 return; 3120 } 3121 if (!mBackupFile.exists()) { 3122 if (!mFile.renameTo(mBackupFile)) { 3123 Log.e(TAG, "Couldn't rename file " + mFile 3124 + " to backup file " + mBackupFile); 3125 mcr.setDiskWriteResult(false); 3126 return; 3127 } 3128 } else { 3129 mFile.delete(); 3130 } 3131 } 3132 3133 // Attempt to write the file, delete the backup and return true as atomically as 3134 // possible. If any exception occurs, delete the new file; next time we will restore 3135 // from the backup. 3136 try { 3137 FileOutputStream str = createFileOutputStream(mFile); 3138 if (str == null) { 3139 mcr.setDiskWriteResult(false); 3140 return; 3141 } 3142 XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str); 3143 str.close(); 3144 setFilePermissionsFromMode(mFile.getPath(), mMode, 0); 3145 FileStatus stat = new FileStatus(); 3146 if (FileUtils.getFileStatus(mFile.getPath(), stat)) { 3147 synchronized (this) { 3148 mTimestamp = stat.mtime; 3149 } 3150 } 3151 // Writing was successful, delete the backup file if there is one. 3152 mBackupFile.delete(); 3153 mcr.setDiskWriteResult(true); 3154 return; 3155 } catch (XmlPullParserException e) { 3156 Log.w(TAG, "writeToFile: Got exception:", e); 3157 } catch (IOException e) { 3158 Log.w(TAG, "writeToFile: Got exception:", e); 3159 } 3160 // Clean up an unsuccessfully written file 3161 if (mFile.exists()) { 3162 if (!mFile.delete()) { 3163 Log.e(TAG, "Couldn't clean up partially-written file " + mFile); 3164 } 3165 } 3166 mcr.setDiskWriteResult(false); 3167 } 3168 } 3169} 3170