blob: 10ebd607ec4da09036fb28484db6f33de9effbfa [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080020import com.android.internal.util.XmlUtils;
svetoslavganov75986cf2009-05-14 22:28:01 -070021import com.google.android.collect.Maps;
22
23import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.ContextWrapper;
30import android.content.IContentProvider;
31import android.content.Intent;
32import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070033import android.content.IIntentReceiver;
34import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.ReceiverCallNotAllowedException;
36import android.content.ServiceConnection;
37import android.content.SharedPreferences;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070041import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.pm.IPackageDataObserver;
43import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080045import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070047import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.content.pm.InstrumentationInfo;
49import android.content.pm.PackageInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
53import android.content.pm.ProviderInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.ServiceInfo;
56import android.content.res.AssetManager;
57import android.content.res.Resources;
58import android.content.res.XmlResourceParser;
Vasu Nori74f170f2010-06-01 18:06:18 -070059import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.database.sqlite.SQLiteDatabase;
61import android.database.sqlite.SQLiteDatabase.CursorFactory;
62import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.graphics.drawable.Drawable;
64import android.hardware.SensorManager;
Bai Taoa58a8752010-07-13 15:32:16 +080065import android.location.CountryDetector;
66import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.location.ILocationManager;
68import android.location.LocationManager;
69import android.media.AudioManager;
70import android.net.ConnectivityManager;
71import android.net.IConnectivityManager;
Steve Howarda2709362010-07-02 17:12:48 -070072import android.net.DownloadManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070073import android.net.ThrottleManager;
74import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.net.Uri;
76import android.net.wifi.IWifiManager;
77import android.net.wifi.WifiManager;
78import android.os.Binder;
79import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080080import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080081import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.FileUtils;
83import android.os.Handler;
84import android.os.IBinder;
85import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.PowerManager;
88import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070089import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.ServiceManager;
91import android.os.Vibrator;
92import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080093import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.telephony.TelephonyManager;
95import android.text.ClipboardManager;
96import android.util.AndroidRuntimeException;
97import android.util.Log;
98import android.view.ContextThemeWrapper;
99import android.view.LayoutInflater;
100import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -0700101import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -0700103import android.accounts.AccountManager;
104import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800105import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
Dan Egnorf18a01c2009-11-12 11:32:50 -0800107import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import java.io.File;
110import java.io.FileInputStream;
111import java.io.FileNotFoundException;
112import java.io.FileOutputStream;
113import java.io.IOException;
114import java.io.InputStream;
115import java.lang.ref.WeakReference;
116import java.util.ArrayList;
117import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700118import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import java.util.Iterator;
120import java.util.List;
121import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700122import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700123import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.util.Map.Entry;
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126class ReceiverRestrictedContext extends ContextWrapper {
127 ReceiverRestrictedContext(Context base) {
128 super(base);
129 }
130
131 @Override
132 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
133 return registerReceiver(receiver, filter, null, null);
134 }
135
136 @Override
137 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
138 String broadcastPermission, Handler scheduler) {
139 throw new ReceiverCallNotAllowedException(
140 "IntentReceiver components are not allowed to register to receive intents");
141 //ex.fillInStackTrace();
142 //Log.e("IntentReceiver", ex.getMessage(), ex);
143 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
144 // scheduler);
145 }
146
147 @Override
148 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
149 throw new ReceiverCallNotAllowedException(
150 "IntentReceiver components are not allowed to bind to services");
151 //ex.fillInStackTrace();
152 //Log.e("IntentReceiver", ex.getMessage(), ex);
153 //return mContext.bindService(service, interfaceName, conn, flags);
154 }
155}
156
157/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800158 * Common implementation of Context API, which provides the base
159 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800161class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700163 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 private final static boolean DEBUG_ICONS = false;
165
166 private static final Object sSync = new Object();
167 private static AlarmManager sAlarmManager;
168 private static PowerManager sPowerManager;
169 private static ConnectivityManager sConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700170 private static ThrottleManager sThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 private static WifiManager sWifiManager;
172 private static LocationManager sLocationManager;
Bai Taoa58a8752010-07-13 15:32:16 +0800173 private static CountryDetector sCountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
175 new HashMap<File, SharedPreferencesImpl>();
176
177 private AudioManager mAudioManager;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700178 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 private Resources mResources;
180 /*package*/ ActivityThread mMainThread;
181 private Context mOuterContext;
182 private IBinder mActivityToken = null;
183 private ApplicationContentResolver mContentResolver;
184 private int mThemeResource = 0;
185 private Resources.Theme mTheme = null;
186 private PackageManager mPackageManager;
187 private NotificationManager mNotificationManager = null;
188 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700189 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 private Context mReceiverRestrictedContext = null;
191 private SearchManager mSearchManager = null;
192 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800193 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 private Vibrator mVibrator = null;
195 private LayoutInflater mLayoutInflater = null;
196 private StatusBarManager mStatusBarManager = null;
197 private TelephonyManager mTelephonyManager = null;
198 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700199 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700200 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800201 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800202 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800203 private UiModeManager mUiModeManager = null;
Steve Howarda2709362010-07-02 17:12:48 -0700204 private DownloadManager mDownloadManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205
206 private final Object mSync = new Object();
207
208 private File mDatabasesDir;
209 private File mPreferencesDir;
210 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800212 private File mExternalFilesDir;
213 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 private static long sInstanceCount = 0;
216
217 private static final String[] EMPTY_FILE_LIST = {};
218
Carl Shapiro82fe5642010-02-24 00:14:23 -0800219 // For debug only
220 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 @Override
222 protected void finalize() throws Throwable {
223 super.finalize();
224 --sInstanceCount;
225 }
Carl Shapiro82fe5642010-02-24 00:14:23 -0800226 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
228 public static long getInstanceCount() {
229 return sInstanceCount;
230 }
231
232 @Override
233 public AssetManager getAssets() {
234 return mResources.getAssets();
235 }
236
237 @Override
238 public Resources getResources() {
239 return mResources;
240 }
241
242 @Override
243 public PackageManager getPackageManager() {
244 if (mPackageManager != null) {
245 return mPackageManager;
246 }
247
248 IPackageManager pm = ActivityThread.getPackageManager();
249 if (pm != null) {
250 // Doesn't matter if we make more than one instance.
251 return (mPackageManager = new ApplicationPackageManager(this, pm));
252 }
253
254 return null;
255 }
256
257 @Override
258 public ContentResolver getContentResolver() {
259 return mContentResolver;
260 }
261
262 @Override
263 public Looper getMainLooper() {
264 return mMainThread.getLooper();
265 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 @Override
268 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700269 return (mPackageInfo != null) ?
270 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 @Override
274 public void setTheme(int resid) {
275 mThemeResource = resid;
276 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 @Override
279 public Resources.Theme getTheme() {
280 if (mTheme == null) {
281 if (mThemeResource == 0) {
282 mThemeResource = com.android.internal.R.style.Theme;
283 }
284 mTheme = mResources.newTheme();
285 mTheme.applyStyle(mThemeResource, true);
286 }
287 return mTheme;
288 }
289
290 @Override
291 public ClassLoader getClassLoader() {
292 return mPackageInfo != null ?
293 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
294 }
295
296 @Override
297 public String getPackageName() {
298 if (mPackageInfo != null) {
299 return mPackageInfo.getPackageName();
300 }
301 throw new RuntimeException("Not supported in system context");
302 }
303
304 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700305 public ApplicationInfo getApplicationInfo() {
306 if (mPackageInfo != null) {
307 return mPackageInfo.getApplicationInfo();
308 }
309 throw new RuntimeException("Not supported in system context");
310 }
311
312 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 public String getPackageResourcePath() {
314 if (mPackageInfo != null) {
315 return mPackageInfo.getResDir();
316 }
317 throw new RuntimeException("Not supported in system context");
318 }
319
320 @Override
321 public String getPackageCodePath() {
322 if (mPackageInfo != null) {
323 return mPackageInfo.getAppDir();
324 }
325 throw new RuntimeException("Not supported in system context");
326 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 private static File makeBackupFile(File prefsFile) {
329 return new File(prefsFile.getPath() + ".bak");
330 }
331
Joe Onorato23ecae32009-06-10 17:07:15 -0700332 public File getSharedPrefsFile(String name) {
333 return makeFilename(getPreferencesDir(), name + ".xml");
334 }
335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 @Override
337 public SharedPreferences getSharedPreferences(String name, int mode) {
338 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700339 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 synchronized (sSharedPrefs) {
341 sp = sSharedPrefs.get(f);
342 if (sp != null && !sp.hasFileChanged()) {
343 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
344 return sp;
345 }
346 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 FileInputStream str = null;
349 File backup = makeBackupFile(f);
350 if (backup.exists()) {
351 f.delete();
352 backup.renameTo(f);
353 }
354
355 // Debugging
356 if (f.exists() && !f.canRead()) {
357 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
358 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200359
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 Map map = null;
361 if (f.exists() && f.canRead()) {
362 try {
363 str = new FileInputStream(f);
364 map = XmlUtils.readMapXml(str);
365 str.close();
366 } catch (org.xmlpull.v1.XmlPullParserException e) {
367 Log.w(TAG, "getSharedPreferences", e);
368 } catch (FileNotFoundException e) {
369 Log.w(TAG, "getSharedPreferences", e);
370 } catch (IOException e) {
371 Log.w(TAG, "getSharedPreferences", e);
372 }
373 }
374
375 synchronized (sSharedPrefs) {
376 if (sp != null) {
377 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
378 sp.replace(map);
379 } else {
380 sp = sSharedPrefs.get(f);
381 if (sp == null) {
382 sp = new SharedPreferencesImpl(f, mode, map);
383 sSharedPrefs.put(f, sp);
384 }
385 }
386 return sp;
387 }
388 }
389
390 private File getPreferencesDir() {
391 synchronized (mSync) {
392 if (mPreferencesDir == null) {
393 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
394 }
395 return mPreferencesDir;
396 }
397 }
398
399 @Override
400 public FileInputStream openFileInput(String name)
401 throws FileNotFoundException {
402 File f = makeFilename(getFilesDir(), name);
403 return new FileInputStream(f);
404 }
405
406 @Override
407 public FileOutputStream openFileOutput(String name, int mode)
408 throws FileNotFoundException {
409 final boolean append = (mode&MODE_APPEND) != 0;
410 File f = makeFilename(getFilesDir(), name);
411 try {
412 FileOutputStream fos = new FileOutputStream(f, append);
413 setFilePermissionsFromMode(f.getPath(), mode, 0);
414 return fos;
415 } catch (FileNotFoundException e) {
416 }
417
418 File parent = f.getParentFile();
419 parent.mkdir();
420 FileUtils.setPermissions(
421 parent.getPath(),
422 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
423 -1, -1);
424 FileOutputStream fos = new FileOutputStream(f, append);
425 setFilePermissionsFromMode(f.getPath(), mode, 0);
426 return fos;
427 }
428
429 @Override
430 public boolean deleteFile(String name) {
431 File f = makeFilename(getFilesDir(), name);
432 return f.delete();
433 }
434
435 @Override
436 public File getFilesDir() {
437 synchronized (mSync) {
438 if (mFilesDir == null) {
439 mFilesDir = new File(getDataDirFile(), "files");
440 }
441 if (!mFilesDir.exists()) {
442 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200443 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 return null;
445 }
446 FileUtils.setPermissions(
447 mFilesDir.getPath(),
448 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
449 -1, -1);
450 }
451 return mFilesDir;
452 }
453 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800456 public File getExternalFilesDir(String type) {
457 synchronized (mSync) {
458 if (mExternalFilesDir == null) {
459 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
460 getPackageName());
461 }
462 if (!mExternalFilesDir.exists()) {
463 try {
464 (new File(Environment.getExternalStorageAndroidDataDir(),
465 ".nomedia")).createNewFile();
466 } catch (IOException e) {
467 }
468 if (!mExternalFilesDir.mkdirs()) {
469 Log.w(TAG, "Unable to create external files directory");
470 return null;
471 }
472 }
473 if (type == null) {
474 return mExternalFilesDir;
475 }
476 File dir = new File(mExternalFilesDir, type);
477 if (!dir.exists()) {
478 if (!dir.mkdirs()) {
479 Log.w(TAG, "Unable to create external media directory " + dir);
480 return null;
481 }
482 }
483 return dir;
484 }
485 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200486
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800487 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 public File getCacheDir() {
489 synchronized (mSync) {
490 if (mCacheDir == null) {
491 mCacheDir = new File(getDataDirFile(), "cache");
492 }
493 if (!mCacheDir.exists()) {
494 if(!mCacheDir.mkdirs()) {
495 Log.w(TAG, "Unable to create cache directory");
496 return null;
497 }
498 FileUtils.setPermissions(
499 mCacheDir.getPath(),
500 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
501 -1, -1);
502 }
503 }
504 return mCacheDir;
505 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200506
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800507 @Override
508 public File getExternalCacheDir() {
509 synchronized (mSync) {
510 if (mExternalCacheDir == null) {
511 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
512 getPackageName());
513 }
514 if (!mExternalCacheDir.exists()) {
515 try {
516 (new File(Environment.getExternalStorageAndroidDataDir(),
517 ".nomedia")).createNewFile();
518 } catch (IOException e) {
519 }
520 if (!mExternalCacheDir.mkdirs()) {
521 Log.w(TAG, "Unable to create external cache directory");
522 return null;
523 }
524 }
525 return mExternalCacheDir;
526 }
527 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200528
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 @Override
530 public File getFileStreamPath(String name) {
531 return makeFilename(getFilesDir(), name);
532 }
533
534 @Override
535 public String[] fileList() {
536 final String[] list = getFilesDir().list();
537 return (list != null) ? list : EMPTY_FILE_LIST;
538 }
539
540 @Override
541 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800542 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
544 setFilePermissionsFromMode(f.getPath(), mode, 0);
545 return db;
546 }
547
548 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700549 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
550 DatabaseErrorHandler errorHandler) {
551 File f = validateFilePath(name, true);
552 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
553 setFilePermissionsFromMode(f.getPath(), mode, 0);
554 return db;
555 }
556
557 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 public boolean deleteDatabase(String name) {
559 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800560 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 return f.delete();
562 } catch (Exception e) {
563 }
564 return false;
565 }
566
567 @Override
568 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800569 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 }
571
572 @Override
573 public String[] databaseList() {
574 final String[] list = getDatabasesDir().list();
575 return (list != null) ? list : EMPTY_FILE_LIST;
576 }
577
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 private File getDatabasesDir() {
580 synchronized (mSync) {
581 if (mDatabasesDir == null) {
582 mDatabasesDir = new File(getDataDirFile(), "databases");
583 }
584 if (mDatabasesDir.getPath().equals("databases")) {
585 mDatabasesDir = new File("/data/system");
586 }
587 return mDatabasesDir;
588 }
589 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 @Override
592 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700593 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
596 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700597 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700598 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 }
600
601 @Override
602 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700603 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
605
606 @Override
607 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700608 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 }
610
611 @Override
612 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700613 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 }
615
616 @Override
617 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700618 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 }
620
621 @Override
622 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700623 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 }
625
626 @Override
627 public void startActivity(Intent intent) {
628 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
629 throw new AndroidRuntimeException(
630 "Calling startActivity() from outside of an Activity "
631 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
632 + " Is this really what you want?");
633 }
634 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700635 getOuterContext(), mMainThread.getApplicationThread(), null,
636 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 }
638
639 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700640 public void startIntentSender(IntentSender intent,
641 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
642 throws IntentSender.SendIntentException {
643 try {
644 String resolvedType = null;
645 if (fillInIntent != null) {
646 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
647 }
648 int result = ActivityManagerNative.getDefault()
649 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
650 fillInIntent, resolvedType, null, null,
651 0, flagsMask, flagsValues);
652 if (result == IActivityManager.START_CANCELED) {
653 throw new IntentSender.SendIntentException();
654 }
655 Instrumentation.checkStartActivityResult(result, null);
656 } catch (RemoteException e) {
657 }
658 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200659
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700660 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 public void sendBroadcast(Intent intent) {
662 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
663 try {
664 ActivityManagerNative.getDefault().broadcastIntent(
665 mMainThread.getApplicationThread(), intent, resolvedType, null,
666 Activity.RESULT_OK, null, null, null, false, false);
667 } catch (RemoteException e) {
668 }
669 }
670
671 @Override
672 public void sendBroadcast(Intent intent, String receiverPermission) {
673 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
674 try {
675 ActivityManagerNative.getDefault().broadcastIntent(
676 mMainThread.getApplicationThread(), intent, resolvedType, null,
677 Activity.RESULT_OK, null, null, receiverPermission, false, false);
678 } catch (RemoteException e) {
679 }
680 }
681
682 @Override
683 public void sendOrderedBroadcast(Intent intent,
684 String receiverPermission) {
685 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
686 try {
687 ActivityManagerNative.getDefault().broadcastIntent(
688 mMainThread.getApplicationThread(), intent, resolvedType, null,
689 Activity.RESULT_OK, null, null, receiverPermission, true, false);
690 } catch (RemoteException e) {
691 }
692 }
693
694 @Override
695 public void sendOrderedBroadcast(Intent intent,
696 String receiverPermission, BroadcastReceiver resultReceiver,
697 Handler scheduler, int initialCode, String initialData,
698 Bundle initialExtras) {
699 IIntentReceiver rd = null;
700 if (resultReceiver != null) {
701 if (mPackageInfo != null) {
702 if (scheduler == null) {
703 scheduler = mMainThread.getHandler();
704 }
705 rd = mPackageInfo.getReceiverDispatcher(
706 resultReceiver, getOuterContext(), scheduler,
707 mMainThread.getInstrumentation(), false);
708 } else {
709 if (scheduler == null) {
710 scheduler = mMainThread.getHandler();
711 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700712 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
714 }
715 }
716 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
717 try {
718 ActivityManagerNative.getDefault().broadcastIntent(
719 mMainThread.getApplicationThread(), intent, resolvedType, rd,
720 initialCode, initialData, initialExtras, receiverPermission,
721 true, false);
722 } catch (RemoteException e) {
723 }
724 }
725
726 @Override
727 public void sendStickyBroadcast(Intent intent) {
728 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
729 try {
730 ActivityManagerNative.getDefault().broadcastIntent(
731 mMainThread.getApplicationThread(), intent, resolvedType, null,
732 Activity.RESULT_OK, null, null, null, false, true);
733 } catch (RemoteException e) {
734 }
735 }
736
737 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700738 public void sendStickyOrderedBroadcast(Intent intent,
739 BroadcastReceiver resultReceiver,
740 Handler scheduler, int initialCode, String initialData,
741 Bundle initialExtras) {
742 IIntentReceiver rd = null;
743 if (resultReceiver != null) {
744 if (mPackageInfo != null) {
745 if (scheduler == null) {
746 scheduler = mMainThread.getHandler();
747 }
748 rd = mPackageInfo.getReceiverDispatcher(
749 resultReceiver, getOuterContext(), scheduler,
750 mMainThread.getInstrumentation(), false);
751 } else {
752 if (scheduler == null) {
753 scheduler = mMainThread.getHandler();
754 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700755 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700756 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
757 }
758 }
759 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
760 try {
761 ActivityManagerNative.getDefault().broadcastIntent(
762 mMainThread.getApplicationThread(), intent, resolvedType, rd,
763 initialCode, initialData, initialExtras, null,
764 true, true);
765 } catch (RemoteException e) {
766 }
767 }
768
769 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 public void removeStickyBroadcast(Intent intent) {
771 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
772 if (resolvedType != null) {
773 intent = new Intent(intent);
774 intent.setDataAndType(intent.getData(), resolvedType);
775 }
776 try {
777 ActivityManagerNative.getDefault().unbroadcastIntent(
778 mMainThread.getApplicationThread(), intent);
779 } catch (RemoteException e) {
780 }
781 }
782
783 @Override
784 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
785 return registerReceiver(receiver, filter, null, null);
786 }
787
788 @Override
789 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
790 String broadcastPermission, Handler scheduler) {
791 return registerReceiverInternal(receiver, filter, broadcastPermission,
792 scheduler, getOuterContext());
793 }
794
795 private Intent registerReceiverInternal(BroadcastReceiver receiver,
796 IntentFilter filter, String broadcastPermission,
797 Handler scheduler, Context context) {
798 IIntentReceiver rd = null;
799 if (receiver != null) {
800 if (mPackageInfo != null && context != null) {
801 if (scheduler == null) {
802 scheduler = mMainThread.getHandler();
803 }
804 rd = mPackageInfo.getReceiverDispatcher(
805 receiver, context, scheduler,
806 mMainThread.getInstrumentation(), true);
807 } else {
808 if (scheduler == null) {
809 scheduler = mMainThread.getHandler();
810 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700811 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700812 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 }
814 }
815 try {
816 return ActivityManagerNative.getDefault().registerReceiver(
817 mMainThread.getApplicationThread(),
818 rd, filter, broadcastPermission);
819 } catch (RemoteException e) {
820 return null;
821 }
822 }
823
824 @Override
825 public void unregisterReceiver(BroadcastReceiver receiver) {
826 if (mPackageInfo != null) {
827 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
828 getOuterContext(), receiver);
829 try {
830 ActivityManagerNative.getDefault().unregisterReceiver(rd);
831 } catch (RemoteException e) {
832 }
833 } else {
834 throw new RuntimeException("Not supported in system context");
835 }
836 }
837
838 @Override
839 public ComponentName startService(Intent service) {
840 try {
841 ComponentName cn = ActivityManagerNative.getDefault().startService(
842 mMainThread.getApplicationThread(), service,
843 service.resolveTypeIfNeeded(getContentResolver()));
844 if (cn != null && cn.getPackageName().equals("!")) {
845 throw new SecurityException(
846 "Not allowed to start service " + service
847 + " without permission " + cn.getClassName());
848 }
849 return cn;
850 } catch (RemoteException e) {
851 return null;
852 }
853 }
854
855 @Override
856 public boolean stopService(Intent service) {
857 try {
858 int res = ActivityManagerNative.getDefault().stopService(
859 mMainThread.getApplicationThread(), service,
860 service.resolveTypeIfNeeded(getContentResolver()));
861 if (res < 0) {
862 throw new SecurityException(
863 "Not allowed to stop service " + service);
864 }
865 return res != 0;
866 } catch (RemoteException e) {
867 return false;
868 }
869 }
870
871 @Override
872 public boolean bindService(Intent service, ServiceConnection conn,
873 int flags) {
874 IServiceConnection sd;
875 if (mPackageInfo != null) {
876 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
877 mMainThread.getHandler(), flags);
878 } else {
879 throw new RuntimeException("Not supported in system context");
880 }
881 try {
882 int res = ActivityManagerNative.getDefault().bindService(
883 mMainThread.getApplicationThread(), getActivityToken(),
884 service, service.resolveTypeIfNeeded(getContentResolver()),
885 sd, flags);
886 if (res < 0) {
887 throw new SecurityException(
888 "Not allowed to bind to service " + service);
889 }
890 return res != 0;
891 } catch (RemoteException e) {
892 return false;
893 }
894 }
895
896 @Override
897 public void unbindService(ServiceConnection conn) {
898 if (mPackageInfo != null) {
899 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
900 getOuterContext(), conn);
901 try {
902 ActivityManagerNative.getDefault().unbindService(sd);
903 } catch (RemoteException e) {
904 }
905 } else {
906 throw new RuntimeException("Not supported in system context");
907 }
908 }
909
910 @Override
911 public boolean startInstrumentation(ComponentName className,
912 String profileFile, Bundle arguments) {
913 try {
914 return ActivityManagerNative.getDefault().startInstrumentation(
915 className, profileFile, 0, arguments, null);
916 } catch (RemoteException e) {
917 // System has crashed, nothing we can do.
918 }
919 return false;
920 }
921
922 @Override
923 public Object getSystemService(String name) {
924 if (WINDOW_SERVICE.equals(name)) {
925 return WindowManagerImpl.getDefault();
926 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
927 synchronized (mSync) {
928 LayoutInflater inflater = mLayoutInflater;
929 if (inflater != null) {
930 return inflater;
931 }
932 mLayoutInflater = inflater =
933 PolicyManager.makeNewLayoutInflater(getOuterContext());
934 return inflater;
935 }
936 } else if (ACTIVITY_SERVICE.equals(name)) {
937 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700938 } else if (INPUT_METHOD_SERVICE.equals(name)) {
939 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 } else if (ALARM_SERVICE.equals(name)) {
941 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700942 } else if (ACCOUNT_SERVICE.equals(name)) {
943 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 } else if (POWER_SERVICE.equals(name)) {
945 return getPowerManager();
946 } else if (CONNECTIVITY_SERVICE.equals(name)) {
947 return getConnectivityManager();
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700948 } else if (THROTTLE_SERVICE.equals(name)) {
949 return getThrottleManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 } else if (WIFI_SERVICE.equals(name)) {
951 return getWifiManager();
952 } else if (NOTIFICATION_SERVICE.equals(name)) {
953 return getNotificationManager();
954 } else if (KEYGUARD_SERVICE.equals(name)) {
955 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700956 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
957 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 } else if (LOCATION_SERVICE.equals(name)) {
959 return getLocationManager();
Bai Taoa58a8752010-07-13 15:32:16 +0800960 } else if (COUNTRY_DETECTOR.equals(name)) {
961 return getCountryDetector();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 } else if (SEARCH_SERVICE.equals(name)) {
963 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700964 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800966 } else if (STORAGE_SERVICE.equals(name)) {
967 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 } else if (VIBRATOR_SERVICE.equals(name)) {
969 return getVibrator();
970 } else if (STATUS_BAR_SERVICE.equals(name)) {
971 synchronized (mSync) {
972 if (mStatusBarManager == null) {
973 mStatusBarManager = new StatusBarManager(getOuterContext());
974 }
975 return mStatusBarManager;
976 }
977 } else if (AUDIO_SERVICE.equals(name)) {
978 return getAudioManager();
979 } else if (TELEPHONY_SERVICE.equals(name)) {
980 return getTelephonyManager();
981 } else if (CLIPBOARD_SERVICE.equals(name)) {
982 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700983 } else if (WALLPAPER_SERVICE.equals(name)) {
984 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700985 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800986 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800987 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
988 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100989 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800990 return getUiModeManager();
Steve Howarda2709362010-07-02 17:12:48 -0700991 } else if (DOWNLOAD_SERVICE.equals(name)) {
992 return getDownloadManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 }
994
995 return null;
996 }
997
Fred Quintana60307342009-03-24 22:48:12 -0700998 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700999 synchronized (mSync) {
1000 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -07001001 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
1002 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -07001003 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -07001004 }
Fred Quintanae00a3112009-09-22 15:13:30 -07001005 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -07001006 }
Fred Quintana60307342009-03-24 22:48:12 -07001007 }
1008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 private ActivityManager getActivityManager() {
1010 synchronized (mSync) {
1011 if (mActivityManager == null) {
1012 mActivityManager = new ActivityManager(getOuterContext(),
1013 mMainThread.getHandler());
1014 }
1015 }
1016 return mActivityManager;
1017 }
1018
1019 private AlarmManager getAlarmManager() {
1020 synchronized (sSync) {
1021 if (sAlarmManager == null) {
1022 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1023 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1024 sAlarmManager = new AlarmManager(service);
1025 }
1026 }
1027 return sAlarmManager;
1028 }
1029
1030 private PowerManager getPowerManager() {
1031 synchronized (sSync) {
1032 if (sPowerManager == null) {
1033 IBinder b = ServiceManager.getService(POWER_SERVICE);
1034 IPowerManager service = IPowerManager.Stub.asInterface(b);
1035 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1036 }
1037 }
1038 return sPowerManager;
1039 }
1040
1041 private ConnectivityManager getConnectivityManager()
1042 {
1043 synchronized (sSync) {
1044 if (sConnectivityManager == null) {
1045 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1046 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1047 sConnectivityManager = new ConnectivityManager(service);
1048 }
1049 }
1050 return sConnectivityManager;
1051 }
1052
Irfan Sheriffc9b68512010-04-08 14:12:33 -07001053 private ThrottleManager getThrottleManager()
1054 {
1055 synchronized (sSync) {
1056 if (sThrottleManager == null) {
1057 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1058 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1059 sThrottleManager = new ThrottleManager(service);
1060 }
1061 }
1062 return sThrottleManager;
1063 }
1064
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 private WifiManager getWifiManager()
1066 {
1067 synchronized (sSync) {
1068 if (sWifiManager == null) {
1069 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1070 IWifiManager service = IWifiManager.Stub.asInterface(b);
1071 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1072 }
1073 }
1074 return sWifiManager;
1075 }
1076
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001077 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 synchronized (mSync) {
1079 if (mNotificationManager == null) {
1080 mNotificationManager = new NotificationManager(
1081 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1082 mMainThread.getHandler());
1083 }
1084 }
1085 return mNotificationManager;
1086 }
1087
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001088 private WallpaperManager getWallpaperManager() {
1089 synchronized (mSync) {
1090 if (mWallpaperManager == null) {
1091 mWallpaperManager = new WallpaperManager(getOuterContext(),
1092 mMainThread.getHandler());
1093 }
1094 }
1095 return mWallpaperManager;
1096 }
1097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001098 private TelephonyManager getTelephonyManager() {
1099 synchronized (mSync) {
1100 if (mTelephonyManager == null) {
1101 mTelephonyManager = new TelephonyManager(getOuterContext());
1102 }
1103 }
1104 return mTelephonyManager;
1105 }
1106
1107 private ClipboardManager getClipboardManager() {
1108 synchronized (mSync) {
1109 if (mClipboardManager == null) {
1110 mClipboardManager = new ClipboardManager(getOuterContext(),
1111 mMainThread.getHandler());
1112 }
1113 }
1114 return mClipboardManager;
1115 }
1116
1117 private LocationManager getLocationManager() {
1118 synchronized (sSync) {
1119 if (sLocationManager == null) {
1120 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1121 ILocationManager service = ILocationManager.Stub.asInterface(b);
1122 sLocationManager = new LocationManager(service);
1123 }
1124 }
1125 return sLocationManager;
1126 }
1127
Bai Taoa58a8752010-07-13 15:32:16 +08001128 private CountryDetector getCountryDetector() {
1129 synchronized (sSync) {
1130 if (sCountryDetector == null) {
1131 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
1132 ICountryDetector service = ICountryDetector.Stub.asInterface(b);
1133 sCountryDetector = new CountryDetector(service);
1134 }
1135 }
1136 return sCountryDetector;
1137 }
1138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001139 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 synchronized (mSync) {
1141 if (mSearchManager == null) {
1142 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1143 }
1144 }
1145 return mSearchManager;
1146 }
1147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 private SensorManager getSensorManager() {
1149 synchronized (mSync) {
1150 if (mSensorManager == null) {
1151 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1152 }
1153 }
1154 return mSensorManager;
1155 }
1156
San Mehatc9d81752010-02-01 10:23:27 -08001157 private StorageManager getStorageManager() {
1158 synchronized (mSync) {
1159 if (mStorageManager == null) {
1160 try {
1161 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1162 } catch (RemoteException rex) {
1163 Log.e(TAG, "Failed to create StorageManager", rex);
1164 mStorageManager = null;
1165 }
1166 }
1167 }
1168 return mStorageManager;
1169 }
1170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 private Vibrator getVibrator() {
1172 synchronized (mSync) {
1173 if (mVibrator == null) {
1174 mVibrator = new Vibrator();
1175 }
1176 }
1177 return mVibrator;
1178 }
Dan Egnor95240272009-10-27 18:23:39 -07001179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 private AudioManager getAudioManager()
1181 {
1182 if (mAudioManager == null) {
1183 mAudioManager = new AudioManager(this);
1184 }
1185 return mAudioManager;
1186 }
1187
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001188 /* package */ static DropBoxManager createDropBoxManager() {
1189 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1190 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1191 return new DropBoxManager(service);
1192 }
1193
Dan Egnorf18a01c2009-11-12 11:32:50 -08001194 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001195 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001196 if (mDropBoxManager == null) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001197 mDropBoxManager = createDropBoxManager();
Dan Egnor95240272009-10-27 18:23:39 -07001198 }
1199 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001200 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001201 }
1202
Dianne Hackbornd6847842010-01-12 18:14:19 -08001203 private DevicePolicyManager getDevicePolicyManager() {
1204 synchronized (mSync) {
1205 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001206 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001207 mMainThread.getHandler());
1208 }
1209 }
1210 return mDevicePolicyManager;
1211 }
1212
Tobias Haamel53332882010-02-18 16:15:43 -08001213 private UiModeManager getUiModeManager() {
1214 synchronized (mSync) {
1215 if (mUiModeManager == null) {
1216 mUiModeManager = new UiModeManager();
1217 }
1218 }
1219 return mUiModeManager;
1220 }
1221
Steve Howarda2709362010-07-02 17:12:48 -07001222 private DownloadManager getDownloadManager() {
1223 synchronized (mSync) {
1224 if (mDownloadManager == null) {
Steve Howardb8e07a52010-07-21 14:53:21 -07001225 mDownloadManager = new DownloadManager(getContentResolver(), getPackageName());
Steve Howarda2709362010-07-02 17:12:48 -07001226 }
1227 }
1228 return mDownloadManager;
1229 }
1230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 @Override
1232 public int checkPermission(String permission, int pid, int uid) {
1233 if (permission == null) {
1234 throw new IllegalArgumentException("permission is null");
1235 }
1236
1237 if (!Process.supportsProcesses()) {
1238 return PackageManager.PERMISSION_GRANTED;
1239 }
1240 try {
1241 return ActivityManagerNative.getDefault().checkPermission(
1242 permission, pid, uid);
1243 } catch (RemoteException e) {
1244 return PackageManager.PERMISSION_DENIED;
1245 }
1246 }
1247
1248 @Override
1249 public int checkCallingPermission(String permission) {
1250 if (permission == null) {
1251 throw new IllegalArgumentException("permission is null");
1252 }
1253
1254 if (!Process.supportsProcesses()) {
1255 return PackageManager.PERMISSION_GRANTED;
1256 }
1257 int pid = Binder.getCallingPid();
1258 if (pid != Process.myPid()) {
1259 return checkPermission(permission, pid,
1260 Binder.getCallingUid());
1261 }
1262 return PackageManager.PERMISSION_DENIED;
1263 }
1264
1265 @Override
1266 public int checkCallingOrSelfPermission(String permission) {
1267 if (permission == null) {
1268 throw new IllegalArgumentException("permission is null");
1269 }
1270
1271 return checkPermission(permission, Binder.getCallingPid(),
1272 Binder.getCallingUid());
1273 }
1274
1275 private void enforce(
1276 String permission, int resultOfCheck,
1277 boolean selfToo, int uid, String message) {
1278 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1279 throw new SecurityException(
1280 (message != null ? (message + ": ") : "") +
1281 (selfToo
1282 ? "Neither user " + uid + " nor current process has "
1283 : "User " + uid + " does not have ") +
1284 permission +
1285 ".");
1286 }
1287 }
1288
1289 public void enforcePermission(
1290 String permission, int pid, int uid, String message) {
1291 enforce(permission,
1292 checkPermission(permission, pid, uid),
1293 false,
1294 uid,
1295 message);
1296 }
1297
1298 public void enforceCallingPermission(String permission, String message) {
1299 enforce(permission,
1300 checkCallingPermission(permission),
1301 false,
1302 Binder.getCallingUid(),
1303 message);
1304 }
1305
1306 public void enforceCallingOrSelfPermission(
1307 String permission, String message) {
1308 enforce(permission,
1309 checkCallingOrSelfPermission(permission),
1310 true,
1311 Binder.getCallingUid(),
1312 message);
1313 }
1314
1315 @Override
1316 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1317 try {
1318 ActivityManagerNative.getDefault().grantUriPermission(
1319 mMainThread.getApplicationThread(), toPackage, uri,
1320 modeFlags);
1321 } catch (RemoteException e) {
1322 }
1323 }
1324
1325 @Override
1326 public void revokeUriPermission(Uri uri, int modeFlags) {
1327 try {
1328 ActivityManagerNative.getDefault().revokeUriPermission(
1329 mMainThread.getApplicationThread(), uri,
1330 modeFlags);
1331 } catch (RemoteException e) {
1332 }
1333 }
1334
1335 @Override
1336 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1337 if (!Process.supportsProcesses()) {
1338 return PackageManager.PERMISSION_GRANTED;
1339 }
1340 try {
1341 return ActivityManagerNative.getDefault().checkUriPermission(
1342 uri, pid, uid, modeFlags);
1343 } catch (RemoteException e) {
1344 return PackageManager.PERMISSION_DENIED;
1345 }
1346 }
1347
1348 @Override
1349 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1350 if (!Process.supportsProcesses()) {
1351 return PackageManager.PERMISSION_GRANTED;
1352 }
1353 int pid = Binder.getCallingPid();
1354 if (pid != Process.myPid()) {
1355 return checkUriPermission(uri, pid,
1356 Binder.getCallingUid(), modeFlags);
1357 }
1358 return PackageManager.PERMISSION_DENIED;
1359 }
1360
1361 @Override
1362 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1363 return checkUriPermission(uri, Binder.getCallingPid(),
1364 Binder.getCallingUid(), modeFlags);
1365 }
1366
1367 @Override
1368 public int checkUriPermission(Uri uri, String readPermission,
1369 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001370 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1372 + readPermission + " writePermission=" + writePermission
1373 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1374 }
1375 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1376 if (readPermission == null
1377 || checkPermission(readPermission, pid, uid)
1378 == PackageManager.PERMISSION_GRANTED) {
1379 return PackageManager.PERMISSION_GRANTED;
1380 }
1381 }
1382 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1383 if (writePermission == null
1384 || checkPermission(writePermission, pid, uid)
1385 == PackageManager.PERMISSION_GRANTED) {
1386 return PackageManager.PERMISSION_GRANTED;
1387 }
1388 }
1389 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1390 : PackageManager.PERMISSION_DENIED;
1391 }
1392
1393 private String uriModeFlagToString(int uriModeFlags) {
1394 switch (uriModeFlags) {
1395 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1396 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1397 return "read and write";
1398 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1399 return "read";
1400 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1401 return "write";
1402 }
1403 throw new IllegalArgumentException(
1404 "Unknown permission mode flags: " + uriModeFlags);
1405 }
1406
1407 private void enforceForUri(
1408 int modeFlags, int resultOfCheck, boolean selfToo,
1409 int uid, Uri uri, String message) {
1410 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1411 throw new SecurityException(
1412 (message != null ? (message + ": ") : "") +
1413 (selfToo
1414 ? "Neither user " + uid + " nor current process has "
1415 : "User " + uid + " does not have ") +
1416 uriModeFlagToString(modeFlags) +
1417 " permission on " +
1418 uri +
1419 ".");
1420 }
1421 }
1422
1423 public void enforceUriPermission(
1424 Uri uri, int pid, int uid, int modeFlags, String message) {
1425 enforceForUri(
1426 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1427 false, uid, uri, message);
1428 }
1429
1430 public void enforceCallingUriPermission(
1431 Uri uri, int modeFlags, String message) {
1432 enforceForUri(
1433 modeFlags, checkCallingUriPermission(uri, modeFlags),
1434 false, Binder.getCallingUid(), uri, message);
1435 }
1436
1437 public void enforceCallingOrSelfUriPermission(
1438 Uri uri, int modeFlags, String message) {
1439 enforceForUri(
1440 modeFlags,
1441 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1442 Binder.getCallingUid(), uri, message);
1443 }
1444
1445 public void enforceUriPermission(
1446 Uri uri, String readPermission, String writePermission,
1447 int pid, int uid, int modeFlags, String message) {
1448 enforceForUri(modeFlags,
1449 checkUriPermission(
1450 uri, readPermission, writePermission, pid, uid,
1451 modeFlags),
1452 false,
1453 uid,
1454 uri,
1455 message);
1456 }
1457
1458 @Override
1459 public Context createPackageContext(String packageName, int flags)
1460 throws PackageManager.NameNotFoundException {
1461 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001462 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 }
1464
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001465 LoadedApk pi =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 mMainThread.getPackageInfo(packageName, flags);
1467 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001468 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001469 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001470 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 if (c.mResources != null) {
1472 return c;
1473 }
1474 }
1475
1476 // Should be a better exception.
1477 throw new PackageManager.NameNotFoundException(
1478 "Application package " + packageName + " not found");
1479 }
1480
Romain Guy870e09f2009-07-06 16:35:25 -07001481 @Override
1482 public boolean isRestricted() {
1483 return mRestricted;
1484 }
1485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 private File getDataDirFile() {
1487 if (mPackageInfo != null) {
1488 return mPackageInfo.getDataDirFile();
1489 }
1490 throw new RuntimeException("Not supported in system context");
1491 }
1492
1493 @Override
1494 public File getDir(String name, int mode) {
1495 name = "app_" + name;
1496 File file = makeFilename(getDataDirFile(), name);
1497 if (!file.exists()) {
1498 file.mkdir();
1499 setFilePermissionsFromMode(file.getPath(), mode,
1500 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1501 }
1502 return file;
1503 }
1504
Dianne Hackborn21556372010-02-04 16:34:40 -08001505 static ContextImpl createSystemContext(ActivityThread mainThread) {
1506 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 context.init(Resources.getSystem(), mainThread);
1508 return context;
1509 }
1510
Dianne Hackborn21556372010-02-04 16:34:40 -08001511 ContextImpl() {
Carl Shapiro82fe5642010-02-24 00:14:23 -08001512 // For debug only
1513 //++sInstanceCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 mOuterContext = this;
1515 }
1516
1517 /**
1518 * Create a new ApplicationContext from an existing one. The new one
1519 * works and operates the same as the one it is copying.
1520 *
1521 * @param context Existing application context.
1522 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001523 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 ++sInstanceCount;
1525 mPackageInfo = context.mPackageInfo;
1526 mResources = context.mResources;
1527 mMainThread = context.mMainThread;
1528 mContentResolver = context.mContentResolver;
1529 mOuterContext = this;
1530 }
1531
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001532 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001534 init(packageInfo, activityToken, mainThread, null);
1535 }
1536
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001537 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001538 IBinder activityToken, ActivityThread mainThread,
1539 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 mPackageInfo = packageInfo;
1541 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001542
Dianne Hackborn559a7872010-04-07 18:19:41 -07001543 if (mResources != null && container != null
1544 && container.getCompatibilityInfo().applicationScale !=
1545 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001546 if (DEBUG) {
1547 Log.d(TAG, "loaded context has different scaling. Using container's" +
1548 " compatiblity info:" + container.getDisplayMetrics());
1549 }
1550 mResources = mainThread.getTopLevelResources(
1551 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 mMainThread = mainThread;
1554 mContentResolver = new ApplicationContentResolver(this, mainThread);
1555
1556 setActivityToken(activityToken);
1557 }
1558
1559 final void init(Resources resources, ActivityThread mainThread) {
1560 mPackageInfo = null;
1561 mResources = resources;
1562 mMainThread = mainThread;
1563 mContentResolver = new ApplicationContentResolver(this, mainThread);
1564 }
1565
1566 final void scheduleFinalCleanup(String who, String what) {
1567 mMainThread.scheduleContextCleanup(this, who, what);
1568 }
1569
1570 final void performFinalCleanup(String who, String what) {
1571 //Log.i(TAG, "Cleanup up context: " + this);
1572 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1573 }
1574
1575 final Context getReceiverRestrictedContext() {
1576 if (mReceiverRestrictedContext != null) {
1577 return mReceiverRestrictedContext;
1578 }
1579 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1580 }
1581
1582 final void setActivityToken(IBinder token) {
1583 mActivityToken = token;
1584 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 final void setOuterContext(Context context) {
1587 mOuterContext = context;
1588 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590 final Context getOuterContext() {
1591 return mOuterContext;
1592 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 final IBinder getActivityToken() {
1595 return mActivityToken;
1596 }
1597
1598 private static void setFilePermissionsFromMode(String name, int mode,
1599 int extraPermissions) {
1600 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1601 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1602 |extraPermissions;
1603 if ((mode&MODE_WORLD_READABLE) != 0) {
1604 perms |= FileUtils.S_IROTH;
1605 }
1606 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1607 perms |= FileUtils.S_IWOTH;
1608 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001609 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1611 + ", perms=0x" + Integer.toHexString(perms));
1612 }
1613 FileUtils.setPermissions(name, perms, -1, -1);
1614 }
1615
Oscar Montemayora8529f62009-11-18 10:14:20 -08001616 private File validateFilePath(String name, boolean createDirectory) {
1617 File dir;
1618 File f;
1619
1620 if (name.charAt(0) == File.separatorChar) {
1621 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1622 dir = new File(dirPath);
1623 name = name.substring(name.lastIndexOf(File.separatorChar));
1624 f = new File(dir, name);
1625 } else {
1626 dir = getDatabasesDir();
1627 f = makeFilename(dir, name);
1628 }
1629
1630 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1631 FileUtils.setPermissions(dir.getPath(),
1632 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1633 -1, -1);
1634 }
1635
1636 return f;
1637 }
1638
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 private File makeFilename(File base, String name) {
1640 if (name.indexOf(File.separatorChar) < 0) {
1641 return new File(base, name);
1642 }
1643 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001644 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
1646
1647 // ----------------------------------------------------------------------
1648 // ----------------------------------------------------------------------
1649 // ----------------------------------------------------------------------
1650
1651 private static final class ApplicationContentResolver extends ContentResolver {
1652 public ApplicationContentResolver(Context context,
1653 ActivityThread mainThread)
1654 {
1655 super(context);
1656 mMainThread = mainThread;
1657 }
1658
1659 @Override
1660 protected IContentProvider acquireProvider(Context context, String name)
1661 {
1662 return mMainThread.acquireProvider(context, name);
1663 }
1664
1665 @Override
1666 public boolean releaseProvider(IContentProvider provider)
1667 {
1668 return mMainThread.releaseProvider(provider);
1669 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 private final ActivityThread mMainThread;
1672 }
1673
1674 // ----------------------------------------------------------------------
1675 // ----------------------------------------------------------------------
1676 // ----------------------------------------------------------------------
1677
1678 /*package*/
1679 static final class ApplicationPackageManager extends PackageManager {
1680 @Override
1681 public PackageInfo getPackageInfo(String packageName, int flags)
1682 throws NameNotFoundException {
1683 try {
1684 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1685 if (pi != null) {
1686 return pi;
1687 }
1688 } catch (RemoteException e) {
1689 throw new RuntimeException("Package manager has died", e);
1690 }
1691
1692 throw new NameNotFoundException(packageName);
1693 }
1694
Mihai Predaeae850c2009-05-13 10:13:48 +02001695 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001696 public String[] currentToCanonicalPackageNames(String[] names) {
1697 try {
1698 return mPM.currentToCanonicalPackageNames(names);
1699 } catch (RemoteException e) {
1700 throw new RuntimeException("Package manager has died", e);
1701 }
1702 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001703
Dianne Hackborn47096932010-02-11 15:57:09 -08001704 @Override
1705 public String[] canonicalToCurrentPackageNames(String[] names) {
1706 try {
1707 return mPM.canonicalToCurrentPackageNames(names);
1708 } catch (RemoteException e) {
1709 throw new RuntimeException("Package manager has died", e);
1710 }
1711 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001712
Dianne Hackborn47096932010-02-11 15:57:09 -08001713 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001714 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001715 // First see if the package has an INFO activity; the existence of
1716 // such an activity is implied to be the desired front-door for the
1717 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001718 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1719 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001720 intentToResolve.setPackage(packageName);
1721 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001724 if (resolveInfo == null) {
1725 // reuse the intent instance
1726 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1727 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001728 intentToResolve.setPackage(packageName);
1729 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001731 if (resolveInfo == null) {
1732 return null;
1733 }
Johan Erlandssondf4cfa362010-03-31 08:20:51 +02001734 Intent intent = new Intent(intentToResolve);
1735 intent.setClassName(resolveInfo.activityInfo.applicationInfo.packageName,
1736 resolveInfo.activityInfo.name);
Mihai Predaeae850c2009-05-13 10:13:48 +02001737 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1738 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001741 @Override
1742 public int[] getPackageGids(String packageName)
1743 throws NameNotFoundException {
1744 try {
1745 int[] gids = mPM.getPackageGids(packageName);
1746 if (gids == null || gids.length > 0) {
1747 return gids;
1748 }
1749 } catch (RemoteException e) {
1750 throw new RuntimeException("Package manager has died", e);
1751 }
1752
1753 throw new NameNotFoundException(packageName);
1754 }
1755
1756 @Override
1757 public PermissionInfo getPermissionInfo(String name, int flags)
1758 throws NameNotFoundException {
1759 try {
1760 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1761 if (pi != null) {
1762 return pi;
1763 }
1764 } catch (RemoteException e) {
1765 throw new RuntimeException("Package manager has died", e);
1766 }
1767
1768 throw new NameNotFoundException(name);
1769 }
1770
1771 @Override
1772 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1773 throws NameNotFoundException {
1774 try {
1775 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1776 if (pi != null) {
1777 return pi;
1778 }
1779 } catch (RemoteException e) {
1780 throw new RuntimeException("Package manager has died", e);
1781 }
1782
1783 throw new NameNotFoundException(group);
1784 }
1785
1786 @Override
1787 public PermissionGroupInfo getPermissionGroupInfo(String name,
1788 int flags) throws NameNotFoundException {
1789 try {
1790 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1791 if (pgi != null) {
1792 return pgi;
1793 }
1794 } catch (RemoteException e) {
1795 throw new RuntimeException("Package manager has died", e);
1796 }
1797
1798 throw new NameNotFoundException(name);
1799 }
1800
1801 @Override
1802 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1803 try {
1804 return mPM.getAllPermissionGroups(flags);
1805 } catch (RemoteException e) {
1806 throw new RuntimeException("Package manager has died", e);
1807 }
1808 }
1809
1810 @Override
1811 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1812 throws NameNotFoundException {
1813 try {
1814 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1815 if (ai != null) {
1816 return ai;
1817 }
1818 } catch (RemoteException e) {
1819 throw new RuntimeException("Package manager has died", e);
1820 }
1821
1822 throw new NameNotFoundException(packageName);
1823 }
1824
1825 @Override
1826 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1827 throws NameNotFoundException {
1828 try {
1829 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1830 if (ai != null) {
1831 return ai;
1832 }
1833 } catch (RemoteException e) {
1834 throw new RuntimeException("Package manager has died", e);
1835 }
1836
1837 throw new NameNotFoundException(className.toString());
1838 }
1839
1840 @Override
1841 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1842 throws NameNotFoundException {
1843 try {
1844 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1845 if (ai != null) {
1846 return ai;
1847 }
1848 } catch (RemoteException e) {
1849 throw new RuntimeException("Package manager has died", e);
1850 }
1851
1852 throw new NameNotFoundException(className.toString());
1853 }
1854
1855 @Override
1856 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1857 throws NameNotFoundException {
1858 try {
1859 ServiceInfo si = mPM.getServiceInfo(className, flags);
1860 if (si != null) {
1861 return si;
1862 }
1863 } catch (RemoteException e) {
1864 throw new RuntimeException("Package manager has died", e);
1865 }
1866
1867 throw new NameNotFoundException(className.toString());
1868 }
1869
1870 @Override
1871 public String[] getSystemSharedLibraryNames() {
1872 try {
1873 return mPM.getSystemSharedLibraryNames();
1874 } catch (RemoteException e) {
1875 throw new RuntimeException("Package manager has died", e);
1876 }
1877 }
1878
1879 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001880 public FeatureInfo[] getSystemAvailableFeatures() {
1881 try {
1882 return mPM.getSystemAvailableFeatures();
1883 } catch (RemoteException e) {
1884 throw new RuntimeException("Package manager has died", e);
1885 }
1886 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001887
Dianne Hackborn49237342009-08-27 20:08:01 -07001888 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001889 public boolean hasSystemFeature(String name) {
1890 try {
1891 return mPM.hasSystemFeature(name);
1892 } catch (RemoteException e) {
1893 throw new RuntimeException("Package manager has died", e);
1894 }
1895 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001896
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001897 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001898 public int checkPermission(String permName, String pkgName) {
1899 try {
1900 return mPM.checkPermission(permName, pkgName);
1901 } catch (RemoteException e) {
1902 throw new RuntimeException("Package manager has died", e);
1903 }
1904 }
1905
1906 @Override
1907 public boolean addPermission(PermissionInfo info) {
1908 try {
1909 return mPM.addPermission(info);
1910 } catch (RemoteException e) {
1911 throw new RuntimeException("Package manager has died", e);
1912 }
1913 }
1914
1915 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001916 public boolean addPermissionAsync(PermissionInfo info) {
1917 try {
1918 return mPM.addPermissionAsync(info);
1919 } catch (RemoteException e) {
1920 throw new RuntimeException("Package manager has died", e);
1921 }
1922 }
1923
1924 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001925 public void removePermission(String name) {
1926 try {
1927 mPM.removePermission(name);
1928 } catch (RemoteException e) {
1929 throw new RuntimeException("Package manager has died", e);
1930 }
1931 }
1932
1933 @Override
1934 public int checkSignatures(String pkg1, String pkg2) {
1935 try {
1936 return mPM.checkSignatures(pkg1, pkg2);
1937 } catch (RemoteException e) {
1938 throw new RuntimeException("Package manager has died", e);
1939 }
1940 }
1941
1942 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001943 public int checkSignatures(int uid1, int uid2) {
1944 try {
1945 return mPM.checkUidSignatures(uid1, uid2);
1946 } catch (RemoteException e) {
1947 throw new RuntimeException("Package manager has died", e);
1948 }
1949 }
1950
1951 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 public String[] getPackagesForUid(int uid) {
1953 try {
1954 return mPM.getPackagesForUid(uid);
1955 } catch (RemoteException e) {
1956 throw new RuntimeException("Package manager has died", e);
1957 }
1958 }
1959
1960 @Override
1961 public String getNameForUid(int uid) {
1962 try {
1963 return mPM.getNameForUid(uid);
1964 } catch (RemoteException e) {
1965 throw new RuntimeException("Package manager has died", e);
1966 }
1967 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001970 public int getUidForSharedUser(String sharedUserName)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 throws NameNotFoundException {
1972 try {
1973 int uid = mPM.getUidForSharedUser(sharedUserName);
1974 if(uid != -1) {
1975 return uid;
1976 }
1977 } catch (RemoteException e) {
1978 throw new RuntimeException("Package manager has died", e);
1979 }
1980 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1981 }
1982
1983 @Override
1984 public List<PackageInfo> getInstalledPackages(int flags) {
1985 try {
1986 return mPM.getInstalledPackages(flags);
1987 } catch (RemoteException e) {
1988 throw new RuntimeException("Package manager has died", e);
1989 }
1990 }
1991
1992 @Override
1993 public List<ApplicationInfo> getInstalledApplications(int flags) {
1994 try {
1995 return mPM.getInstalledApplications(flags);
1996 } catch (RemoteException e) {
1997 throw new RuntimeException("Package manager has died", e);
1998 }
1999 }
2000
2001 @Override
2002 public ResolveInfo resolveActivity(Intent intent, int flags) {
2003 try {
2004 return mPM.resolveIntent(
2005 intent,
2006 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2007 flags);
2008 } catch (RemoteException e) {
2009 throw new RuntimeException("Package manager has died", e);
2010 }
2011 }
2012
2013 @Override
2014 public List<ResolveInfo> queryIntentActivities(Intent intent,
2015 int flags) {
2016 try {
2017 return mPM.queryIntentActivities(
2018 intent,
2019 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2020 flags);
2021 } catch (RemoteException e) {
2022 throw new RuntimeException("Package manager has died", e);
2023 }
2024 }
2025
2026 @Override
2027 public List<ResolveInfo> queryIntentActivityOptions(
2028 ComponentName caller, Intent[] specifics, Intent intent,
2029 int flags) {
2030 final ContentResolver resolver = mContext.getContentResolver();
2031
2032 String[] specificTypes = null;
2033 if (specifics != null) {
2034 final int N = specifics.length;
2035 for (int i=0; i<N; i++) {
2036 Intent sp = specifics[i];
2037 if (sp != null) {
2038 String t = sp.resolveTypeIfNeeded(resolver);
2039 if (t != null) {
2040 if (specificTypes == null) {
2041 specificTypes = new String[N];
2042 }
2043 specificTypes[i] = t;
2044 }
2045 }
2046 }
2047 }
2048
2049 try {
2050 return mPM.queryIntentActivityOptions(caller, specifics,
2051 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2052 flags);
2053 } catch (RemoteException e) {
2054 throw new RuntimeException("Package manager has died", e);
2055 }
2056 }
2057
2058 @Override
2059 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2060 try {
2061 return mPM.queryIntentReceivers(
2062 intent,
2063 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2064 flags);
2065 } catch (RemoteException e) {
2066 throw new RuntimeException("Package manager has died", e);
2067 }
2068 }
2069
2070 @Override
2071 public ResolveInfo resolveService(Intent intent, int flags) {
2072 try {
2073 return mPM.resolveService(
2074 intent,
2075 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2076 flags);
2077 } catch (RemoteException e) {
2078 throw new RuntimeException("Package manager has died", e);
2079 }
2080 }
2081
2082 @Override
2083 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2084 try {
2085 return mPM.queryIntentServices(
2086 intent,
2087 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2088 flags);
2089 } catch (RemoteException e) {
2090 throw new RuntimeException("Package manager has died", e);
2091 }
2092 }
2093
2094 @Override
2095 public ProviderInfo resolveContentProvider(String name,
2096 int flags) {
2097 try {
2098 return mPM.resolveContentProvider(name, flags);
2099 } catch (RemoteException e) {
2100 throw new RuntimeException("Package manager has died", e);
2101 }
2102 }
2103
2104 @Override
2105 public List<ProviderInfo> queryContentProviders(String processName,
2106 int uid, int flags) {
2107 try {
2108 return mPM.queryContentProviders(processName, uid, flags);
2109 } catch (RemoteException e) {
2110 throw new RuntimeException("Package manager has died", e);
2111 }
2112 }
2113
2114 @Override
2115 public InstrumentationInfo getInstrumentationInfo(
2116 ComponentName className, int flags)
2117 throws NameNotFoundException {
2118 try {
2119 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2120 className, flags);
2121 if (ii != null) {
2122 return ii;
2123 }
2124 } catch (RemoteException e) {
2125 throw new RuntimeException("Package manager has died", e);
2126 }
2127
2128 throw new NameNotFoundException(className.toString());
2129 }
2130
2131 @Override
2132 public List<InstrumentationInfo> queryInstrumentation(
2133 String targetPackage, int flags) {
2134 try {
2135 return mPM.queryInstrumentation(targetPackage, flags);
2136 } catch (RemoteException e) {
2137 throw new RuntimeException("Package manager has died", e);
2138 }
2139 }
2140
2141 @Override public Drawable getDrawable(String packageName, int resid,
2142 ApplicationInfo appInfo) {
2143 ResourceName name = new ResourceName(packageName, resid);
2144 Drawable dr = getCachedIcon(name);
2145 if (dr != null) {
2146 return dr;
2147 }
2148 if (appInfo == null) {
2149 try {
2150 appInfo = getApplicationInfo(packageName, 0);
2151 } catch (NameNotFoundException e) {
2152 return null;
2153 }
2154 }
2155 try {
2156 Resources r = getResourcesForApplication(appInfo);
2157 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002158 if (false) {
2159 RuntimeException e = new RuntimeException("here");
2160 e.fillInStackTrace();
2161 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2162 + " from package " + packageName
2163 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2164 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2165 e);
2166 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2168 + Integer.toHexString(resid) + " from " + r
2169 + ": " + dr);
2170 putCachedIcon(name, dr);
2171 return dr;
2172 } catch (NameNotFoundException e) {
2173 Log.w("PackageManager", "Failure retrieving resources for"
2174 + appInfo.packageName);
2175 } catch (RuntimeException e) {
2176 // If an exception was thrown, fall through to return
2177 // default icon.
2178 Log.w("PackageManager", "Failure retrieving icon 0x"
2179 + Integer.toHexString(resid) + " in package "
2180 + packageName, e);
2181 }
2182 return null;
2183 }
2184
2185 @Override public Drawable getActivityIcon(ComponentName activityName)
2186 throws NameNotFoundException {
2187 return getActivityInfo(activityName, 0).loadIcon(this);
2188 }
2189
2190 @Override public Drawable getActivityIcon(Intent intent)
2191 throws NameNotFoundException {
2192 if (intent.getComponent() != null) {
2193 return getActivityIcon(intent.getComponent());
2194 }
2195
2196 ResolveInfo info = resolveActivity(
2197 intent, PackageManager.MATCH_DEFAULT_ONLY);
2198 if (info != null) {
2199 return info.activityInfo.loadIcon(this);
2200 }
2201
2202 throw new NameNotFoundException(intent.toURI());
2203 }
2204
2205 @Override public Drawable getDefaultActivityIcon() {
2206 return Resources.getSystem().getDrawable(
2207 com.android.internal.R.drawable.sym_def_app_icon);
2208 }
2209
2210 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002211 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002212 }
2213
2214 @Override public Drawable getApplicationIcon(String packageName)
2215 throws NameNotFoundException {
2216 return getApplicationIcon(getApplicationInfo(packageName, 0));
2217 }
Adam Powell81cd2e92010-04-21 16:35:18 -07002218
2219 @Override
2220 public Drawable getActivityLogo(ComponentName activityName)
2221 throws NameNotFoundException {
2222 return getActivityInfo(activityName, 0).loadLogo(this);
2223 }
2224
2225 @Override
2226 public Drawable getActivityLogo(Intent intent)
2227 throws NameNotFoundException {
2228 if (intent.getComponent() != null) {
2229 return getActivityLogo(intent.getComponent());
2230 }
2231
2232 ResolveInfo info = resolveActivity(
2233 intent, PackageManager.MATCH_DEFAULT_ONLY);
2234 if (info != null) {
2235 return info.activityInfo.loadLogo(this);
2236 }
2237
2238 throw new NameNotFoundException(intent.toUri(0));
2239 }
2240
2241 @Override
2242 public Drawable getApplicationLogo(ApplicationInfo info) {
2243 return info.loadLogo(this);
2244 }
2245
2246 @Override
2247 public Drawable getApplicationLogo(String packageName)
2248 throws NameNotFoundException {
2249 return getApplicationLogo(getApplicationInfo(packageName, 0));
2250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002251
2252 @Override public Resources getResourcesForActivity(
2253 ComponentName activityName) throws NameNotFoundException {
2254 return getResourcesForApplication(
2255 getActivityInfo(activityName, 0).applicationInfo);
2256 }
2257
2258 @Override public Resources getResourcesForApplication(
2259 ApplicationInfo app) throws NameNotFoundException {
2260 if (app.packageName.equals("system")) {
2261 return mContext.mMainThread.getSystemContext().getResources();
2262 }
2263 Resources r = mContext.mMainThread.getTopLevelResources(
2264 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002265 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 if (r != null) {
2267 return r;
2268 }
2269 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2270 }
2271
2272 @Override public Resources getResourcesForApplication(
2273 String appPackageName) throws NameNotFoundException {
2274 return getResourcesForApplication(
2275 getApplicationInfo(appPackageName, 0));
2276 }
2277
2278 int mCachedSafeMode = -1;
2279 @Override public boolean isSafeMode() {
2280 try {
2281 if (mCachedSafeMode < 0) {
2282 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2283 }
2284 return mCachedSafeMode != 0;
2285 } catch (RemoteException e) {
2286 throw new RuntimeException("Package manager has died", e);
2287 }
2288 }
2289
2290 static void configurationChanged() {
2291 synchronized (sSync) {
2292 sIconCache.clear();
2293 sStringCache.clear();
2294 }
2295 }
2296
Dianne Hackborn21556372010-02-04 16:34:40 -08002297 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 IPackageManager pm) {
2299 mContext = context;
2300 mPM = pm;
2301 }
2302
2303 private Drawable getCachedIcon(ResourceName name) {
2304 synchronized (sSync) {
2305 WeakReference<Drawable> wr = sIconCache.get(name);
2306 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2307 + name + ": " + wr);
2308 if (wr != null) { // we have the activity
2309 Drawable dr = wr.get();
2310 if (dr != null) {
2311 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2312 + name + ": " + dr);
2313 return dr;
2314 }
2315 // our entry has been purged
2316 sIconCache.remove(name);
2317 }
2318 }
2319 return null;
2320 }
2321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 private void putCachedIcon(ResourceName name, Drawable dr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 synchronized (sSync) {
2324 sIconCache.put(name, new WeakReference<Drawable>(dr));
2325 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2326 + name + ": " + dr);
2327 }
2328 }
2329
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002330 static final void handlePackageBroadcast(int cmd, String[] pkgList,
2331 boolean hasPkgInfo) {
2332 boolean immediateGc = false;
2333 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2334 immediateGc = true;
2335 }
2336 if (pkgList != null && (pkgList.length > 0)) {
2337 boolean needCleanup = false;
2338 for (String ssp : pkgList) {
2339 synchronized (sSync) {
2340 if (sIconCache.size() > 0) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002341 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2342 while (it.hasNext()) {
2343 ResourceName nm = it.next();
2344 if (nm.packageName.equals(ssp)) {
2345 //Log.i(TAG, "Removing cached drawable for " + nm);
2346 it.remove();
2347 needCleanup = true;
2348 }
2349 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002350 }
2351 if (sStringCache.size() > 0) {
2352 Iterator<ResourceName> it = sStringCache.keySet().iterator();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002353 while (it.hasNext()) {
2354 ResourceName nm = it.next();
2355 if (nm.packageName.equals(ssp)) {
2356 //Log.i(TAG, "Removing cached string for " + nm);
2357 it.remove();
2358 needCleanup = true;
2359 }
2360 }
2361 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002362 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002363 }
2364 if (needCleanup || hasPkgInfo) {
2365 if (immediateGc) {
2366 // Schedule an immediate gc.
2367 Runtime.getRuntime().gc();
2368 } else {
2369 ActivityThread.currentActivityThread().scheduleGcIdler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 }
2371 }
2372 }
2373 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002375 private static final class ResourceName {
2376 final String packageName;
2377 final int iconId;
2378
2379 ResourceName(String _packageName, int _iconId) {
2380 packageName = _packageName;
2381 iconId = _iconId;
2382 }
2383
2384 ResourceName(ApplicationInfo aInfo, int _iconId) {
2385 this(aInfo.packageName, _iconId);
2386 }
2387
2388 ResourceName(ComponentInfo cInfo, int _iconId) {
2389 this(cInfo.applicationInfo.packageName, _iconId);
2390 }
2391
2392 ResourceName(ResolveInfo rInfo, int _iconId) {
2393 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2394 }
2395
2396 @Override
2397 public boolean equals(Object o) {
2398 if (this == o) return true;
2399 if (o == null || getClass() != o.getClass()) return false;
2400
2401 ResourceName that = (ResourceName) o;
2402
2403 if (iconId != that.iconId) return false;
2404 return !(packageName != null ?
2405 !packageName.equals(that.packageName) : that.packageName != null);
2406
2407 }
2408
2409 @Override
2410 public int hashCode() {
2411 int result;
2412 result = packageName.hashCode();
2413 result = 31 * result + iconId;
2414 return result;
2415 }
2416
2417 @Override
2418 public String toString() {
2419 return "{ResourceName " + packageName + " / " + iconId + "}";
2420 }
2421 }
2422
2423 private CharSequence getCachedString(ResourceName name) {
2424 synchronized (sSync) {
2425 WeakReference<CharSequence> wr = sStringCache.get(name);
2426 if (wr != null) { // we have the activity
2427 CharSequence cs = wr.get();
2428 if (cs != null) {
2429 return cs;
2430 }
2431 // our entry has been purged
2432 sStringCache.remove(name);
2433 }
2434 }
2435 return null;
2436 }
2437
2438 private void putCachedString(ResourceName name, CharSequence cs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002439 synchronized (sSync) {
2440 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2441 }
2442 }
2443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002444 @Override
2445 public CharSequence getText(String packageName, int resid,
2446 ApplicationInfo appInfo) {
2447 ResourceName name = new ResourceName(packageName, resid);
2448 CharSequence text = getCachedString(name);
2449 if (text != null) {
2450 return text;
2451 }
2452 if (appInfo == null) {
2453 try {
2454 appInfo = getApplicationInfo(packageName, 0);
2455 } catch (NameNotFoundException e) {
2456 return null;
2457 }
2458 }
2459 try {
2460 Resources r = getResourcesForApplication(appInfo);
2461 text = r.getText(resid);
2462 putCachedString(name, text);
2463 return text;
2464 } catch (NameNotFoundException e) {
2465 Log.w("PackageManager", "Failure retrieving resources for"
2466 + appInfo.packageName);
2467 } catch (RuntimeException e) {
2468 // If an exception was thrown, fall through to return
2469 // default icon.
2470 Log.w("PackageManager", "Failure retrieving text 0x"
2471 + Integer.toHexString(resid) + " in package "
2472 + packageName, e);
2473 }
2474 return null;
2475 }
2476
2477 @Override
2478 public XmlResourceParser getXml(String packageName, int resid,
2479 ApplicationInfo appInfo) {
2480 if (appInfo == null) {
2481 try {
2482 appInfo = getApplicationInfo(packageName, 0);
2483 } catch (NameNotFoundException e) {
2484 return null;
2485 }
2486 }
2487 try {
2488 Resources r = getResourcesForApplication(appInfo);
2489 return r.getXml(resid);
2490 } catch (RuntimeException e) {
2491 // If an exception was thrown, fall through to return
2492 // default icon.
2493 Log.w("PackageManager", "Failure retrieving xml 0x"
2494 + Integer.toHexString(resid) + " in package "
2495 + packageName, e);
2496 } catch (NameNotFoundException e) {
2497 Log.w("PackageManager", "Failure retrieving resources for"
2498 + appInfo.packageName);
2499 }
2500 return null;
2501 }
2502
2503 @Override
2504 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002505 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 }
2507
2508 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002509 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2510 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002512 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 } catch (RemoteException e) {
2514 // Should never happen!
2515 }
2516 }
2517
2518 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002519 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2520 try {
2521 mPM.movePackage(packageName, observer, flags);
2522 } catch (RemoteException e) {
2523 // Should never happen!
2524 }
2525 }
2526
2527 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002528 public String getInstallerPackageName(String packageName) {
2529 try {
2530 return mPM.getInstallerPackageName(packageName);
2531 } catch (RemoteException e) {
2532 // Should never happen!
2533 }
2534 return null;
2535 }
2536
2537 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2539 try {
2540 mPM.deletePackage(packageName, observer, flags);
2541 } catch (RemoteException e) {
2542 // Should never happen!
2543 }
2544 }
2545 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002546 public void clearApplicationUserData(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 IPackageDataObserver observer) {
2548 try {
2549 mPM.clearApplicationUserData(packageName, observer);
2550 } catch (RemoteException e) {
2551 // Should never happen!
2552 }
2553 }
2554 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002555 public void deleteApplicationCacheFiles(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002556 IPackageDataObserver observer) {
2557 try {
2558 mPM.deleteApplicationCacheFiles(packageName, observer);
2559 } catch (RemoteException e) {
2560 // Should never happen!
2561 }
2562 }
2563 @Override
2564 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2565 try {
2566 mPM.freeStorageAndNotify(idealStorageSize, observer);
2567 } catch (RemoteException e) {
2568 // Should never happen!
2569 }
2570 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002571
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002573 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002574 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002575 mPM.freeStorage(freeStorageSize, pi);
2576 } catch (RemoteException e) {
2577 // Should never happen!
2578 }
2579 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 @Override
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002582 public void getPackageSizeInfo(String packageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 IPackageStatsObserver observer) {
2584 try {
2585 mPM.getPackageSizeInfo(packageName, observer);
2586 } catch (RemoteException e) {
2587 // Should never happen!
2588 }
2589 }
2590 @Override
2591 public void addPackageToPreferred(String packageName) {
2592 try {
2593 mPM.addPackageToPreferred(packageName);
2594 } catch (RemoteException e) {
2595 // Should never happen!
2596 }
2597 }
2598
2599 @Override
2600 public void removePackageFromPreferred(String packageName) {
2601 try {
2602 mPM.removePackageFromPreferred(packageName);
2603 } catch (RemoteException e) {
2604 // Should never happen!
2605 }
2606 }
2607
2608 @Override
2609 public List<PackageInfo> getPreferredPackages(int flags) {
2610 try {
2611 return mPM.getPreferredPackages(flags);
2612 } catch (RemoteException e) {
2613 // Should never happen!
2614 }
2615 return new ArrayList<PackageInfo>();
2616 }
2617
2618 @Override
2619 public void addPreferredActivity(IntentFilter filter,
2620 int match, ComponentName[] set, ComponentName activity) {
2621 try {
2622 mPM.addPreferredActivity(filter, match, set, activity);
2623 } catch (RemoteException e) {
2624 // Should never happen!
2625 }
2626 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002629 public void replacePreferredActivity(IntentFilter filter,
2630 int match, ComponentName[] set, ComponentName activity) {
2631 try {
2632 mPM.replacePreferredActivity(filter, match, set, activity);
2633 } catch (RemoteException e) {
2634 // Should never happen!
2635 }
2636 }
2637
2638 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 public void clearPackagePreferredActivities(String packageName) {
2640 try {
2641 mPM.clearPackagePreferredActivities(packageName);
2642 } catch (RemoteException e) {
2643 // Should never happen!
2644 }
2645 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002646
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 @Override
2648 public int getPreferredActivities(List<IntentFilter> outFilters,
2649 List<ComponentName> outActivities, String packageName) {
2650 try {
2651 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2652 } catch (RemoteException e) {
2653 // Should never happen!
2654 }
2655 return 0;
2656 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 @Override
2659 public void setComponentEnabledSetting(ComponentName componentName,
2660 int newState, int flags) {
2661 try {
2662 mPM.setComponentEnabledSetting(componentName, newState, flags);
2663 } catch (RemoteException e) {
2664 // Should never happen!
2665 }
2666 }
2667
2668 @Override
2669 public int getComponentEnabledSetting(ComponentName componentName) {
2670 try {
2671 return mPM.getComponentEnabledSetting(componentName);
2672 } catch (RemoteException e) {
2673 // Should never happen!
2674 }
2675 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2676 }
2677
2678 @Override
2679 public void setApplicationEnabledSetting(String packageName,
2680 int newState, int flags) {
2681 try {
2682 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2683 } catch (RemoteException e) {
2684 // Should never happen!
2685 }
2686 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688 @Override
2689 public int getApplicationEnabledSetting(String packageName) {
2690 try {
2691 return mPM.getApplicationEnabledSetting(packageName);
2692 } catch (RemoteException e) {
2693 // Should never happen!
2694 }
2695 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2696 }
2697
Kenny Root93565c42010-06-18 15:46:06 -07002698 @Override
2699 public void setPackageObbPath(String packageName, String path) {
2700 try {
2701 mPM.setPackageObbPath(packageName, path);
2702 } catch (RemoteException e) {
2703 // Should never happen!
2704 }
2705 }
2706
Dianne Hackborn21556372010-02-04 16:34:40 -08002707 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 private final IPackageManager mPM;
2709
2710 private static final Object sSync = new Object();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2712 = new HashMap<ResourceName, WeakReference<Drawable> >();
2713 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2714 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2715 }
2716
2717 // ----------------------------------------------------------------------
2718 // ----------------------------------------------------------------------
2719 // ----------------------------------------------------------------------
2720
2721 private static final class SharedPreferencesImpl implements SharedPreferences {
2722
2723 private final File mFile;
2724 private final File mBackupFile;
2725 private final int mMode;
2726 private Map mMap;
2727 private final FileStatus mFileStatus = new FileStatus();
2728 private long mTimestamp;
2729
The Android Open Source Project10592532009-03-18 17:39:46 -07002730 private static final Object mContent = new Object();
2731 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732
2733 SharedPreferencesImpl(
2734 File file, int mode, Map initialContents) {
2735 mFile = file;
2736 mBackupFile = makeBackupFile(file);
2737 mMode = mode;
2738 mMap = initialContents != null ? initialContents : new HashMap();
2739 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2740 mTimestamp = mFileStatus.mtime;
2741 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002742 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002743 }
2744
2745 public boolean hasFileChanged() {
2746 synchronized (this) {
2747 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2748 return true;
2749 }
2750 return mTimestamp != mFileStatus.mtime;
2751 }
2752 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 public void replace(Map newContents) {
2755 if (newContents != null) {
2756 synchronized (this) {
2757 mMap = newContents;
2758 }
2759 }
2760 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2763 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002764 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 }
2766 }
2767
2768 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2769 synchronized(this) {
2770 mListeners.remove(listener);
2771 }
2772 }
2773
2774 public Map<String, ?> getAll() {
2775 synchronized(this) {
2776 //noinspection unchecked
2777 return new HashMap(mMap);
2778 }
2779 }
2780
2781 public String getString(String key, String defValue) {
2782 synchronized (this) {
2783 String v = (String)mMap.get(key);
2784 return v != null ? v : defValue;
2785 }
2786 }
Adam Powell212db7d2010-04-08 16:24:46 -07002787
2788 public Set<String> getStringSet(String key, Set<String> defValues) {
2789 synchronized (this) {
2790 Set<String> v = (Set<String>) mMap.get(key);
2791 return v != null ? v : defValues;
2792 }
2793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002794
2795 public int getInt(String key, int defValue) {
2796 synchronized (this) {
2797 Integer v = (Integer)mMap.get(key);
2798 return v != null ? v : defValue;
2799 }
2800 }
2801 public long getLong(String key, long defValue) {
2802 synchronized (this) {
2803 Long v = (Long) mMap.get(key);
2804 return v != null ? v : defValue;
2805 }
2806 }
2807 public float getFloat(String key, float defValue) {
2808 synchronized (this) {
2809 Float v = (Float)mMap.get(key);
2810 return v != null ? v : defValue;
2811 }
2812 }
2813 public boolean getBoolean(String key, boolean defValue) {
2814 synchronized (this) {
2815 Boolean v = (Boolean)mMap.get(key);
2816 return v != null ? v : defValue;
2817 }
2818 }
2819
2820 public boolean contains(String key) {
2821 synchronized (this) {
2822 return mMap.containsKey(key);
2823 }
2824 }
2825
2826 public final class EditorImpl implements Editor {
2827 private final Map<String, Object> mModified = Maps.newHashMap();
2828 private boolean mClear = false;
2829
2830 public Editor putString(String key, String value) {
2831 synchronized (this) {
2832 mModified.put(key, value);
2833 return this;
2834 }
2835 }
Adam Powell212db7d2010-04-08 16:24:46 -07002836 public Editor putStringSet(String key, Set<String> values) {
2837 synchronized (this) {
2838 mModified.put(key, values);
2839 return this;
2840 }
2841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002842 public Editor putInt(String key, int value) {
2843 synchronized (this) {
2844 mModified.put(key, value);
2845 return this;
2846 }
2847 }
2848 public Editor putLong(String key, long value) {
2849 synchronized (this) {
2850 mModified.put(key, value);
2851 return this;
2852 }
2853 }
2854 public Editor putFloat(String key, float value) {
2855 synchronized (this) {
2856 mModified.put(key, value);
2857 return this;
2858 }
2859 }
2860 public Editor putBoolean(String key, boolean value) {
2861 synchronized (this) {
2862 mModified.put(key, value);
2863 return this;
2864 }
2865 }
2866
2867 public Editor remove(String key) {
2868 synchronized (this) {
2869 mModified.put(key, this);
2870 return this;
2871 }
2872 }
2873
2874 public Editor clear() {
2875 synchronized (this) {
2876 mClear = true;
2877 return this;
2878 }
2879 }
2880
2881 public boolean commit() {
2882 boolean returnValue;
2883
2884 boolean hasListeners;
2885 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002886 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887
2888 synchronized (SharedPreferencesImpl.this) {
2889 hasListeners = mListeners.size() > 0;
2890 if (hasListeners) {
2891 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002892 listeners =
2893 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 }
2895
2896 synchronized (this) {
2897 if (mClear) {
2898 mMap.clear();
2899 mClear = false;
2900 }
2901
The Android Open Source Project10592532009-03-18 17:39:46 -07002902 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 String k = e.getKey();
2904 Object v = e.getValue();
2905 if (v == this) {
2906 mMap.remove(k);
2907 } else {
2908 mMap.put(k, v);
2909 }
2910
2911 if (hasListeners) {
2912 keysModified.add(k);
2913 }
2914 }
2915
2916 mModified.clear();
2917 }
2918
2919 returnValue = writeFileLocked();
2920 }
2921
2922 if (hasListeners) {
2923 for (int i = keysModified.size() - 1; i >= 0; i--) {
2924 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002925 for (OnSharedPreferenceChangeListener listener : listeners) {
2926 if (listener != null) {
2927 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2928 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002929 }
2930 }
2931 }
2932
2933 return returnValue;
2934 }
2935 }
2936
2937 public Editor edit() {
2938 return new EditorImpl();
2939 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 private FileOutputStream createFileOutputStream(File file) {
2942 FileOutputStream str = null;
2943 try {
2944 str = new FileOutputStream(file);
2945 } catch (FileNotFoundException e) {
2946 File parent = file.getParentFile();
2947 if (!parent.mkdir()) {
2948 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2949 return null;
2950 }
2951 FileUtils.setPermissions(
2952 parent.getPath(),
2953 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2954 -1, -1);
2955 try {
2956 str = new FileOutputStream(file);
2957 } catch (FileNotFoundException e2) {
2958 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2959 }
2960 }
2961 return str;
2962 }
2963
2964 private boolean writeFileLocked() {
2965 // Rename the current file so it may be used as a backup during the next read
2966 if (mFile.exists()) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002967 if (!mBackupFile.exists()) {
2968 if (!mFile.renameTo(mBackupFile)) {
2969 Log.e(TAG, "Couldn't rename file " + mFile
2970 + " to backup file " + mBackupFile);
2971 return false;
2972 }
2973 } else {
2974 mFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 }
2976 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002978 // Attempt to write the file, delete the backup and return true as atomically as
2979 // possible. If any exception occurs, delete the new file; next time we will restore
2980 // from the backup.
2981 try {
2982 FileOutputStream str = createFileOutputStream(mFile);
2983 if (str == null) {
2984 return false;
2985 }
2986 XmlUtils.writeMapXml(mMap, str);
2987 str.close();
2988 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2989 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2990 mTimestamp = mFileStatus.mtime;
2991 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002992
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002993 // Writing was successful, delete the backup file if there is one.
2994 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 return true;
2996 } catch (XmlPullParserException e) {
2997 Log.w(TAG, "writeFileLocked: Got exception:", e);
2998 } catch (IOException e) {
2999 Log.w(TAG, "writeFileLocked: Got exception:", e);
3000 }
3001 // Clean up an unsuccessfully written file
3002 if (mFile.exists()) {
3003 if (!mFile.delete()) {
3004 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
3005 }
3006 }
3007 return false;
3008 }
3009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003010}